#38 undefined macro variables

release
open
nobody
Program (79)
5
2014-08-19
2002-01-19
TK Soh
No

this patch will give the 'undefined' variables in NEdit
macros a Perl-like behavior, which returns 0 (zero)
when evaluated as integer, or returns "" (empty string)
when evaluated as string.

This way we no longer need to pre-define the variables
in ~/.neditmacro before using them.

Use isnull() to check if a variable is undefined
(null), if you want to. To undef a variable, simply
assign an unused var name to it, probably some uncommon
var name like UNDEF to avoid confusion.

Discussion

  • TK Soh
    TK Soh
    2002-01-19

    cvs diff #1 for undef macro var

     
    Attachments
  • Alexander Mai
    Alexander Mai
    2002-03-18

    • milestone: --> release
     
  • Alexander Mai
    Alexander Mai
    2002-03-18

    Logged In: YES
    user_id=15180

    Any comments from our macro experts on this?

     
  • Nathan Gray
    Nathan Gray
    2002-07-26

    Logged In: YES
    user_id=121553

    I think that having valid default values for unintialized variables is
    a really bad idea in any programming language. It hides bugs that
    involve failing to properly initialize variables before using them.

    I think it's a very good idea, though, to have an "isnull(var)"
    subroutine to check whether a variable is undefined or not, but
    there's an important semantic difference between 0 or "" and an
    undefined variable.

     
  • TK Soh
    TK Soh
    2002-07-29

    Logged In: YES
    user_id=411637

    Perl does it, sh does it, even VB does it. Haven't heard much complaint so
    far.

    You are not wrong, but the macro engine is an extension of the
    NEdit's functionality. It's ease of use should be [one of] the main concern.
    Users want something that can help ease the tedious editing works,
    hence the scripting support, not to write an application out of
    it.

    There are a lot of great macros waiting at www.nedit.org,
    perhaps the most annoying lines on these pages, to me, would read "you
    need to set xxx variable in the .neditmacro file, ...."

    Hence the
    patch.

     
  • Nathan Gray
    Nathan Gray
    2002-07-29

    Logged In: YES
    user_id=121553

    > Perl does it, sh does it, even VB does it. Haven't heard much
    complaint so far.

    On the contrary, in my experience these are three of the
    languages that are most widely considered ugly and poorly
    designed. Default values are one of the reasons for this.

    You mention ease-of-use as a benefit of defaul values, but
    ease-of-use is the exact reason I oppose them. Your burden
    when first coding goes down a tiny bit because you don't have to
    put in variable initializations, but your debugging burden
    *increases* significantly, because a little slip-up like a spelling
    error in a variable name becomes a difficult to locate bug instead
    of an easy one. I'm not speaking from an abstract academic
    point of view, but from a practical programmer's point of view.

    In this particular implementation, the fact that uninitialized
    variables are polymorphic is also a problem. It means that the
    result of code like this becomes much harder to predict:

    if( n = 0 ) # Am I testing for zero, or initialization?
    t_print( "n = " n ) # Was foo a number, or uninitialized??

    Will it print out "n = 0" or "n = "? It's not clear unless you've made
    sure that your variable is initialized correctly. So in other words,
    any time a programmer relies on default initialization, they have to
    worry *more* about how their variables are initialized.

    You rightly point out that making users add lines to their
    .neditmacro files is annoying. I definitely agree that this is a
    problem, but it could be solved with the isnull() feature alone.
    There is no need to introduce the problems that default values will
    bring.

    Another solution that I think would be really sensible is to allow
    global variable initializations appear outside of "define" blocks in
    macro files. So a file that looked like this:

    $some_global = "foo"
    define bar {
    t_print( $some_global "bar" )
    }

    would act just like if the user added the $some_global initialization
    to his .neditmacro file (except, of course, the order of initialization
    among global variables would not be well-defined). What do you
    think?

     
  • TK Soh
    TK Soh
    2002-07-30

    Logged In: YES
    user_id=411637

    the 'default value' behavior is usually well defined, at
    least in Perl, which kinda inspired this patch, it hasn't
    caused any trouble AFAIK because people understand the
    simple rules and handle it accordingly. the isnull()
    function is actually trying to mimic the function of
    'defined' in Perl, but was so named because someone gave the
    name "define" to what apparently should have been called
    "sub" :-(

    If the case of you example, it prints "n = 0", becaseu you
    set n = 0. If "n = 0" is changed to "n == 0", then it prints
    "N = ".

    I am no expert in language design, so I won't go too far
    arguing the pros and cons on how certain features ware
    implemention in other languages (this is probably not the
    place too)

    I remember reading Larry Wall said something (roughly) like
    this: "Perl has its weakness, the trick is to know how to
    use its strength". Same thing go to any language I believe.
    So just try to add more strength to it :-)

    btw, your suggestion on global variable initialization may
    work, but doesn't quite address the issue for the "casual"
    macro developers like me, who write macros in the macro
    dialog, since 'define' is only allowed in the macro files.
    Having said that, I think the handling of macro/macro-files
    should be improved too (this is off topic, of 'cos :-)

     
  • Nathan Gray
    Nathan Gray
    2002-07-30

    Logged In: YES
    user_id=121553

    First, of course you are right and I meant "if (n==0)"
    (assignment in if statements is a whole different rant ;^).
    My point was that the "if" makes you think that n is a
    number, but then it prints as an empty string.

    Second, since you say that Perl was where this idea
    came from I should point out that the reason Perl has
    "use strict" is to keep people from shooting themselves
    in the feet with default values. See here:
    http://perl.about.com/library/weekly/aa081701a.htm
    for a discussion of "use strict" and the problems that
    default values can cause.

    You're right that the "$global = init" in .nm files won't
    help you in the macro entry dialogs. How about an
    init_var( var, val ) function that returns the value of var
    if it's initialized or val otherwise? Then you could say:

    $global_var = init_var( $global_var, 0 )

    in a macro dialog or anywhere else and be guaranteed
    that $global_var is either initialized to zero or left
    unchanged. It's basically shorthand for:

    if( isnull( $global_var ) )
    $global_var = 0

    By the way, it turns out that "$global_var = init" in .nm
    files *is* allowed, though it's not seamless. Check out
    the implementation of these macros for an example:
    http://www.nedit.org/macro/4/4-19.shtml

     
  • TK Soh
    TK Soh
    2002-07-31

    Logged In: YES
    user_id=411637

    for Perl, -w will suffice. use strict is mainly for
    relatively big projects, or the paranoia ;-) Anyway this
    discussion on Perl should be taking place on c.l.p.m.

    back to nedit. I think isnull() will be good enough, at
    least it meets the original goal of the patch - no more
    variables initialization in the .neditmacro file required.
    If we vote out the other feature, so it shall not stay.

    as for "$global = init", checked the pages, but couldn't see
    anything. maybe I misunderstood you.

     
  • Nathan Gray
    Nathan Gray
    2002-07-31

    Logged In: YES
    user_id=121553

    About the page I gave for "$global = init", the file
    NEDIT_LOADED.nm, which is linked to from the page I
    gave, uses this syntax. I've tried it before, though, and
    it didn't work for me. There's some trick to it, because
    our parser is, um, quirky.

    As for our discussion of Perl, I think it's important to
    understand the impact that a feature can have on a
    language, and so it's not off-topic to talk about that
    here. Still, I think I've said what I needed to say, so I
    won't bring it up if you don't. :-)

    I will happily support isnull(), though I think maybe it
    should be spelled is_null to fit in with other NEdit macro
    subroutines. I'd also like to see some other predicates
    like is_string, is_int, and is_array in the language, but
    that's a subject for a different patch...

     
  • TK Soh
    TK Soh
    2002-07-31

    Logged In: YES
    user_id=411637

    it's a good discussion, nonetheless.

    btw, the patch is currently for 5.2 (the diff file is a bit
    'poluted' also), which needs to be updated for 5.3 or later.
    I can work on if the needs arise later.

     
  • Logged In: NO

    The whole problem is that global variables can't be used in an
    menu macro, unless they are initialized outside the menu
    (in .neditmacro). They could also be initialized in the menu,
    however this won't make sense, since you choose a global
    variable because you need the old value when running the
    macro again. The initializing statement in the menu would
    delete the old value, when the macro is rerun.

    Hence the best proposal was made already. Can this patch
    be transformed into something that provides a single built-in
    macro function
    a=init_var(b, v) ?
    If the variable b is undefined, then the function would assign a
    to the value of v. Otherwise nothing is done.

    This should allow for example
    $a=init_var($a, $empty_array)

    The advantage is twofold:
    1. There is no silent assignment to default(?) values.
    2. You can give arbitrary values, including arrays.

    --Joerg