5 ms·
> I have worked with many languages, and Perl has always been one of the hardest to remember due to non-standard symbol abuse and a few strange semantics. For
by gbacon 6y ago
> I have worked with many languages, and Perl has always been one of the hardest to remember due to non-standard symbol abuse and a few strange semantics.
For example?
- cogman10 6y agoI mean, the combinations of $%@ are really astoundingly bad. $ alone has so many different meanings and operations depending on context. You won't find that sort of thing in any other language. Not even PHP which for some bizarre reason brought $ along for the ride. Here's a fun exercise, write a dictionary of arrays. Now write a dictionary of 2d arrays. In any other language, that's hardly a challenge to both read and write such a structure. Not so with perl.
- edoceo 6y agoI think shells did $ for vars first, then Perl added @ and % for arrays and hashes (and then $ was refs)
- fgasper 6y ago> Here's a fun exercise, write a dictionary of arrays. Umm … ok: my %dict = ( foo => [ 1, 2, 3 ], bar => [ 4, 5, 6 ], ); > Now write a dictionary of 2d arrays. my %dict2d = ( foo => [ [1, 2, 3], [4, 5, 6] ], bar => [], ); It’s pretty much identical to JS. Not sure how that’s supposed to exemplify how hard it is to write Perl.
- amirkdv 6y agoI'm not the original comment author, neither am I fluent in Perl. But I suspect they meant nested hashes and not a hash whose values are arrays of arrays. As you point out, the latter is trivial. To be clear, even a nested hash is all well as long as the depth and the keys are literals (as in your example). It is when keys are dynamic that things get unruly. And god forbid if the _depth_ of nesting is dynamic. All of these are trivial to implement in Python, Ruby, JS, PHP, ...
- gbacon 6y ago%nested = (foo => { bar => { baz => "quux" } }); Access the leaf with $nested->{foo}{bar}{baz} If the keys are in variables, it becomes $nested->{$x}{$y}{$z} For dynamic depth, do you have a specific use case in mind? If I have a tree, I’m probably going to search it rather than using a hardcoded path.
- kbenson 6y agoThis is why we use strict! The extra arrow is unneeded, as you're working on the actual hash, not a reference to the hash. This is a compiler error with use strict though, so it's not something you would generally be bitten with when writing real code, just internet comments. :)
- gbacon 6y agoWhoops, good catch! I had references on the brain. For completeness, that makes it either $nested{$x}{$y}{$z} or after initializing with curly brackets rather than parentheses to construct a new reference to an anonymous hash $nested = { … }; and then use the arrow to dereference as in the grandparent.
- cookiecaper 6y agoI think the point is not that Perl's rules don't make sense -- it's that they're much less obvious than those in many competing languages. In Python, lists are `l = [1, 2, 3]` and dicts are `d = {"key": val}`. Both structures can be nested without any change to the semantics.
- rosywoozlechan 6y ago> I mean, the combinations of $%@ are really astoundingly bad. $ alone has so many different meanings and operations depending on context. You won't find that sort of thing in any other language. I kind of felt lost first getting started with Scala where I felt like there was symbol overload.
- gbacon 6y ago> $ alone has so many different meanings and operations depending on context. Used as a sigil, $ always tags a scalar, a single value. $foo = 3; A reference to something else is a single value. $bar = [qw/ apple orange banana /]; The special variable $$ is the pid of the current process, borrowed from the shell. Special variables with punctuation names have length at most one. The leading $ is the scalar sigil, and the latter is its name. Dereferencing a reference to scalar is rarely used and looks like either $$baz = $quux; or ${$baz} = $quux; In a regex, $ broadly means end of line, but the exact meaning is context sensitive: possibly end of buffer, just before a newline at the end of a buffer, or end of logical line within a buffer. Where it matters, the anchors \z and \Z have less flexible meanings. Of those, the kinda fuzzy one is $ inside a regex. The rest follow consistent, simple rules. I’m not sure what you mean by different operations on $. Am I skipping a difficult case you have in mind?
- ricardobeat 6y agoA classic (hope I didn't get it wrong): print "[", +( join '', map { "-> $_" } @$_ ), "]" for @{$ref}
- petre 6y agoThe concatenation operator is . in Perl and ~ in Raku. You could write a normal, braced foreach loop with another one inside and not use $_.
- notyourday 6y ago> print "[", +( join '', map { "-> $_" } @$_ ), "]" for @{$ref} Because computers are so slow, memory is so limited and disk space is so expensive the programmer absolutely had to write it in a single line in the most convoluted way possible? Yeah, that's definitely a language fault.
- ricardobeat 6y agoThis is pretty idiomatic Perl, and I've seen similar constructs countless times at work. You could indent the map body but it normally wouldn't be done for such a short expression. There is not much room for maneuver there if you don't want intermediate variables. And this is a quick sample, there is much, much hairier stuff to be found in real code. "Knowing the language well" is seen as a virtue for many.