in reply to Re^4: Nesting Functions
in thread Nesting Functions

> while in python it must have been defined before chronologically.

not sure what you mean. Example?

> Also in perl one distinction is that non lexicals can be accessed by name (symref or symbols table) while lexicals can't. Python doesn't have that distinction.

AFAIK does Python have namespaces - well classes - like __BUILTINS__ or globals()['var'] to access such non-lexicals.

> Are you saying the names of elements in a language must match their implementation and not their behaviour?

I'm saying it has to match the semantic of the definition. From what I know have "lexical vars" been invented in lambda calculus.

I suppose they where first implemented in lisp.

> as you can't limit a variable to a scope except function (so a variable in a loop can be used outside of that loop)

Scoping rules are different, but please keep in mind that you need an extra "form" in lisp to build a lexical scope. (at least in elisp). So scopes are language depended.

But what matters here is the visibility of lexicals (or rather non-visibility outside a scope)

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Replies are listed 'Best First'.
Re^6: Nesting Functions
by Eily (Monsignor) on Jul 19, 2019 at 14:23 UTC

    I've edited my post after seeing your update FYI.

    > while in python it must have been defined before chronologically.

    not sure what you mean. Example?
    This was what my example above was meant to demonstrate. The print(a) is fine because a=x has been executed first chronologically, although it was done after lexically (ie, below).

    I'm saying it has to match the semantic of the definition
    But definition are different between language aren't they? Like a closure can just be an anonymous function in some languages. Or do you consider that there is one true definition, and incorrect uses? You say that "Scoping rules are different", but you might just consider that the definition of a scope is different between languages. I could then argue that python doesn't have a definition for lexical variables. But I see it's a very poor argument, as you can't say that a language doesn't have a feature simply because the feature has another name :).

    But what matters here is the visibility of lexicals
    That makes sense. And IMHO it's an argument for calling our variable lexical aliases rather than just package variables :D.

    I still don't think calling python variables lexical is really helpful, especially when comparing it to perl. But I see your points and accept them as valid. I won't discuss much further, or at all, because who cares about python anyway?

      But definition are different between language aren't they?

      Some are, and that's a pity because it only leads to confusion. I like standards and one of them is a standard jargon/lexicon. If some language decides that it's going to abandon that then it is to that language's detriment.

      Like a closure can just be an anonymous function in some languages.

      That's just plain nuts. If a function isn't closing over anything then it is not a closure - QED. :-)

      Or do you consider that there is one true definition, and incorrect uses?

      For some terms, absolutely. There are terms which are well defined within Comp Sci (pointer, array, function, etc.) which if used to mean something else would certainly be classed as an incorrect use.

      I won't discuss much further, or at all, because who cares about python anyway?

      Amen, brother. Our fellow monk betmatt does seem rather obsessed by it, though. Poor chap.

        For some terms, absolutely. There are terms which are well defined within Comp Sci (pointer, array, function, etc.) which if used to mean something else would certainly be classed as an incorrect use.

        "Well defined" within certain contexts, as all things are

        Maybe in the 1970s this meant more, back when there were fewer choices

      yes there's hoisting happening in Python (though hoisting might be a JS term)

      OK if you want to define "lexical" by the order of statements inside a scope, (our is a good example) than let's compromise on "private" .

      Both Perl and Python have private variables.

      • in Perl they are also called "lexical vars" and declared with my for the rest of the scope
      • in Python they are called "local vars" and implicitly declared while assigning in a function scope or some obscure comprehensions for the full scope, even up-wards

      OK?

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        My "OK" is on your edit where variables in python are now described as being similar to my, rather than implying that they are equivalent ;-). As a compromise, I can also change my statement into:

        Python doesn't have sane lexicals.

      > "But definition are different between language aren't they? Like a closure can just be an anonymous function in some languages"

      Lisp popularized both concepts for decades, other languages can't bend the definitions into the opposite.

      And Larry took them from Lisp after adapting it to the different syntax of Perl when designing Perl 5

      A lexical variable is a variable that can be referenced only within the lexical scope of the form that establishes that variable; lexical variables have lexical scope. Each time a form creates a lexical binding of a variable, a fresh binding is established.

      So there you have a form where the variables are defined at the very beginning. °

      (let ((var1 init-form-1) (var2 init-form-2) ... (varm init-form-m)) form1 form2 ... formn)

      Both Perl and Python avoid extra "blocks" for each declaration by coupling the declaration to the surrounding scope.

      (To exactly simulate this behaviour we'd need a do block in Perl where all lexical vars are defined at the very beginning)

      So yes Perl is a bit saner but with a more complex implementation than Python and JS which are pretending the declaration happened at the scopes start.

      So using your arguments none of these languages are implementing lexical vars, because none is using a "let block" syntax.

      My argument is that semantics matter not syntax.

      AND you can easily transform Python and JS scoping to Perl's by moving the declaration at their scopes start and leaving the init parts at their respective place.

      Replicating my former example

      sub fun2 { my $a; print $a; # undef warning * $a = 33; }

      I hope my POV is clearer now.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      *) In order to have a fatal like in python just tie the declarations with a tied variable that croaks when fetched.

      °) though I don't know the original notation in lambda calculus

Re^6: Nesting Functions
by choroba (Cardinal) on Jul 19, 2019 at 14:12 UTC
    > Example?

    fruits = ["apple", "banana", "cherry"] for x in fruits: print(x) if x == "banana": print(y) if x == "apple": y=1

    whips himself

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      what's your point?

      >>> fruits = ["apple", "banana", "cherry"] >>> for x in fruits: ... print(x) ... if x == "banana": ... print(y) ... if x == "apple": ... y=1 ... apple banana 1 cherry

      Probably you don't like the "hoisting" of the binding of y?

      Please note that JS is also doing hoisting even that it has a var statement°

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      °) and now even let which behaves (almost completely) like my in Perl