Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^4: Nesting Functions

by Eily (Monsignor)
on Jul 19, 2019 at 13:32 UTC ( [id://11103028]=note: print w/replies, xml ) Need Help??


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

Implementation of semantic matters not syntax or naming.
I'm not sure I understand what you mean. Are you saying the names of elements in a language must match their implementation and not their behaviour? I really don't agree with that, you shouldn't have to know which interpreter you are using to call things, if their behaviour is well defined.

If you do call python's function variables lexical, I surely wouldn't call them "lexical my", 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). And the condition for using a variable in perl is that it has been declared before lexically, while in python it must have been defined before chronologically. 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.

Python has closures, closures require lexicals.
I'm tempted to argue that it could also be that Python has a different definition of closure, but I think that's a fair point. But Python variables behave so differently than lexicals from other languages (at least the ones I know), that I'd rather avoid calling them lexicals, and focus on the fact that closures keep a hold of variables beyond their expected lifespan, rather than talking about lexical scope.

Edit: (after yours):

the first assignment in a "scope" is an implicit declaration in Python.
I'd rather consider that all possible variables are implicitly declared. Otherwise that would mean that you can access a variable above it's (implicit) declaration like in my example. This would also imply conditional declaration when I'd rather consider only the definition/initialization can be conditional. Although, after checking, exec (the equivalent of perl's eval) only sees globals by default. So that's a point for lexicals.

Replies are listed 'Best First'.
Re^5: Nesting Functions
by LanX (Saint) on Jul 19, 2019 at 13:48 UTC
    > 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

      > 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

      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.

        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

        > "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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11103028]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-03-28 20:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found