7 ms·
Used to spend a ton of time writing Perl (see username). Moved on to better designed languages. Which are not hard to find. There are a few big issues with Per
by mapgrep 7y ago
Used to spend a ton of time writing Perl (see username). Moved on to better designed languages. Which are not hard to find.
There are a few big issues with Perl 5 but the biggest is easily the mess of references vs flat values. Python, Ruby, JavaScript and many other dynamic languages do not make the programmer think about whether you are going to pass a data structure like an array or hash as a reference or direct value. Perl does. A lot of built in operators expect direct values, eg array ops like join, push. This is because the ops existed before Perl added complex data structures — arrays of arrays, hashes of arrays, etc. References were bolted on in Perl 5 to support such structures. And any code using them will handle references not direct values. So you have a split. And then a lot of energy is spent navigating between these two types of variables.
As Steve Yegge said:
“Perl's references are basically pointers. As in, C-style pointers. You know. Addresses. Machine addresses. What in the flip-flop are machine addresses doing in a "very high-level language (VHLL)", might you ask? Well, gosh, what they're doing is taking up about 30% of the space in all Perl documentation worldwide.”
https://sites.google.com/site/steveyegge2/ancient-languages-perl https://sites.google.com/site/steveyegge2/ancient-languages-...
For a taste of this here is how you join an array inside a hash:
join(‘,’,@{$foo->{‘bar’}})
Update - I forgot to say my favorite thing about Perl. The CPAN community. People talk about the sheer scale of CPAN but my favorite thing about it is the quality of documentation, at least back when I was using it. Really good uniform high quality docs. Almost always a great synopsis with multiple good examples covering real uses cases and gotchas. Then thorough documentation of functions/methods. My theory is this culture developed because CPAN predates StackOverflow, github, Google, maybe even search engines. The docs had to be good.
- combatentropy 7y ago> join(‘,’,@{$foo->{‘bar’}}) Thank you for that example. I guess the equivalent in JavaScript is: foo.bar.join(',')
- pflanze 7y agoCorrect. You can use libraries in Perl (autobox and a class offering "join") so you can write it in Perl as: $foo->{bar}->join(',') I've done that in FunctionalPerl[1]: use FunctionalPerl ":autobox"; my $foo= {bar=> ["hi", "there"]}; is $foo->{bar}->join(','), 'hi,there'; [1] https://metacpan.org/pod/FunctionalPerl https://metacpan.org/pod/FunctionalPerl
- pmoriarty 7y ago"Python, Ruby, JavaScript and many other dynamic languages do not make the programmer think about whether you are going to pass a data structure like an array or hash as a reference or direct value. Perl does." If you don't think about these things in python, you're going to be scratching your head when you see something like this: >>> foo = ['a','b','c'] >>> bar = foo >>> bar[1] = 'z' >>> foo ['a', 'z', 'c']
- ben509 7y agoIt's incredibly confusing if you naively use a list as a default argument, e.g. def foo(some_list=[]): ... some_list.append(3) ... Since the default is constructed when the function is evaluated, it's the same list, but only when the default is used. Or the n00b's attempt to use lambdas: def list_of_lambdas(x): result = [] for n in range(x): result.append(lambda m: n + m) return result for func in list_of_lambdas(3): print(func(3)) 5 5 5 (All the closures share the same "cell", meaning the same "n", which is 2 at the end of that loop. Worse, if you 'yield lambda ...', that example would look like it worked. So, yes, Python absolutely has references.)
- jlokier 7y agoYes indeed, that's a bug-prone misfeature of Python. Perl and JavaScript both get default arguments right: They make a new array on each call. Perl and JavaScript also get the for-loop closures right as well. In Perl, "for (my $n = ...)" and in JavaScript "for (let n = ...)" will both create a new "cell" each time around the loop, so closures work as expected. (However, MSIE's version of "let" doesn't create a new "cell" each time, and this can be a source of difficult to see event callback bugs; best transpiled out.)
- zbentley 7y agoPerl has default arguments (outside of Devel::Declare trickery)?
- 7y ago
- Ultimatt 7y ago> join(‘,’,@{$foo->{‘bar’}}) You might write it this way. I prefer to use the features of the language developed in the last decade: join ',', $foo->{'bar'}->@* Which if that looks spooky, the * simply means everything in the array. You can just as easily slice: join ',', $foo->{'bar'}->@[2..5]
- adrianmonk 7y agoI once did a lot of Perl too, and I agree that Perl has many design flaws, but I prefer it this way. The main reason is if the same array is contained inside two different data structures, I want this to be explicitly obvious in the syntax of the language. For example: my $a = [10, 20, 30]; my $b = { array => $a }; my $c = { array => $a }; $b->{array}[0] = 99; print $c->{array}[0]; To me, anything the syntax can do to make it clear that the above code prints "99" (and not "10") is a net win. I don't care how cluttered it looks or how much extra typing it requires. If a language hides this from me in the name of cleanliness, then it's creating a leaky abstraction that is going to cause bugs and other forms of suffering. If you're in a language which has immutable arrays, then this doesn't matter. But Perl isn't that, so that's not really relevant here. To me, languages that add reference types (like C++'s) or language features that allow passing things by reference just create an extra cognitive burden. I look at some code and wonder, "Is this going to have ripple effects in distant places?", and I have to work through some rule in my head such as, if it's an integer, then no, but if it's an array, then yes. Contrast that with the Perl (or C) way. I look at some code and the syntax tells me. There's no mistaking what's going on. So less cognitive burden and less opportunity for error.