Larry Wall is a wonderful human who I had the privilege of meeting back in college. He came out for a summer tech conference we were hosting and was the keynote speaker. When we broke out into small groups he was in mine and we chatted a bit. He was the first internet famous person I had ever met - kind and unassuming, and also the creator of something highly successful in the Perl programming language.
Perl was one of the original web languages and the Swiss Army knife of scrappy programmers and sysadmins everywhere. It was a direct influence on many more recent programming languages, including Python and Ruby to name a few.
My friends and I discovered this very own home page back around the time I met him some 10 years ago. It was where I first learned the word "chartreuse", and I'm still not fully sure what color that refers to. You can find some of his writings under the "My Ravings" section, which are a hoot.
One of my favorites of his writings is The Three Virtues of a programmer (http://threevirtues.com/):
Laziness: The quality that makes you go to great effort to reduce overall energy expenditure. It makes you write labor-saving programs that other people will find useful and document what you wrote so you don't have to answer so many questions about it.
Impatience: The anger you feel when the computer is being lazy. This makes you write programs that don't just react to your needs, but actually anticipate them. Or at least pretend to.
Hubris: The quality that makes you write (and maintain) programs that other people won't want to say bad things about.
> Most of you are familiar with the virtues of a programmer. There are three, of course: laziness, impatience, and hubris.
> These are virtues of passion. They are not, however, virtues of community. The virtues of community sound like their opposites: diligence, patience, and humility.
> They're not really opposites, because you can do them all at the same time. It's another matter of perspective. These are the virtues that have brought us this far. These are the virtues that will carry our community into the future, if we do not abandon them.
I learned Perl 4 back in the mid-1990s, before the massive piles of cruft got bolted on that turned it in to Perl 5. It was basically just glorified sed/awk meets shell script in a single process, and it was awesome.
As a junior programmer, I had to do some maintenance work on a couple of daemons written in C that were just launchers for other programs. A couple thousand lines of messy, badly structured C. So I had the clever idea to just rewrite them in Perl. Suddenly they were 50 lines, easy to read, robust, and had really useful logging.
Perl 4 also spoke Sybase really well, which made it our reporting tool of choice. We could grab whatever from our Sybase databases, and format nice printed/screen reports easily in Perl.
I was really excited when Perl 5 came out, but ugh. I wound up writing about 10,000 lines of it at a dotcom, and it was so, so ugly. All the stuff that made 50 line Perl 4 beautiful made 10,000 line Perl 5 an unreadable mess. Worse, there were three of us writing it, so consistent coding standards were a big challenge.
I don't use Perl anymore for anything but one-liner fancy greps on the command line. If I have to write an actual script, it'll either be plain sh/ksh/bash, or Python or Ruby if it needs structure. I'm not going to waste my brain trying to write readable code in Perl anymore.
> I was really excited when Perl 5 came out, but ugh. I wound up writing about 10,000 lines of it at a dotcom, and it was so, so ugly. All the stuff that made 50 line Perl 4 beautiful made 10,000 line Perl 5 an unreadable mess.
I find that Perl gets a bad rap for being "unreadable". In my experience the readability of Perl is the direct result of the discipline of the person writing it. It's not hard to write readable, maintainable Perl 5, but it's _easy_ to write _crap_ Perl 5. So, you have to be disciplined in how you create things.
Just about any programming language can be made readable, with sufficient discipline. But it shouldn't require "discipline" to have basically readable code.
Python is like the opposite of Perl in that respect. It's inherently readable, and you have to go out of your way to make it difficult to grok what the code is doing. (Ruby is somewhere in the middle, but Ruby is more eloquent than Python, so I'll take a little clarity risk for the potential of even greater clarity.)
There's a joke running around Twitter about how it's hard to tell the difference between Perl and a cat stepping on your keyboard. You'll never see that for Python or Ruby.
That Python is fundamentally more readable is a myth. Unless by "readable" you mean that any Python program is superficially more visually similar to other Python programs than are programs in other languages. Syntactic white space will do that.
In comparing Python, Ruby and Perl, each relies to a certain extent on symbols in the code to express meaning. Python uses symbols very sparingly, and those it does use are either very much like other languages or established patterns from mathematics, even going so far as to ban braces for indicating structure--nothing is exotic. Perl is the opposite extreme, with to sigils encode variable context (which is a concept foreign to other language) and complex regular expression and quoting schemes built into to language. Ruby sits very much in the middle between these languages.
The use of all non-word symbols to densely encode meaning helps reduce code size at the cost of apparent readability. That's why you think Ruby is "more eloquent". Perl can be even more expressive than Ruby, but it's compactness can intimidate people, leading to defensive "humor".
Real readability comes from good structure and explicit code, whatever the language. It is especially important for developers using dynamic languages to document the contents of their data-structures.
If Python tends to be readable, it comes from a culture that values readability and focuses heavily on choosing a single, consistent style. Not from any inherent technical factor.
This is a nice piece on code readability in real life terms: http://www.pgbovine.net/python-unreadable.htm
(TLDR: code may be readable in over small sections, but what really matters is whether you can understand the whole program. If you get lazy, you will make a mess. Be explicit.)
You can quote all the "facts" you want, but I've done a lot of both Python and Perl, and it's a lot easier to walk cold into a bunch of Python code, even badly written Python. What you call "superficially more visually similar", I call consistency. If I have to use conscious thought to figure out the structure of the code, it's taking from the conscious thought I need to understand its function.
And yes, Perl is even more powerful than Ruby when it comes to making code compact, but compactness and eloquence are two different things.
Same for C++. Generally the problem is when you have multiple ways to do things, you have groups that use multiple ways to do things, and then you have to understand and maintain multiple ways that things were done.
I learned Java before I learned Perl so I've always tried to write code with small functions, use strict enabled and clear variables and I've often heard people say about my code:
"I didn't know that you could do that with Perl! I thought it was just an ugly scripting language."
I discovered Perl in the later days of 4--wait, I don't have to fuss around with lex and yacc to parse ugly formats?--and was dragged into 5 because somebody up the chain wanted us to run SATAN. Then I discovered Oraperl, and eventually DBI.
I have written some truly awful Perl in my day, and now and then some that I can look through again years later and acknowledge as not too bad. It has saved me, and through me people I work with, a great deal of time.
I like that the perl 5 code I wrote in 2002-2007 is still running, but the python 2 code I wrote circa 2008 to 2018 needs to get ported over to python 3. Should have stuck with perl!
>I learned Perl 4 back in the mid-1990s, before the massive piles of cruft got bolted on that turned it in to Perl 5.
Interesting. Can you elaborate a bit on what changes made 5 worse than 4, in your opinion?
>Perl 4 also spoke Sybase really well, which made it our reporting tool of choice. We could grab whatever from our Sybase databases, and format nice printed/screen reports easily in Perl.
Can confirm that about Perl and Sybase, anecdotally. A friend worked at banks in Singapore and Japan that used sybperl, which was a way to use Sybase from Perl. IIRC he said it made writing DB-related programs easy.
The "object oriented" stuff, while making it more powerful, looked like modem line noise, and created a half-dozen new ways to say the same thing. It drifted away from the shell-like nature of Perl 4, and lost a lot of clarity.
Do you know that Perl 5.0 actually had less syntax than Perl 4? It had more generalizable syntax, and was mostly backwards compatible, but it had fewer actual syntax rules!
Useless trivia. Both the . and the -> notations for OO programming have their roots in C. If foo is a struct, and bar is a property of the struct, foo.bar pulls that property out. If baz is a pointer to foo, then baz->bar does likewise.
In Perl the . was already taken for string concatenation, so -> was the next reasonable choice. And the analogy is surprisingly exact. For example if $foo = $bar = {} then calling bless($foo) will also bless $bar since both are just references to the actual object.
As for lots of ways to say the same thing, TIMTOWTDI was an intentional goal.
Sure, TIMTOWTDI was an intentional goal. I'm not sure it was a good goal, in hindsight. The whole "What idiot wrote this crap? Oh yeah, me" problem was worse in Perl than in other languages. And reading other people's code often involved learning whole new programming concepts.
Which is actually incorrect usage of "object oriented stuff", because you should use an accessor, not depend on the underlying representation. So that should have read `$this->mess`
multi sub trait_mod:<is> (Attribute:D $attr, :$ro!) {
# no need to do anything, because this is the default
}
class Pointer {
has $.x is ro;
has $.y is rw;
}
That is assuming you aren't fine with using `is readonly`.
class Pointer {
has $.x is readonly;
has $.y is rw;
}
Which works better with the trait mod `is required`
class Pointer {
has $.x is readonly is required;
has $.y is rw;
}
I guess require-ing files all over the code and using the global scope for everything and using globals or even a global hash and having functions read and write to that hash is something to be regretted. Not that C is much better.
I have maintained and ported Perl 3 and 4 to Perl 5, I must say the existence of PHP3 made sense after that :)
There was that trick using goto and exit to simulate functions that people writing Perl 3/4 loved. Was it done for performance reasons ?
It was done that way because that's how we learned to write functions. I dunno if it was the best way, I was just a kid then, but if you had the O'Reilly Perl books, that's how you learned it.
It was a force multiplier when comparing with C, C++ or BASH.
Perl 5 saved Perl from itself, too bad Perl 3/4 lovers kept writing Perl 3 years after 2000 until they saw the light and the truth and moved to Python.
Perl remains my go to language for a lot of kinds of tasks because its more flexible approach to data structures than the other languages that might be candidates for me (PHP, Python3), especially if it is a task where I'm having to experiment a lot to find the right approach and so am frequently revising data structures.
The big thing is that in Perl arrays and hashes act like they are infinite.
For example, you can read past the end of arrays or from non-existent hash entries and you get undef, not an error.
In a lot of applications, that is terrible. You want an error, like you get in Python. For those applications, I'd probably pick Python3 over using Perl and having to put things like "die unless exists $hash{$foo}" all over the place.
But for a lot of applications, especially involving reports where going in you don't know what you actually want or need, it is great. For instance, let's say I'm doing a report on sales. At some point I have $account (the account identifier for a customer), $service (a service we offer that they use), and $amount (the amount they ordered of the service on a particular order).
If I have a hash, "my %count", I can use it like this in Perl:
In the other languages I'd have to somewhere in there explicitly do something equivalent to:
$count{$account} = {}
when I start processing $account, and
$count{$account}{$service} = {}
the first time I come across an order of $service for $account.
That doesn't seem like much, but it is noise and if I've got enough different kinds of things I'm accumulating stats on so that I've got a lot of those it gets distracting, the same way that for programs where accessing things not predefined would be a sign of a serious error putting "die unless exists $hash{$foo}" all over the place would be distracting (and so it is clearer to do those programs in Python).
Now suppose I find out that on the report I need to not only list the count for each account of their orders for each service but the order numbers of all the orders. Simple. Just change:
and anyplace that was using $count{$account}{$service}{orders} as that count, change to using the length of that array (and of course add something to the final output that iterates the array and prints the order numbers in some pretty way).
If a language removes enough of these distractions, you can get into a very productive rapid experiment and feedback loop.
In a sense, I think removing distractions is kind of the point of high level languages. A distraction is anything that that is there that is not a natural part of the way a human thinks about the problem at hand but that is needed because the computer needs it. For example, memory management is a computer thing, not a human thing, so we expect high level languages to handle that.
Once that productive experimental phase is done, though, some of those things that were distractions might cease to be so. They can then become useful documentation to future readers of how the following code intended to use things.
That makes using a language like Perl, which lets you leave off those things when they are distractions, require some discipline if you use it for things that aren't one time throwaways. You need the discipline to go back and put those declarations in, or better to add some block comments explaining your final data structures. If you don't have that discipline, stay away from Perl.
But if you do, or if you are sure it is a one time throwaway, Perl can be a great choice.
Chartreuse comes from the Alps (Isère), and was brewed by the monks of the Grande-Chartreuse. The drink's history is pretty interesting to read about[1].
There are actually two kinds of Chartreuse, one green (easiest to find) and one yellow. The recipe supposedly containing over 100 medicinal herbs, Chartreuse was originally sold as a "health elixir" rather than a digestif. To this day the recipe is still held secret in the monastery, although production has scaled up.
As you may have guessed, it's one of my favorite liqueurs and has become my go-to "last drink" (after a big meal, when my guests leave).
Also, if you ever go skiing in the Alps, you can mess with the locals of Savoie by asking for a Chartreuse rather than a Genepi[2], a similar drink from there.
The drink [0] is actually still kind of produced by the monks. The brothers Chartreux, who have all taken vows of silence by the way, collect the medicinal herbs in their remote mountain valley where they live. They live in a castle [1] that looks like something out of the Harry Potter franchise by the way. Each of them has his own multistory rowhouse. Anyway, the herbs they collect make up the mixture, which makes up the drink, then it is brought to the nearby distillery where it is distilled. What's changed from the old days is that they don't do the distilling in the monastery. And there's actually still a Chartreuse "health elixir" [2], me and my partner buy them for our grandmas. It comes in little bottles that are put in a wooden cast-sort-of thing that opens like a matroska. You drink one teaspoon at a time, it's around 60 degrees, it has a different herb mixture, and I think it has less sugar. If you're ever around that region of the alps, the valley of the monastery is a nice place to hike.
(I wonder if Mr Wall is a dog person or a cat person type. I just realize now that having a cat stomping around could explain the look of some perl code... mmhh)
Larry Wall is a wonderful human who I had the privilege of meeting back in college. He came out for a summer tech conference we were hosting and was the keynote speaker. When we broke out into small groups he was in mine and we chatted a bit. He was the first internet famous person I had ever met - kind and unassuming, and also the creator of something highly successful in the Perl programming language.
Perl was one of the original web languages and the Swiss Army knife of scrappy programmers and sysadmins everywhere. It was a direct influence on many more recent programming languages, including Python and Ruby to name a few.
My friends and I discovered this very own home page back around the time I met him some 10 years ago. It was where I first learned the word "chartreuse", and I'm still not fully sure what color that refers to. You can find some of his writings under the "My Ravings" section, which are a hoot.
One of my favorites of his writings is The Three Virtues of a programmer (http://threevirtues.com/):
Laziness: The quality that makes you go to great effort to reduce overall energy expenditure. It makes you write labor-saving programs that other people will find useful and document what you wrote so you don't have to answer so many questions about it.
Impatience: The anger you feel when the computer is being lazy. This makes you write programs that don't just react to your needs, but actually anticipate them. Or at least pretend to.
Hubris: The quality that makes you write (and maintain) programs that other people won't want to say bad things about.