Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Oh man, this brings back memories.

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.



I also really liked the follow up on the three virtues, in the 2nd State of the Onion (http://www.wall.org/~larry/onion/onion.html)

> 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.


100% agree.

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 worked in a giant Perl, Moose heavy codebase with enforced Perl::Tidy for a bank and loved every second of it.

I admit there was a lot of "clever" code, but contrary to those who didn't bother learning the language, I didn't mind much.


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!


> All the stuff that made 50 line Perl 4 beautiful made 10,000 line Perl 5 an unreadable mess.

Yeah, that's the best description of Perl I've ever read.

At the time when the options were Perl awk, or C, it was a great language. It's just past its own time now.


>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.


What made Perl 5 worse than 4?

$this->{mess}

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`


And who writes accessor methods in PERL?

At that point, you might as well start using a heavier language.


In Modern Perl (5) you use a module such as [Moose](https://metacpan.org/pod/Moose) or if that's too heavy for you [Moo](https://metacpan.org/pod/Moo).

You rarely write accessor methods yourself in Perl 5. In Perl 6, you describe your accessors/mutators in the class definition:

    class Pointer {
        has $.x;       # a ro accessor
        has $.y is rw; # a rw mutator
    }
Which, by the way, is now faster than Perl 5.


> has $.x; # a ro accessor

> has $.y is rw; # a rw mutator

Opinion: I don't like the asymmetry of that, although I do understand that having to write "is ro" too, would make the language slightly more verbose.

Python has something similar with the syntax for properties; don't like that syntax too, for the same reason (asymmetry).

E.g.: The 2nd code example in the question here -

https://stackoverflow.com/questions/17330160/how-does-the-pr...

- the one that uses

    @x.setter
I'm not a language designer or close to it, though, just saying.


You can always add `is ro` trait modifier.

    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;
    }


Perl 4 ... the good days :)

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.


I started Perl 4 back in the mid 90s, but today I use Modern Perl with Moo. I have to say it is much cleaner than what you describe.


That mirrors my Perl experience exactly.

In the early nineties it was a force multiplier, and then it seemingly just imploded in on itself.


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:

  ++$count{$account}{$service}{orders};
  ++$count{$account}{orders};
  ++$count{orders}
  $count{$account}{$service}{total} += $amount
  $count{$account}{total} += $amount;
  $count{total} += $amount
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:

  ++$count{$account}{$service}{orders};
to

  push @{$count{$account}{$service}{orders}}, $order_number;
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.


You can access an item in a hash in a similar manner with Ruby now.

https://ruby-doc.org/core-2.3.1/Hash.html#method-i-dig


I think Python defaultdict does some of what you are looking for.

https://docs.python.org/3/library/collections.html#collectio...


Chartreuse is a kind of green-ish color, it comes for the drink! Go to France and ask it as a digestif it's great ( but gives me terrible headaches ).

And thanks for the three rules maybe now I might explain my manager why my laziness is good


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.

[1]: https://en.wikipedia.org/wiki/Chartreuse_(liqueur) [2]: https://en.wikipedia.org/wiki/G%C3%A9n%C3%A9pi


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.

[0] https://en.wikipedia.org/wiki/Chartreuse_(liqueur) [1] https://en.wikipedia.org/wiki/Grande_Chartreuse [2] https://en.wikipedia.org/wiki/Chartreuse_(liqueur)#/media/Fi...


There is a great documentary [1] about the Grande Chartreuse, available on DVD [2].

1: https://en.wikipedia.org/wiki/Into_Great_Silence

2: https://www.amazon.com/Into-Great-Silence-Two-Disc-Set/dp/B0...


It's on Youtube [0], though the quality is lacking. Thanks for sharing this!

[0] https://www.youtube.com/watch?v=fgfU_RRNYkw



You can also have it in feline format as a stone gray coloured little beast with yellow/orange eyes:

https://en.wikipedia.org/wiki/Chartreux

(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)


It is also the background color of the page in question if you are looking for a visual example.


also, it's the background color for his page


> ... the word "chartreuse", and I'm still not fully sure what color that refers to.

Take a look at the background colour of the web site that this thread is about. :-)


Cool fact about chartreuse: it's a color named for a liqueur.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: