http://qs1969.pair.com?node_id=11139815

sectokia has asked for the wisdom of the Perl Monks concerning the following question:

Are there any modules to help reduce the amount of syntax in perl?

Example, instead of:

$ref->{'foo'}{$bar}

something that gets it closer to JS with less brackets and $ etc:

ref[foo].bar

I saw semi::semicolons, so I figured the rest of the language could be changed some how as well?

Replies are listed 'Best First'.
Re: Modules to reduce syntax?
by GrandFather (Saint) on Dec 22, 2021 at 05:54 UTC

    Have you actually looked at what Semi::Semicolons does? Do you really want that?

    Perl is what it is. What you pay in sigils you more than make up in language flexibility, reliability and conciseness. For most coding tasks Perl ends up being more concise than most other popular general purpose languages so if it is saving keystrokes you are interested in, Perl generally comes out the winner in the long haul.

    That said, saving keystrokes is almost never a productive use of time. Much better to learn the strengths of whatever language you are using and play to those strengths rather than try to bend a language to fit whatever your prior experience might be. A strength of Perl is that it can accommodate most programming styles and provides very powerful data management with easy to understand fundamental data types.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: Modules to reduce syntax?
by eyepopslikeamosquito (Archbishop) on Dec 22, 2021 at 06:06 UTC

    Are there any modules to help reduce the amount of syntax in perl?

    Yes. For really clean programs, use Acme::Bleach.

Re: Modules to reduce syntax?
by kcott (Archbishop) on Dec 22, 2021 at 14:29 UTC

    G'day sectokia,

    I often see code that does seem to have the "can't see the woods for the trees" problem. Much of that can usually be mitigated by a better understanding of the syntax that currently exists. Some examples:

    • Unnecessary quotes: $ref->{'foo'}{$bar} vs. $ref->{foo}{$bar}
    • Unnecessary dereferencing: $ref->{x}->[$i]->{$y} vs. $ref->{x}[$i]{$y}
    • Unnecessary parentheses to fix precedence issues: open(my $fh, '<', $file) || die vs. open my $fh, '<', $file or die

    Finding ways to removed sigils is, in my opinion, a rather pointless exercise. It's extra work up-front and results in code that looks like it's from a different language: reduces readability; by extension, reduces maintainability; and makes the code more error-prone.

    Removing whitespace, because Perl doesn't need it, has much the same effect as using too much punctuation: itcanmakeitverydifficulttoreadthecode.

    Avoid excessive comments by using meaningful names. Good:

    $grand_total += $sub_total;

    Less good:

    # Add the current sub-total to the grand-total $x += $y;

    There are many more examples; these just came to mind as I was writing this post. You'd be better off spending time learning more about the existing syntax than learning a new, syntax-reducing module.

    — Ken

Re: Modules to reduce syntax?
by eyepopslikeamosquito (Archbishop) on Dec 22, 2021 at 07:02 UTC
Re: Modules to reduce syntax?
by hippo (Bishop) on Dec 22, 2021 at 09:50 UTC

    You can reduce the amount of syntax in the line you provided and it doesn't even require the use of an additional module. The expression $ref->{'foo'}{$bar} is exactly equivalent to $ref->{foo}{$bar} and the latter has the advantage that you don't waste any time pondering why the author has chosen to enclose foo in single quotes like that.


    🦛

Re: Modules to reduce syntax?
by ikegami (Patriarch) on Dec 22, 2021 at 20:04 UTC

    I saw semi::semicolons, so I figured the rest of the language could be changed some how as well?

    Semi::Semicolons take a non-Perl program, translates it to Perl, then runs that. Feel free to create your own programming language and translator just like Semi::Semicolons did. Then, all you need is this:

    package MyLang; use Filter::Simple; sub translate { my $mylang_code = shift; ... return $perl_code; } FILTER { $_ = translate($_) } 1

    Note that ref[foo] already means something in Perl. (It means the same thing as ref( [ foo() ] ).) So you're new language is going to have to change that too.

