Perl 6 Advent Calendar
perl6advent.wordpress.com
perl6advent.wordpress.com
To answer some of the comments: no, this isn't satire, nor is it a marketing or advertisement piece.
I'm just having fun with the language and wrote a post in the voice of The Grinch (https://en.wikipedia.org/wiki/Grinch). It's meant to be mean. That's all there is to it. Tomorrow's article (coincidentally, also written by me), will have a more sober tone and will describe Perl 6's system of containers and variables. See if you like it more.
I'm OK if you don't like Perl 6 :) That's why we have so many different wonderful languages: everyone can find what they love. I love Perl 6. You should try it out.
Some fuddy-duddies think that preferring expression over safety is irresponsible. They might be right, but Perl is a language that doesn't have to justify itself:
https://www.perl.com/pub/1999/03/pm.html
Can't wait for the next one!
Still, I have to love the fun some Perl coders feel in their language.
Perl 6 is the only language in the world suitable for metaphorical programming.
For example, how would you implement a load-balanced pool of HTTP web servers over Port 80 in a language like Python, serving Hello World?
In Perl 6 this is just five lines:
imagine web servers, like the droplets of mists of fog
as many as the sun shines through. A clarion: Hello world.
The sun? An http server, its port 80.
Cast off!
I'll steer when I'm ready.
And that's it. What's great about Perl is that you're not stuck with a nautical analogy, you are free to mix metaphors. For example this is another way to do the exact same thing: race, ye hogs of web servers
the killing time is near. Your cries? Hello world.
The abattoir? An http server, its port 80.
Cast off!
I'll steer ye when I'm ready.
Even though it would hurt any poet's brain to read a metaphor this mixed, there's more than one way to do it, and this is really where Perl 6 shines. use Cro::HTTP::Server;
use Cro::HTTP::Router;
my $app = route {
get -> { content 'text/html', 'Hello World! ' ~ DateTime.now() }
}
my Cro::Service $service = Cro::HTTP::Server.new(
:host('localhost'), :port(9000), :$app
);
$service.start;
react whenever signal(SIGINT) {
$service.stop;
say "Goodbye!";
exit;
}I guess it is targeted at people that are already well-versed in Perl 6 (or at least Perl 5)? Maybe it should say so at the top so that people like me do not get a terrible first impression of it.
Perl 6, at least seen through the lens of this post, doesn't appear to have fixed the write-only nature of Perl 5 and it's amazing ability to help you create truly obfuscated code first time round. No tools required.
unit module Jolly;
sub term:«\c[INVISIBLE TIMES]» is export { 42 }
sub infix:«\c[INVISIBLE TIMES]» is export {
$^a × $^b
}
sub prefix:«\c[INVISIBLE SEPARATOR]» (|)
is looser(&[,]) is export
{
say "Ho-ho-ho!";
}
In order to have the line: say 42;
# OUTPUT:
# 1764
# Ho-ho-ho!
Neat tricks within the scope of the language itself perhaps, and despite everything it is great to see progress on Perl 6 even if only for reasons of nostalgia. Not a great advert for a modern language though.Despite all evidence, the Perl community persists in considering this a feature, not a bug. Which is a big part of why the Perl community is so much smaller these days than it used to be.
In other words, they're about "hacking"...
They also server as a decent health check (e.g. Catalyst seems pretty much dead), but aren't really about advertising.
I do a fair amount of perl5 script maintenance, so am familiar with the language. Advents calendars are daily small chunks, an Ideal way to introduce the language but they turned this into a "look how clever" our language is post, which to me is "wow this is hard to read and maintain."
Lamentably these examples don't give me hope that Perl6 is going to be any better at being maintained.
I used to write quite a bit of Perl 5 and didn't really understand why Perl 6 seemed like it was trying to be everything to everyone and I didn't see what problem domain it was really the obvious choice for picking it over another easier to comprehend language.
FWIW I tried Python, I just didn't like it. I've programmed a lot of languages and most I'm fine with, I just didn't like the way Python felt.
It's also likely why there have been multiple (for the most part failed) projects over the years trying to do just what you asked for. Sometimes it bears fruit in other places, but future Perl has always been beholden to, and held back by past Perl, and Perl's extreme commitment to backwards compatibility. That's actually seeming to change a little recently, with newer version actually removing long deprecated features, which bodes well for interesting future change.
I agree, and when hiring recently I specifically noted that I didn't think anyone familiar with Python, Ruby, Javascript or Perl would have much problem easily learning another on that list. The operative words in the sentence question, which admittedly had little qualifying explanation, were "what programming feels like".
I find programming Perl is often and exercise in choosing the right Perl language options to fit your idea of what you want to accomplish as closely as possible, because the language was designed with affordances for how we think and express ourselves colloquially. This is how Perl tries to ease the act of expressing intent.
I find that Python tries to ease the act of expressing intent by limiting your options to the point that you have fewer choices, but the transcription of idea to code becomes rather ingrained and automatic.
Both are valid attempts at the act of easing programmer burden, but along that spectrum, I find them opposed. I can see how many Perl coders used to one approach might find the other stifling, at least initially.
Sadly some programmers went down this path when they first encountered Perl - that gnarly Perl 5 regex that stopped them in their tracks. WTF they cried - and they never forgot that feeling.
The flipside to Perl's expressive power is the potential to disempower those that don't look deep enough to get it.
Perl 6 takes this expressivity and whipupitude to another level. I suspect this Advent post has touched a raw nerve with some commenters because they feel disempowered all over again.
Please don't be!
Perl 6 is a playful language optimised for fun: https://perl6advent.wordpress.com/2015/12/20/perl-6-christma...
Look deeper and you'll be rewarded.
Yeah, thanks. I always wanted an operator that did that.
I wonder why Perl 6 hasn't caught on?
Now I’m wondering if the remaining Perl 6 community is just a bunch of basically compulsively clever show-off blowhards that I would never want to work with. There were always some of them with Perl 5 too (along with plenty of let’s-get-stuff-done people who I do like) but the unpleasant ones seem to have firmly taken over now. And that’s not just looking at the spirit of this blog post... it’s looking at some of the language features that they decided to have.
That's the line where they lost me. Who wants to debug a situation where two unrelated modules clash because they wanted incompatible weird effects added to stdin? It would be better to have a situation like scala implicits, where you at least have to import the providing module to bring in the effects. Modules are only as useful as they are composable, in projects of any size.
However, this particular code basically just modifies a global variable (technically a dynamic one, but you get the point) - and modifications of global state will be globally visible no matter the language
I love Perl5, smalltalk, lisp, etc., and I guess for that reason I feel like we have plenty of great languages where these hazards are exposed already. I'm not excited by yet another one. I'm more interested in new languages that attempt to allow crazy hacks in a contained way, so things still compose in the large.
use lib <.>;
{ use Jolly;
# inner scope
}
# TODO: this does not throw an error try:
x = 1 / int(s)
except ZeroDivisionError, ValueError:
print "uh oh"
Oops, you just accidentally overwrote what the term ValueError means, in a way that won't get you a warning or anything. But somewhere else, far away, when you try to refer to ValueError, you're going to get really weird bugs and have no idea where they're coming from, since the stack trace will be nowhere near the code with the bug. >>> try:
... x = 1 / int(s)
... except ZeroDivisionError, ValueError:
File "<stdin>", line 3
except ZeroDivisionError, ValueError:
^
SyntaxError: invalid syntax
It now requires the "as" keyword. Also, AFAIK setting ValueError to something else affects only the current module; only modifying __builtins__.ValueError would affect other modules.I'm looking to learn more about Python, but having a hard time finding a solid starting point; I've tried 'Learn Python the Hard Way', but it doesn't seem to keep me engaged to the point where the material being learned is of interest.
and related udemy course free offer ends today, see author's post for details (https://www.reddit.com/r/learnprogramming/comments/7fxq5o/im...)
Can't recommend it enough.
Disclaimer: no affiliation whatsoever.
One of the best Python books I've read!
But I would never recommend it to a (Python) beginner. There are more 'lightweight' books/solutions for beginner.
If GP is somewhat experienced in Python and would like to broaden his knowledge - Fluent Python all the way!
[1]https://github.com/norvig/pytudes
[2]https://nbviewer.jupyter.org/url/norvig.com/ipython/Advent%2...
this is an article for people who already know perl6, and know it well
i doubt this is meant to promote perl6 outside of the perl6 community
my $old = 0;
my $val = $old but True;
say $old.Bool; # False
say $val.Bool; # True
say $val.Numeric; # 0
Which can be thought of as short for my $old = 0;
my $val = class :: is Int {
method Bool (){ True }
}.new( $old )
say $old.Bool; # False
say $val.Bool; # True
say $val.Numeric; # 0
Note that under the hood it is a little more complicated so that it will work on any instance.I think this was added as a generalization which replaces the following in Perl 5.
my $val = "0 but true";
say $val ? "True" : "False"; # True
say 0+$val; # 0My mind was so blown after day 1 of this advent calendar that I think reading the remaining 24 days might be hazardous to my sanity.
A year or two ago I decided that Perl 6 was too far along the spectrum of complexity and required front-loading of learning the language for my tastes. I program Perl 5 for a living, and love it, but I feel Perl 6 has too much stuff built in for be to devote the time to actually learning it all usefully enough to want to do anything professional in it, or want to use anything professionally written in it that I might have to poke in the code. And this comes as someone that followed development since the Parrot days, and actually read through all the Synopsis documents almost a decade ago.
That said, it's likely a phenomenally fun language to play with (it's even fun to read about development of, and novel solution in, IMO). I've seen really clever solutions using the interesting features it has (and it has a LOT of interesting features). Built in grammars, for example, are something I think is awesome, and simplify a lot of parsing code to the point of triviality.
There's a spectrum of features, which at some point starts mapping fairly evenly to TIMTOWTDI. On this spectrum I find Python too stifling, Perl 5 a happy medium, and Perl 6 providing way too much freedom (at least for work related things).
For just about everything you do in Perl 5 there is an equivalent in Perl 6 that is simpler to remember and is more general in its use.
For example using an iterator variable other than `$_` in a for loop:
Perl 5:
for my $line (...) {...}
Perl 6: for (...) -> $line {...}
Note that you can also use this for any keyword that has the form `KEYWORD CONDITION {BLOCK}` if $a.method() -> $result {...}
You can also use this exact same syntax for a lambda: @a.sort( -> $a, $b {...} )
So you can see it is more general, and since you can and do use it everywhere it is easier to remember.The other day I was trying to remember how to alias two subroutines in Perl 5;
*foo = \&bar;
I can easily remember how to do it in Perl 6 my &foo = &bar;
The things shown in this article would be very much black magic Perl 5 code, but are completely doable. If you can manage to keep from writing source filters, I think you can avoid doing the things shown in the article.I will note that this mutability makes it so that for example OO::Monitors http://modules.perl6.org/dist/OO::Monitors:github:Jonathan%2... can be made easily.
The mutability is also the reason you can import modules from other languages as if they were written in Perl 6. You just have to make sure you have the appropriate Inline module installed and loaded.
In an effort to keep the language similar looking to those used to Perl 5, there's both functions and methods for almost all core operations. You can call:
@a.sort( -> $a, $b {...} )
as you did, or you can still use the same style Perl 5 uses: sort( -> $a, $b {...}, @a);
Oh, and that anonymous subroutine syntax? The old way still works for that as well: sort( sub { ... }, @a);
But let's not forget that we can omit parens: sort sub { ... }, @a;
And also that we can omit sub entirely because the braces will be interpreted as a block because of the signature: sort { ... }, @a;
Just today I was explaining to a coworker what multiple dispatch was and how it could produce some novel solutions. For example, I remember (but annoyingly could not find) someone had implemented a solution to a Microsoft scripting challenge to score a bowling game give the score for each frame (including "/" and "X"), and someone had coded up a succinct and interesting solution using multiple dispatch.It looks interesting, and when presented together, it seems concise and easy to understand, but the truth is that nothing keeps the functions definitions all that local, so it allows for your execution branching and logic to be spread into disparate files, and a later addition of a function or method to change the control flow of the program. Given that these signatures also take into account subtyping, where it's often not possible to figure out where a call will resolve to prior to runtime, and not even good tooling is going to help you. Add in possible coercion, and it's even more complicated.
I love Perl, and I love having options, but as with everything in live, there's a happy medium, and places where you can go too far and not far enough. I think Perl 6 went too far with choices, and what's more it completely lost the thread with steering people towards the better way of doing things, which was also a big part of Perl 5 in my experience.
I really started seeing this when Larry starting playing with using sigilless variables. I suspect Larry was using them because he could and to have fun, but I really couldn't see the positive of them. In a language where you expect variables to have sigils and other identifiers to be functions (or constants, usually defined as simple functions), it really pointed to a problem in the design process to me. Just because something can be included, doesn't mean it should be, and blindly stuffing everything into the language and assuming that you can make them play together just as well as a slightly smaller set of features that's more curated smacks of a bit too much hubris.
To return to my point of too many options and features, if Perl 6 had actually been willing to do away with the syntax of Perl 5 and just go with the method syntax, I think that would have gone a long way towards keeping the things a reader had to keep in mind while reading it down. I understand why they didn't, because I've been following it from the beginning, but that doesn't mean what we're left with is a good situation. It parallels the name situation in a lot of ways. The biggest problems Perl 5 and Perl 6 ever had were each other, which is a shame. Both languages are wonderful in their own way, and would have been better off much more loosely associated. Unfortunately, that boat sailed a decade or more ago.
Sorry if I went a little overboard, but this has been percolating for a while now.
Perl 5 (a.k.a Perl) and Perl 6 are different languages.
python, ruby, perl5 ... agile and fun to work with.
perl5 is the fastest. Being around for so long means there are a lot of libraries at http://metacpan.org/ . If interested, search for... "twitter", "google", "oauth", or any other technology/api to find out there are a lot of new and maintened libraries.
perl5 libraries have great documentation, ie:
- https://metacpan.org/pod/AnyEvent::Memcached
- https://metacpan.org/pod/distribution/Net-Twitter/lib/Net/Tw...
A lot of perl communication happens directly with developers over IRC. Yes, perl community runs irc.perl .. if IRC is not your thing, you can email the developer shown at metacpan (example in links above)
Also not less important is the fact every library uploaded to metacpan gets tested in multiple platforms: https://cpantesters.org/distro/U/uri.html And, what this means is the library author uploads the library and 2 days later its possible to check if library is broken in any platform.
And of course a lot of top notch sites use perl. Many dont promote it, but check metacpan.org home for example of some sponsors.
Too bad some people that never learned perl spread the wrong message.
It is a great language. And perl6 is another language that just happens to be named "perl" and was developed in conjunction with top perl5/other lang. developers.
exit;
Perl5 despite its warts is a decent "just get moving" language, but it's easy to get frustrated with some of the community modules.
Some developers went so creative they use that (ascii draw) to test if next releases of perl are backwards compatible:
- https://metacpan.org/pod/Acme::EyeDrops
Yes, thats another positive about perl5, the code that ran 10 years ago will run the same way today
I'm actually not so sure about that. Besides Python, which espouses a "one true way", Perl culture emphasizes idiomatic code quite heavily (because that emphasis is helpful with all the options), and that usually lends itself to just a few obvious ways to approach a problem (at least at the level where this is event different between most languages. That is, well below the architecture level, which has largely language agnostic common problems). TIMTOWDI doesn't mean use all the different ways all the time[1], but is an acknowledgement that in some circumstances some ways are more intuitive and obvious that others, and this may change depending on circumstance. Esoteric and unnecessarily complex syntax is highly frowned upon
In Perl 5, if I want to perform an action on all items in an array, such as incrementing them (or concatenating, or passing to a function, etc), the following is obvious and succinct:
$_++ for @my_array;
The alternative, which is easily extended for multiple actions on each item, and is the obvious solution in those cases, but overkill for the simple case: for ( @my_array ) {
$_++;
}
The important thing is not to look at the second example and say "that looks more obvious to me", because the implicit ride to that statement is almost always "because my prior experience with other languages lends familiarity". That's a poor way to evaluate a language, because it prevents unbiased assessment. It's generally easy for languages such as Lisp to avoid this, as they look so different that people aren't generally tempted to apply their prior C experiences so directly. Perl looks close enough and allows C-like syntax enough (to ease transition) that I think it caused many people that wrote C-like Perl and didn't attempt to fully learn the language trouble when viewing idiomatic Perl.Edit: Since you likely have enough experience with Perl to have your own strong opinion on this topic, please take this less as a reply to you, and more as my take on the idea in general.