Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Thx, St. Larry, for the Beauty of Sigils

by msouth (Sexton)
on Jul 26, 2019 at 17:12 UTC ( [id://11103471]=perlmeditation: print w/replies, xml ) Need Help??

TL;DR Thanks, Larry, for sigils

I recently took a job at a Python shop, helping out a friend. I have tried to be patient with the new-to-me language and to realize that there are different ways of doing things and that I should expect some mental friction simply due to my unfamiliarity. But, man, I just can't escape the idea that sigils were a good idea.

I needed to access a dynamically specified method and run a dynamically specified method against that method's result. Python can't tell the difference between a variable you created that contains a method name and a method name itself. You have to use a function called getattr to cumbersomely retrieve the reference you want. And if you go any deeper than one, it gets ugly very quickly. In my case, I have something like

getattr(getattr(object_identifier,variable_containing_the_name_of_meth +od_one), variable_containing_the_name_of_method_two)

(I'm using ridiculously long variable names for clarity about what the variables contain.)

With sigils to let Perl know that I mean 'grab the contents of the variable and execute the method having that name', I can do:

$object_identifier->$variable_containing_the_name_of_method_one->$obje +ct_containing_the_name_of_method_two

With the ridiculous names it may be less clear how much nicer this is, but look at:

$obj->$var1->$var2

vs

gettattr( getattr(obj,var1) , var2)

I hate going to the inside and working my way out, trying to remember what I picked up along the way.

I realize that Python people hate having to type sigils all over the place, and that they would find it ironic that this would be the thing I would write in praise of. But I am doing a lot of work right now with dynamic method/attribute names and it really seems to me that Larry made the right call on this.

Replies are listed 'Best First'.
Re: Thx, St. Larry, for the Beauty of Sigils
by shmem (Chancellor) on Jul 27, 2019 at 14:14 UTC
    I hate going to the inside and working my way out, trying to remember what I picked up along the way.

    My first language was GFA-Basic on the Atari, and it also had sigils. You could see at a glance what kind of variables you were dealing with. Un-annotated identifiers always bothered me, be that C, python or even shell. That forces me to annotate the type in the identifier, such as int_foo or member_foo or func_foo. But what if int_foo by accident doesn't hold an integer, but a short? Well sometimes it blows, sometimes you get a warning. Unsure what is which? Open the header file, go figure. Try to remember everything, to avoid going to the inside and work your way out.

    Sigils are the best invention after sliced bread (and beer¹).

    ¹) strictly speaking, beer is not an invention, but a creation: "on the 8th day, God created beer, and hath never been seen any more thereafter".

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Thx, St. Larry, for the Beauty of Sigils
by LanX (Saint) on Jul 26, 2019 at 20:19 UTC
    > I realize that Python people hate having to type sigils all over the place, and that they would find it ironic that this would be the thing I would write in praise of.

    Many Python people just hate everybody who questions a little bit of their language. I think it's also due to the fact that many learn Python as first language and have problems accepting TIMTOWTDI.

    The other problem is the frustrating learn curve of Perl, because we have a list form and a ref form of an array.

    DB<2> $a = [A..Z] DB<3> @a = (a..z) DB<4> x $a[0], $a->[0] 0 'a' 1 'A'

    That has many advantages but makes the syntax confusing.

    I'd personally like to have any new syntax or pragma to "alias" $a and @a together at declaration time, such that I could write

    my $a[]; #=> @a := @$a $a = [A..Z]; print "@a"; # A B C ... print $a[0]; # A

    thus avoiding \ and -> in many cases.

    The downside would be to loose the advantages of separate namespaces, but they are rarely used.

    Though I don't know how to implement it or if it's even possible, without braking old code.

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

      I think it's also due to the fact that many learn Python as first language and have problems accepting TIMTOWTDI.
      In my experience, that's not just first-language Pythonistas. Python has an explicitly anti-TIMTOWTDI philosophy ("There should be one - and preferably only one - obvious way to do it.") so you get problems with TIMTOWTDI even from people who also know other languages if they've drunk the Python Kool-Aid.
        > "There should be one - and preferably only one - obvious way to do it."

        The "Zen of Python" is a big pile of pseudo religious dogma which doesn't hold scientific scrutiny.

        For instance it says "Explicit is better than implicit." but Python does implicit declarations and implicit dereferencing.

        This reminds me about an article about religious dogmas I read recently: It described how a newer religions contain polemics against predominant neighboring religions at time of it's creation. Islam vs Christianity, Christianity vs Judaism, mainstream Judaism vs Samaritans and so on.

        The Zen of Python is best understood as an anti Perl polemic from back then.

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

      The other problem is the frustrating learn curve of Perl, because we have a list form and a ref form of an array.

      No, we have plain variables and references to variables (and functions). The distinction between plain and reference variables is well done IMHO.

      But python is worse - it has list and tuple arrays

      qwurx [shmem] ~> python Python 2.7.15+ (default, Nov 27 2018, 23:36:35) [GCC 7.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> foo = (1,2,3,4) >>> bar = [1,2,3,4] >>> type(foo) <type 'tuple'> >>> type(bar) <type 'list'> >>> bar[0] = 5 >>> foo[0] = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> foo (1, 2, 3, 4) >>> bar [5, 2, 3, 4] >>>

      and it isn't obvious which is which by looking at the identifier. A tuple is inmutable, a list can be assigned to.
      This was a major WTF moment for me.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
        > No, we have plain variables and references to variables (and functions).

        I was using my own wording for the distinction.

        But sorry "plain variable" is blah.

        The fact that other languages do implicit dereferencation in their syntax doesn't make them less plain.

        $a, %a and @a are in fact containers for references, to allow such implicit dereferencation. °

        So how are containers "plain" now?

        But Perl is more explicit* here, which helps understanding what is really happening if you do an assignment a=b in another languages, where they sometimes copy the content or the reference.

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

        updates

        °) e.g. $a[0] is by definition (\@a)->[0]

        *) "Explicit is better than implicit" quote from Python blah

      I could never understand what's supposed to be confusing about this.

      Jenda
      Enoch was right!
      Enjoy the last years of Rome.

Re: Thx, St. Larry, for the Beauty of Sigils
by LanX (Saint) on Jul 26, 2019 at 19:55 UTC
    Just to be sure I understand the problem.

    because a variable is a bareword you can't just type ?

    meth = "name" obj.meth()

    In JS you could solve this with a bracket syntax to look up an attribute obj[meth]()

    Console demo:

    > obj = { name : function () {return "called" } } Object { name: name() } > meth ="name" "name" > obj[meth]() "called"

    But in python you need a function getattr() ?

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

      Yes, but the bracket subscript trick works for dynamic class names, thus: globals()["CLASSNAME"] 🤢

      I wrote about this before at http://redd.it/6epqi5#did1j9b and I also have a collection for several programming languages at https://stackoverflow.com/q/26402047. ES6 classes are missing, and eval('CLASSNAME') is the answer.

      tl;dr if the language does not have sigils on identifiers, this topic is a pain in the butt.

        I like sigils, probably also because my first language was BASIC.

        But I still think they make code more readable, kind of Hungarian Notation

        Parsing non sigil languages is hard without syntax highlighting. *

        And isn't readability part of the Zen(terfold) of Python? ;)

        But some things are unfortunately solved in Perl 5.

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

        *) On a side note: I remember having problems with English too, where the same word can sometimes be a verb, adjective and noun, where other languages have grammatical suffices.

        Headlines in the English newspapers are still a riddle...

Re: Thx, St. Larry, for the Beauty of Sigils
by Anonymous Monk on Jul 29, 2019 at 13:28 UTC
    Let me play the devil's advocate here. I agree that the equivalent Perl code would be much easier to read, but why are you using introspection in this context? Shouldn't dicts (similar to Perl hashes) be used when you want access by arbitrary string key?

      ++. The $obj->$method_name() syntax is basically just a symbolic ref that strict doesn't complain about, and with some extra magic to search in the $obj's package rather than the current one.

      That's more a case of perl giving you more rope than of python hindering correct usage.

        Just yesterday I had to implement a proxy object which delegates calls to other objects.

        getattr() seems to be like Perl's ->can() , but with the difference that you have to check the type in Python by yourself.

        IIRC are classes and objects in Python dicts anyway, which can be accessed via __dict__, though w/o inheritence.

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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://11103471]
Approved by holli
Front-paged by mr_mischief
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: (6)
As of 2024-04-24 09:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found