Re: Modules to reduce syntax?
by LanX (Saint) on Dec 22, 2021 at 08:15 UTC
    > $ref->{'foo'}{$bar}

    and

    > ref[foo].bar

    are definitely not the same in JavaScript

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      It's not clear to me what you want, since your code is wrong.

      Here the correct analogous:

      $ref->{foo}{$bar}

      (NB: autoquoting of key "foo" !)

      is

      demo in the JS console

      >> ref={foo: {x:42}} Object { foo: {…} } >> bar="x" "x" >> ref.foo[bar] 42 >> ref['foo'][bar] 42

      as a side note, $ is a legal identifier in JS so you can also write

      >> $ref={foo: {x:42}} Object { foo: {…} } >> $ref['foo'][$bar] 42

      update

      demo in the Perl debugger

      DB<3> $ref = {foo=> { x => 42 } } DB<4> $bar = "x" DB<5> p $ref->{foo}{$bar} 42 DB<6> p $$ref{foo}{$bar} 42

      update

      DB<11> use experimental 'refaliasing'; \%ref = $ref DB<12> p $ref{foo}{$bar} 42

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        You can't get rid of the sigils $%@ in Perl, because of conflicts with barewords which have many other meanings and the many bultin commands which depend on sigils.

        But this last example of aliasing a list-form and hashref-form \%hsh = $hsh could be simplified, such that the deref -> isn't needed anymore.

        use Keyword::Simple to define a new command like e.g. var or let and any

        var %hsh = LIST;

        is translated to

        my $hsh = \ my %hsh; %hsh = LIST;

        This is not too hard to implement, because you don't need to parse LIST in advance (which could be arbitrary Perl code)

        Like this explicit dereferencing with -> would be "simplified" away.

        Demo:

        DB<27> sub LIST { foo => { x => 42 } } DB<28> $bar ='x' DB<29> my $hsh = \ my %hsh; %hsh = LIST; \\ cont: say $hsh{foo}{$bar} 42

        Of course that way you'd loose the ability to have $ident and %ident in different namespaces, but that's often considered bad style anyway.

        And passing of hash-refs, like with function-parameters wouldn't be that easy without additional \ref-operation

        sub func { var (\%hsh,\@arr) = @_; }

        because otherwise var couldn't tell if a $scalar is meant to be aliased to a %hash or an @array

        sub func { var ($hsh,$arr) = @_; # ??? }

        tho you might be able simplify the syntax in many cases with

        sub func { var \(%hsh,@arr) = @_; }

        HTH! :)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Re: Modules to reduce syntax?
by eyepopslikeamosquito (Archbishop) on Dec 23, 2021 at 11:50 UTC
Re: Modules to reduce syntax?
by perlfan (Vicar) on Dec 27, 2021 at 16:11 UTC
    Util::H2O will take this,
    my $ref = { foo => $bar => 'baz' }; printf "%s\n", $ref->{'foo'}{$bar};
    And let you do this:
    use Util::H2O qw/h2o/; my $ref = h2o -recurse, { foo => $bar => 'herp' }; printf "%s\n", $ref->foo->$bar;
    If you use a lot hash references, it can remove a significant amount of typing and cruft simply by doing away with the curly braces. The reduction in typing and file size from these 2 characters quickly adds up. enjoy!
      > it can remove a significant amount of typing

      That's a Pyrrhic victory from level two onwards.

      Curlies {} are "spared" for mandatory arrows -> for the price of init and OO overhead.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        >Pyrrhic victory

        perhaps a tad hyperbolic? OP asked for reduction in syntax (I read it as more readable) - not even "less typing"; but the only thing I can assuredly tell you is that I tend to use this module a lot nowadays. And it is true that eliminating a paired set of curlies in exchange for some dereference syntax is worth it to me; and "overhead" (whatever that means to the reader) is generally never something I even look at. My optimizations happen on the algorithmic or complexity level; IOW I avoid nesting loops in favor of ... hashes (and references to such) :-) In any case, I should have added a YMMV.