Hacker News new | comments | show | ask | jobs | submit login
A Review of Perl 6 (evanmiller.org)
293 points by jparise 10 months ago | hide | past | web | favorite | 164 comments

Subpar performance is a huge drawback of Perl 6.

I usually don't program in Perl, but occasionally use it instead of sed.

Compare, Perl 5 vs. Perl 6:

    $ time yes | head -n1000000 | perl -pe 's/y/n/' >/dev/null

    real	0m0.945s
    user	0m0.944s
    sys	0m0.016s
    $ time yes | head -n1000000 | perl6 -pe 's/y/n/' >/dev/null

    real	2m49.881s
    user	2m44.892s
    sys	0m2.184s
Spending several minutes to do what can be done in under 1 second is just unacceptable.

It's nice to dream up a language with the perfect semantics; in reality, all programming languages make compromises because they are limited by current compiler technology. Ruby is on one extreme end of the spectrum, making little compromises on beauty, but we all know how slow it is.

Go is on the other end of the spectrum; they have tuned their syntax to be fast to parse, and have stuck to implementing existing compiler technology. If your semantics are very far removed from how computers work, you need a very advanced compiler like GHC.

It sounds like Perl6 is somewhat centrist in its approach, and has innovated quite a bit; I think it will be possible to almost match Perl5's speed with reasonable effort. The interpreter might do well on small examples, but the VM will dominate in very large ones. Many compilers are tiered in that they use an interpreter for cold code, and spend the effort to generate code and JIT hot code.

Yes, performance is where most of the funding is currently going into.

Bleed commits on VM for example, recently passed Perl 5 on speed with read-a-million-line-file-and-sum-up-number-of-chars bench ( https://twitter.com/zoffix/status/895684203550973956 ).

What are bleed commits?

The “cutting edge” of technology or craft is the newest / greatest stuff, pushing the field forward in new unexplored directions, by analogy to the cutting edge of a plow or a knife which slices through some uncut material or unbroken ground. I believe the metaphorical use of the term dates from the middle of the 20th century.

The “bleeding edge” is a more recent term for the same idea, emphasizing that being at the cutting edge might involve danger to yourself.

Commits that happened recently and aren't part of any release yet :)

Commits that would go into the bleeding edge builds

Yes, I haven't tried lately, but for my own small text manipulation program, Perl 6 was still more than 100 times slower than Perl 5 the last time I tried. Probably because of some JIT delaying the startup time. But since my use is calling small programs, it was a no go for me; and after one year it had not improved a bit.

Many string and dictionary based operations seem to work faster in Perl5 than Python for me.

Perl5 string and hash performance was always top notch.

The Perl 5 version was indeed also 3 to 4 times faster than the Python one.

Did you compare to python2 or python3, cause python3 is in the same league as perl6.

wow, that is insane. You picked an awesome example.

We're only talking about on the order of a million bytes in your example, so 2 minutes to process on the order of 1 megabyte with a regex is just insane. If you applied it to 1 gigabyte of files that would be an even 2 days vs Perl 5 @ 16 minutes.[1] Sixteen minutes isn't enough to rewrite it in C, so Perl 5 is "fast enough". You can go get a coffee or think about the next thing you want to do with the data, or write the next part of your processing. But two days is prohibitive: it breaks your workflow.




It might help to point out that the core team only froze the spec during Christmas last year or year before and have therefore just started on performance in a way. If you check the perl6 weekly site you'll see significant progress on a weekly basis (ex: Lists sped up by 1500%).

So, a fairly simple change to this will bring down the time to a few ms (86 ms on my computer)

  time yes | head -n1000000 | perl6 -e 'for $*IN.readchars { .subst("y", "n").print }’
Its slightly more complicated because I’m having it read the input in a chunk instead of on a per-line basis and I’m using subst on a literal instead of a regex.

> \d now matches Unicode digits such as ᭕ (a Balinese five) and ๓ (a Thai three).

This sounds like a disaster waiting to happen.

It has been like that since forever (at least since 5.10, 2007). To only match 0-9, use [0-9] or /\d/a (/a is available since 5.14, 2011).

How, exactly?

Perl 6 is a spec. The current Rakudo implementation is being focused toward sped now that the spec is stable.

It is a drawback of the current implementations of Perl 6, yes.

did you file a bug? is there a way to trace the perl6 one and see where the hotspots are?

perl6 --profile yourprogram.p6

I found this a nifty intro to perl6. I am a 70 year old retiree and have 37 years of C programming and some C++, perl5, and other languages. This is the first time I've been able to make the slightest headway digging perl6.

I am a 70 year old retiree and have 37 years of C programming

That's awesome. Thank you for joining the community here. I have a lot of respect for our elders. New technology gets written about using old technology.

fnj is also a longtime community member of Slashdot, and well regarded.

> I am a 70 year old retiree and have 37 years of C programming and some C++, perl5, and other languages

Sir, when I grow up, I wish to have the same passion as you!

A lot of people here seems to think there is a lot of potential for perl6, with the only complaints being the name and its speed, with at least speed expected to improve.

But I thought this review sounded pretty damning.

Numerical operations are opaque as you never quite know if it's a rational or a float.

The grammar engine is inferior to other languages 3rd party modules, hard to debug and seems to not be suitable for its main purpose (parsing perl6!)

Everything seems to be writable in a multitude of ways with no clear indication if these ways are functionally different.

I do a lot of NLP in python and I wish for better tools to munge and clean up my text data, and have been curious about perl6, but after reading this review I don't find Perl all that enticing at all.

> Numerical operations are opaque as you never quite know if it's a rational or a float.

Not so. When you put in floats, you get floats out. If you want always-rational numbers, put in FatRat and you get out FatRat -- with the predictable bad performance on algorithms that converge on irrational numbers.

> The grammar engine is inferior to other languages 3rd party modules

Nothing stops you from using superior 3rd party modules in Perl 6. Heck, you can use Python modules through Inline::Python in Perl 6.

> hard to debug

I haven't found it harder to debug than other parser libraries, but your mileage my vary. I'm a fan of Grammar::Tracer, which hasn't failed me yet.

> Everything seems to be writable in a multitude of ways with no clear indication if these ways are functionally different.

That is true, but I find it irksome that you mention it right next to Python, which also has a multitude of ways to do different things, even though the Zen of Python says there should be just one way. Think string formatting, for example. I believe it's a trait of every programming language that doesn't set out to babysit you.

Thank you for inputs on the specifics.

Would you say the reviewer/author is misunderstanding Perl6, or that I am misunderstanding the review?

I think you are reading in too much the criticism of how grammars work. Ultimately the leading compiler uses the Perl 6 grammar engine and tooling to implement the language compiler! So if your needs are substantially less complex than needing to implement your own programming language, say parse some XML or something. Then the grammar engine is more than competent. The authors criticism of how to handle errors during parse and making a really advanced robust parser is definitely fair. However, the technology for doing this in a deep way does exist. It's already found in the grammar debugger module from one of the core devs (https://github.com/jnthn/grammar-debugger). There just isn't perhaps a nicer "user" level API for you handling parsing in a flexible way when something goes wrong. There are mechanisms for making your grammar flexible though such as proto rules/tokens/regexes https://docs.perl6.org/language/grammars#Protoregexes here when different options are encountered you can trigger different code to handle whats being parsed.

Evan did not intend folk to read what he wrote as a definitive testimonial.


Check out Perl 6's (or Rakudo's if you prefer) error messages. If they are LTA (Less Than Awesome), it's a bug. Often the Perl 6 Grammar that is parsing my Perl 6 code actually tells me things I didn't notice.... The stuff you need is available, but Perl 6 isn't going to give you an automagic generic error that's any better than "Parse failed at line 5 character 13". You can do that yourself rather easily, and if you want no LTA errors, you'll need to do them yourself.

The review touches the basics, and can't go into all the options that are available.

This is an interesting article overall, but I'm unsure what this part is trying to say:

> Perl 6 is aware of graphemes and combining codepoints, and unlike Python, Swift, or Elixir, Perl 6 can can access arbitrary graphemes by position in constant time, rather than iterating over every grapheme to access a particular one. [...] Graphemes are stored internally as 32-bit integers; this address space is large enough to contain all legal codepoint combinations

It sounds like Perl6 is simply storing strings as UTF-32. AFAIK, there's nothing called a "grapheme" in Unicode; the closest I know of are "grapheme clusters", which are theoretically unbounded in size and so cannot simply be stored in a 32-bit integer. Maybe by "grapheme" the author means "Unicode scalar value"? But being able to access those in constant time isn't especially useful, AFAIK.

Perl6 extends (NFC normalized) UTF-32 with autogenerated 'synthetic' codpoints for grapheme clusters. This yields an upper bound for the number of unique multi-codepoint grapheme clusters a Perl6 program may encounter (something like 2^31 as I believe only negative numbers are used for synthetics).

Is there a document somewhere describing Perl6's string implementation more precisely? To the best of my knowledge this can't be done, since not only is it legal for combining characters to appear an unlimited number of times in a single grapheme cluster, even discounting repetition the number of legal combinations of single combining characters is surely larger than 2^31. It seems self-evident that if all theoretically-legal combinations of codepoints fit into a 32-bit space, then we just wouldn't bother with combining characters and would use precomposed glyphs exclusively!

You're right it can't be done (Perl 6 does that a lot).

The feature could be made to start a new mapping of synthetic characters before it runs out, and throw away the mapping when the last of the old strands gets GCed.

Basically it is a problem in theory, but might not be in practice.

Not everything that's theoretically unsound is a problem in practice (eg a 128-bit address space would clearly be large enough - there are only so many atoms on the surface of the earth, and the number of glyphs written by humans is quite a bit smaller than that...)

This is exactly what I'm asking though; if they decided to treat some bespoke combinations of combining characters as though they were precomposed, then I'm curious how they generated that list, and I'm curious what fallback behavior it has for grapheme clusters that aren't specifically accounted for in this way. I'm also sort of curious what their rationale is for doing any of this in the first place, since it seems like the benefit of constant-time indexing isn't especially useful given the memory tradeoffs.

From what I understand, those "autogenerated 'synthetic' codepoints" aren't guaranteed to be identical across runs (and typically won't be).

What they do is a bit like LZW compression: use a set of codes that is larger than the number of simple graphemes, assign each simple grapheme its 'normal' code and, whenever one encounters a complex one, assign it the first hitherto unused 'code point'.

That works fine until it breaks. They hope it never breaks in practice. I think there's a good chance it won't, but still don't think this is a good idea.

those "autogenerated 'synthetic' codepoints" aren't guaranteed to be identical across runs

Indeed: It's not an exchange format, but the format of the internal in-memory string representation.

If it's only intended as an in-memory representation, then how about a 24-bit representation, which is just as likely to work "in practice, if not in theory" as the 32-bit representation, while saving 25% of the memory? That gives you 16 million unique grapheme clusters per program instance, which, heck, is probably still more than 99% of programs use; you could easily get away with a 16-bit representation and use no more memory for strings than Java, C#, or Javascript. It's not like using a unique superset of UTF-32 is saving anyone the hassle of needing to convert between formats, since the vast majority of the world is ASCII-ish, UTF-8, and UTF-16 anyway.

> how about a 24-bit representation

Because 24-bit integers are not a thing on x86?

Who says you need to use integers? You're completely ignoring my question. Again, if you know of a design doc buried on a mailing list somewhere please just link me to that so that I can answer all of my questions at once.

I'm curious how they generated that list

Synthetic codepoints get dynamically assigned as they are encountered during program execution.

I'm also sort of curious what their rationale is for doing any of this in the first place

The rational is constant-time indexing at grapheme cluster level, with the regex engine probably part of the motivation.

Since this representation is internal, it means that if there is ever a need for more clusters, they can switch to 64 bit integers without breaking any compatibility.

Correct. I should also have clarified that my comment applies to Rakudo Perl6 running on MoarVM. As far as I'm aware, other backends are still behind in implementing proper Unicode semantics.

MoarVM stores strings as either 32-bit signed or 8-bit signed. Negative numbers are reserved for "synthetic's" which are for grapheme clusters which contain more than a single codepoint. Synthetics are allocated as needed, so we can store as much as we need to. The only issue would be storing more than 2^31 possible combinations… though you would run out of memory before you ran out of negative numbers in the 32-bit integer space.

Cool, thanks for the info. Should I assume from the bevy of comments rather than links that this isn't documented anywhere? If both myself and the OP had to ask the devs personally for this info, then it may be productive to make a blog post describing your strategy (or just a comment in the source, even).

You might want to see some of my slides here:


Link is where the string implementation starts. I don't see it detailed in our documentation, but it may be somewhere.

As part of my Unicode grant from the Perl Foundation I will try and add some implementation information to the MoarVM docs.

Let me know if you have anymore questions, Thanks!

Per the Unicode standard, "grapheme" means "what a user thinks of as a character", i.e. nothing to do with computers, whereas "grapheme clusters" are sequences of codepoints that "approximate" a grapheme (more approximately if it's EGC, less approximately if it's TGC).[1]

Being able to access characters or sub-strings in constant time is useful for some (all?) character and sub-string processing.

[1] http://www.unicode.org/glossary/#grapheme and http://www.unicode.org/glossary/#grapheme_cluster

> ... but I personally prefer to be treated like a responsible adult rather than, for instance, a teenager trapped in the father-knows-best house of Go.

My feelings exactly.

Oh, -I- should be treated like a responsible adult, -but those maniacs I work with shouldn't be-.

Is the language for individuals, or for teams? Is it for software developers, or dabblers from other domains who have to crank out a bit of code?

I and the maniacs I work with should be treated as reponisble adults.

IMHO the issues are never with technology itself, it's the people. And whatever language or technology you are using won't make any difference if the people themselves don't want to work as a team.

Perl always was, and still is, a hacker's language. It is for individuals who want to get shit done NOW, disregarding maintainability or teamwork. For this particular niche, it is indispensable.

Not saying otherwise. I, personally, prefer languages I can come back to a month later and figure out what the hell -I- was thinking, let alone someone else, but I understand the appeal.

My point was that it's not really a pro/con of a language on whether it favors individuals hacking, or teams developing, but merely a consideration for its appropriateness to your problem, and so to say "I prefer" needs to be qualified as to -when- it's preferable.

There's a lot to learn in P6 (I'm not an expert at all) and you could definitely beat anyone except for an APL developer in an obfuscated code contest IF you wanted to. However, I find the majority of P6 to be quite pleasant to read and terse to write...a nicely optimized ratio.

You'd probably enjoy this short essay, if you haven't seen it yet: https://www.joelonsoftware.com/2004/12/06/news-45/

Its been endlessly stated but naming it 'Perl 6' was a huge mistake. Perl 5 has an enduring reputation for crufty, unmaintainable code written by graybeard sysadmins. I wrote a lot myself that I wouldn't want to ever deal with again. I think they would have benefitted from a clean break from a marketing perspective, especially considering it's completely different.

Perl 5 was my first love as a programming language. I rarely use it now, but it will always have a special place in my heart. I learned so much with that language. Blessing a regex for example. That was the first time I felt like I had a super power.

Perl 5 is still a great replacement for sed and awk in one-liners. Which is what it was originally envisaged as (although more than just one-liners), and is probably how it should survive - the most powerful one-line tool in existence.

With all due respect to APL?

I think they mean Nix terminal work. APL & J obviously win hands down as overal one-liner kings. Can Dyalog be used via the terminal in that manner? I'm guessing so, but never seen it used outside the IDE.

[citation needed]


> > Apples and oranges. Haskell is defined by a language specification, not an implementation.

Do you have the wrong thread? You're quoting https://news.ycombinator.com/item?id=15005881 , but replying to https://news.ycombinator.com/item?id=15005874 (albeit by the same user).

"Perl 5 was my first love as a programming language" is exactly how I describe it too.

The language has tons of warts, but also an amazing community. Participating in that community taught me more about the practice of software engineering than my computer science degree.

There's actually talk about amending the name for next major language release ( https://rakudo.party/post/The-Hot-New-Language-Named-Rakudo ). Exactly for the reasons you state: it's a completely different language than Perl and so far it proved too confusing for everyone.

For what it's worth, I disagree and was a bit annoyed that you've re-opened that particular Pandora's box again ;)

I don't mind annoying people to solve problems.

You should mind annoying people to cause problems. Bringing up the language naming thing, again after 10+ years of discussion, has all of the problem solving ability of "hay guise whats going on in this thread?"

Branding is not the problem with Perl 6, though it is the easiest thing to bikeshed. The problem is compiler speed, language interoperability, and enough of a toolchain to start building serious apps. Make that good enough, and no one will care what our language is called.

Well, I present to you "D", the language impossible to find anything about on the Intarwebz.

You can try "dlang"

I think you're trying to solve the wrong problem: Don't move the languages further apart through rebranding, move the implementations closer together through improved interoperability.

Have a frontend that can invoke the perl5 interpreter as well as Rakudo as appropriate, supporting the perl5 command line flags, and arguably quite a bit of the problem goes away.

Maybe the problem isn't with the "Perl" part of the name, but with the "6" part? It sounds like an incremental update when it's actually a new language.

Perl X 10.0, like Apple did then?

dunno perl6 seems fine to me, rakudo just looks like something half my team will wonder how to pronounce.. I agree with the other guy that people want a platform that they can use and is performant

I think the people behind the Eta programming language would agrwe with you: they implemented Haskell on the JVM, fully compatible with the Haskell standard and including many popular GHC extensions, but don't mention the word Haskell at all on their landing page: http://eta-lang.org/

Apples and oranges. Haskell is defined by a language specification, not an implementation.

Only that most people program in GHC, not Haskell.

I feel there's a subtlety to your comment that I don't get. Can you explain? (I've not yet learned Haskell.)

There was a 1998 "Haskell Report" which formally defined Haskell-the-language. This version of Haskell is called Haskell 98 (sort of like C++98). There is also an updated version released in 2010, which defines an expanded language called Haskell 2010.



The purpose of these documents is to specify what an implementation of Haskell 98 or 2010, respectively, should support. Just like the analogous standards published for the C and C++ languages, the Haskell reports make no reference to any specific implementation.

The most popular implementation of Haskell is the GHC compiler. (In fact, in reality it's the only compiler anyone uses, with very few exceptions. For better or worse, Haskell is a one-implementation language at present.) GHC accepts a greatly expanded language compared to what the reports specify, including a large number of language extensions that can be turned on with flags. (sort of like how Clang or modern GCC accept C++11/14). There are minor changes from one version to another, so the language accepted by GHC today is often called GHC Haskell for disambiguation.

What GP is pointing out is that almost everyone using Haskell today writes in the language that GHC accepts today instead of sticking to some official standard.

If you want to learn Haskell, you don't need to worry about this at all. All reference materials and books teach modern GHC Haskell, which is also what is used by practically all Haskell users. As noted before, very few people use non-GHC compilers (usually it's just the people implementing or testing them) and you're very unlikely to encounter these implementations.

> so the language accepted by GHC today is often called GHC Haskell for disambiguation

s/by GHC today/by the newest available GHC/

Perl 6 is defined by a test suite, not an implementation. So more like oranges & lemons.

Once I got about halfway into this review, talking about the "whatever star" and all the different ways to declare hashes, it seems like this language is right on track to do the same.

I know the break from Python 2 to 3 is also a mistake, but I don't know which one.

I learned Python 3 because it seemed that it was the new one, but to great confusion Python 2 is alive and default in Linux distributions.

I don't get all this confusion wrt Python 2 and Python 3, it's not different from GCC supporting different C standards. Just run the correct executable (i.e. python2 or python3) and done.

In response to parent comment, Perl 6 is Perl. I don't think that it's difficult to understand that Perl is a family of languages, and Perl 6 is a more recent and sophisticated sibling to Perl 5.

All of this is bikeshedding to me.

I think the Python 2->3 and Perl 5->6 _is_ different from GCC supporting different C standards.

I think that you are overlooking the fact that the vast majority of python 2 code wouldn't run by default with python 3. Yes, there are now conversion utilities that handle most (all? maybe?) of the scenarios, but the fact remains that both Python 3 and Perl 6 break backwards compatibility.

C and C++ have tried very hard to not do this. Your old C code and your old C++ code will almost always compile as is with a newer standard.

Your old C code and your old C++ code will almost always compile as is with a newer standard.

Depends on the code: Some of it won't compile without providing just the right set of flags.

In case of C, for me the crucial feature is not so much full backwards compatibility, but interoperability (you can link the object code regardless of the language version) and the convenience of using the same frontend executable.

In case of Perl, the former is currently possible to some degree via the Perl5 module Inline::Perl6 and the Perl6 module Inline::Perl5.

Personally, I would like to see the latter become a reality as well - this is the solution I'd perfer over trying to distance Perl6 from Perl5 via rebranding.

If you browse the #perl6-toolchain logs[1] you'll see folk making steady progress toward practical interop of multiple versions of the P6 language (6.c, 6.d, etc.), P6 compilers (Rakudo 2017.07 etc.), and P6 modules on the one hand and hosting this stuff on CPAN on the other. But perhaps you know about that already.

I may be imagining things but, peering years into the future, it seems this versioning management aspect of the P6 toolchain might end up being the foundation of a new multiple lang/compiler/module version juggling Perl package manager that can be used with P5, P6, python etc. Does that make sense to you?

[1] https://irclog.perlgeek.de/perl6-toolchain

It is different, all of the differences between Python 2 & 3 seem like the difference from one version of Perl 5 to another as far as I can tell. The main thing is Perl 5 tries to remain mostly backward compatible. I have heard of one company switching back to Perl 5 after switching to various “fad” languages for this very reason. (I wasn't told which company it was, likely because of an NDA) There have occasionally been bugs that P5P were hesitant to remove because someone might be relying on them.

One of the things I've heard is that `print` went from a keyword to a subroutine in Python, or something to that effect. In Perl 5 for most of them there is not really a difference, and what difference there is gets smaller every year.

Another is Unicode, which Perl 5 managed to improve without breaking most existing code. (some of it has to be enabled with a pragma statement)

Usually the only code that gets broken, is code that digs into the internals in some fashion, or use an unintended “feature”. (or occasionally even a feature that should have never been added in the first place)

One such unintended feature which relied on the compiler generating incorrect code was:

    sub foo {
      my $bar = 10 if 0;
      say $bar++;
    foo; # 10
    foo; # 11
    foo; # 12
Which was superseded by the `state` declaration.

    sub foo {
      state $bar = 10;
      say $bar++;
As far as Perl 5 vs Perl 6, it is more like C++ vs C# + Haskell + various other languages

Perl 6 breaks backwards compatibility in all the ways that needed to be broken to modernize the syntax, and reduce special cases. Even infix operators are no longer special.

From what I can see Python 3 breaks backward compatibility for things it didn't really need to if they tried harder. (It would have made the implementation more difficult to work on.)

Correct, but practically, it doesn't matter. If you compile C89, you use gcc in that mode, if C11, similarly. With Python, if you want Python 2, you run Python 2, if 3, Python 3. Backwards compatibility is another issue. IDK if people really build say C89 code with C99 or C11 compilers or use multiple standards concurrently in a given project.

I think Ubuntu switched over to python 3 by default recently.

If they still call the executable "python" then they’re demonstrating the whole issue with keeping the same name for wildly-incompatible upgrades: it “shouldn’t" matter what version a reasonably-modern OS chooses and yet it does, solely because of the name. No one would complain about having "/usr/bin/python", "/usr/bin/py3k", "/usr/bin/perl" and "/usr/bin/rakudo" all at once on the same OS but being forced to choose two is insane.

So like, the same thing that happened between various perl versions (inc 4x -> 5x) and python? Or C++ versions? or even c-library or executable format changes?

Things break sometimes.

If you want good error reporting from grammars then you really need to implement a FAILGOAL in the grammar. For example:

  method FAILGOAL($goal) { die "cannot find $goal near position {self.pos}" }
There is also a very helpful grammar tracer and debugger when developing a grammar:

  use Grammar::Tracer;

  use Grammar::Debugger;

I managed to not only read that several times over as FAILGOAT, but think that, yes, that sounds like an awesome solution.

Perl6 feels like it could be the ultimate language for Man, Machine, Mineral, and Beast, if only we could teleport into a parallel universe where it war already in widespread usage. The sense of sheer potential off the language is intoxicating.

I like to imagine the Geth in Mass Effect run on a hybrid Perl6/Erlang platform.

Funny you mentioning Geth... Perl 6's core devs use a bot named Geth to report new commits on IRC. And.... it's written in Perl 6 ( https://github.com/perl6/geth ) :)

heh, same name as the Go Ethereum client https://geth.ethereum.org/

Huh, fun :)

I really don't understand why you say that. Care to expand? I can't picture what problems I have that perl6 is the solution to.

Well, what kinds of programming tasks do you normally do?

The Geth definitely use Lisp, but the humanoids at the Citadel use Perl6 ;)

Is that before or after they made their Faustian bargain with the Old Machines?

The Old Machines are still running Perl 5.

  $ perl6
  To exit type 'exit' or '^D'
  > 0.3 == 3e-1
I'm really really not sure how I feel about this. Does anyone know why the decision was made to make exponential notation return a float while decimal notation returns a rational?

The "e" notation is an explicit reference to the floating point representation, so it should obviously use it.

But decimal literal numbers (that is, not using the "e" notation) are best represented with rational values, in the sense that they don't need any approximation, so there really is no reason to use floating points for them.

The "e" notation is just a shorthand for multiplying by a power of ten. I was kinda surprised when the article stated that "5.23e5" wasn't treated the same as as "5.23 * 10 * * 5". Mathematically, rational to an integer power is always rational. This strikes me more as a half-measure that can cause surprise and unpredictability.

edit: can't get double-asterisk to get through HN's markup :(

Fine, but then how do you suggest one should write floating point literal values?

PS. I guess there is the "f" suffix as in C++. Well, for some reason that's not what Perl 6 decided. I, for one, think it's simple enough to use the "e" notation. If you want to write a Rat with a power of ten, you can always literally write say


I don't have a ready obvious alternative (though I do see others suggested an "f" suffix). The lack of alternative was sort of my point... language design is tricky, and small features in one place can paint you into a corner when implementing another.

Establishing the right dynamic tension between those features (and the parser, and the VM, and the user's mental model) definitely makes language design one of the high arts in the computer world.

I'm not even saying this was the wrong decision; just that it causing a surprising deviation from how numeric literals behave in other languages.

But Perl's goal has always seemed to me to be less about creating a rigorous language with well defined types that map to the low level; and more about creating an expressive feeling (to humans) language, where fundamental differences in type were merely an implementation detail.

So I'm not surprised that it deviates from the norm in some interesting ways; I'm just not sure if I personally like the feel when I try to speak it :)

... but I might think to close to the metal to be the target audience.

"f" on the end, like floats in C?

Is it though? To me it's just "scientific notation".

Exponential notation doesn't need any approximation either, xey just means x * 10 * * y, and both x and 10 * * y must be rational numbers.

  Python 2.7.3 (default, May  4 2017, 16:44:54) [MSC v.1600 
  32 bit (Intel)] on win32
  Type "help", "copyright", "credits" or "license" for more 
  >>> 0.1+0.2==0.3

A more direct comparison given perl6's typing would be either

    >>> from decimal import Decimal
    >>> Decimal("0.1") + Decimal("0.2") == Decimal("0.3")

    >>> 0.3 == 3e-1
What the perl6 "0.3 != 3e-1" comparison is really doing is

    >>> from decimal import Decimal
    >>> Decimal("0.3") == 3e-1

I understand why decimal notation returns a rational, I'm wondering why exponential notation doesn't.

I'm a bit disappointed about grammars. Usually, when I try to use them, it gets difficult. Especially when recursion is involved. Lately, for instance, I was reading the ECMAScript 2016 reference, and in it they define a repetition of elements with recursion[1]:

        ArgumentList , AssignmentExpression
I've never managed to do something like that with Perl 6's grammar. Basically every time I try to use recursion, it doesn't quite work unless I do some tricks.

Maybe I ask too much, I don't know.

1. http://www.ecma-international.org/ecma-262/7.0/index.html#se...

Huh? Not sure I know what you mean, because something like the following trivially works?

    grammar LOL {
        rule TOP { <string> }
        rule string { <[a..z]><string>? }

    my @lulz = LOL.parse("abcdef");
    say @lulz;

     string => 「abcdef」
      string => 「bcdef」
       string => 「cdef」
        string => 「def」
         string => 「ef」
          string => 「f」]

I didn't say recursion never works. I say most of the times, it doesn't. There is no alternation in the example you provide, for instance.

Had you written it like this:

    grammar {
        rule TOP { <string> }
        rule string { <[a..z]> | <string><[a..z]> }
as inspired by the rule mentioned above in the ECMAscript reference, it would fail.

I'm probably off the mark a little bit.... but 'rule' implies that whitespace is really <.ws> (totally ignored white space matching thingy). '|' is the Longest-Match-First (different from Perl/PCRE/etc). LMF is not possible in the case where it is not a DFA... the implicit <.ws> that is there by using 'rule' and having a space might be your problem... :)

TL;DR Don't forget that 'rule' does <.ws> magic. This may or may not actually be part of the problem...

I have seen a similar sort of thing and only half understand the answer i got.. Check your implicit <.ws> and '|' LMF.

I had tried replacing 'rule' by 'token' and it did not change much.

Superb; enjoyable write up. Very witty in parts, no puns in sight. Makes me want to try Perl6 out.

> no puns in sight

> me want to try Perl6 out

Given your own understanding of desirabilities, I'd recommend you to steer away from this community in particular. :-)

I also enjoyed the article but came away with absolutely no desire to ever use or encounter perl6.

The 6 is for the number of users. ;-)

On a more serious note, your comment is pretty much what I've seen most people say. I will probably poke at it, at some point. I won't have a good reason to do so, except just to learn.

There is more than you think and I expect a decent amount of people to come over from Perl5, Ruby, and Python if the language gets optimized enough. Just for small stuff at first, but in larger numbers as the libraries start to show up

I was similarly wondering what the killer application, platform, or tool will be.

This review calls out the ease of FFI and a reasonable set of concurrency primitives so, in conjunction with the grammars and the data-mangling heritage, I conjecture that Perl6 might be good for IoT programming or SCADA. Of course it's a long trek from "might be good for" to "look at this compelling thing we built with it".

Each to their own. What's your brand of poison?

Full disclosure: I'm not sure a language called perl will ever appeal to me -- I have amusing post-traumatic life memories of perl. My main perl using/learning experience was back in college for a IT job. I was using this tool called unattended[1] which was about automating windows xp installations ... Involved writing hacky perl scripts to do very hacky things -- with some amount of building on top of somebody else's injected (and in some cases dynamically generated) perl code -- in a context where the only way to run/test changes was to reboot a machine, initiate a complete windows installation, wait for it to finish, and then wait for various post-installation hooks to kick in and eventually get around to running your code...

NOT a fun place to learn the many many random subtleties of $ vs @ variable dereferencing behavior or any of the other samples from the long list of surprising perl behaviors ...

[1] http://unattended.sourceforge.net/index.php

I have a lifelong preference for languages which don't actively prefer obfuscation over clarity... If your expectation for your developer's workflow is such that calling a directory 't' for 'tests' is deemed a useful abbreviation -- then I just simply do not want anything to do with that workflow.

> Modifiers (i for case-insenstive is the most important one) can appear inside a regex when preceded by a colon. For example, this Perl 5 regex:

> (Male|Female) (?:[Cc][Aa][Tt]|[Dd][Oo][Gg])

> would be translated to Perl 6 as:

> (Male || Female) ' ' [:i cat || dog]

Perl 5 does support this feature:

(Male|Female) ((?i)cat|dog)


(Male|Female) (?i:cat|dog)

Also I would use

    ( Male | Female )
in Perl 6, as it tries to match both in parallel.

The reason the version with || is in P5-to-p6 is that is how | works in Perl 5.

FWIW, I note my own trigger for revisiting Perl 6, is the existence of a standards-compliant transliterating implementation of another language, say Javascript, written in Perl 6. No ambiguity, just "does it pass the validation suite?", and "how fast is it?". A decade of "it's usable now!" has left that sentence with little signal weight for me.

The idea is, at least as of a decade ago, it was straightforward to massage the then ECMA spec into Perl 6 code. The spec says "Go to step 4 ... 4. ..."? Well, "goto Step_4;... Step_4: ..." is code. And so on. Perl 6, at least as envisioned then, is a very nice language for language implementation. Implementation often goes like this: most of the language is easy, nicely compatible with the target; some of it is hard, requiring some struggle to impedance match; and tiny bit of it is impossible, or nearly so, or requires rewriting all the rest, because of "gotcha" conflicts with the target semantics. With a rich kitchen-sink target, almost everything becomes easier, and there's likely some hook you can use to get that impossible bit done. And when writing a compiler, (then, almost) general grammars, and multiple dispatch with type sets, is a nice place to be.

But the corollary is, when I don't see a compliant ES2017 transliterated to Perl 6, then I assume something is wrong - something isn't working yet - be it unfortunate spec, or "doesn't quite work yet at scale" implementation, or community.

The "whatever star" seems like a less-well-implemented version of Wolfram Language's pure anonymous functions:


Essentially, WL uses # instead of * and requires a "&" to indicate when you're done defining your function. So the WL equivalent to Perl's

    (1, 2, 3).map: * * 2 

    Map[ #*2&, {1,2,3}] 
(idiomatically you would use /@ as shorthand for Map[], so it would be)

Except WL is far more general with what you can do with #, and you can do things like this:

    Outer[ #1 * #2 &, {1,2,3}, {4,5,6}]
which returns

    {{4, 5, 6}, {8, 10, 12}, {12, 15, 18}}
because #1 * #2 & defines a function of two arguments, and "Outer" feeds the lists into that function. You can even use ## to refer to all the arguments passed into that function (regardless of how many arguments there are), so

    Outer[## &, {1, 2, 3}, {4, 5, 6}]

    {{1, 4, 1, 5, 1, 6}, {2, 4, 2, 5, 2, 6}, {3, 4, 3, 5, 3, 6}}
And you can even do stuff like:

    f[x_] := x^2
    Outer[ #1[#2] &, {e, f, g}, {4, 5, 6}]
to get

    {{e[4], e[5], e[6]}, {16, 25, 36}, {g[4], g[5], g[6]}}

if you want a more general way to create anonymous functions in Perl 6, it's not that many more keystrokes away:

    sub ($a, $b) { $a + $b, [1, 2, 3], [4, 5, 6] }
Or even

    sub { $^a + $^b, [1, 2, 3], [4, 5, 6] }
So yes, the whatever-star isn't the most powerful thing imaginable, but it's good enough for very simple cases, and more powerful mechanism are available too.

But that's my point. Mathematica's # syntax is both. (i.e. it is good enough for very simple cases, and it is the more powerful mechanism.)

Scala had it before WL, with "_" which can be used with two or more arguments where necessary. I suspect other languages had it earlier than that.

It's a very useful shorthand, although it becomes less necessary with properly first class functions and/or currying by default. E.g. I don't know if Haskell has it at all, but it doesn't need it.


At the bottom of the page, it says:

>Introduced in 1988 (1.0)

So WL had this syntax several years before the JVM was even invented.

Hmm, I thought I remembered WL being announced a few years ago, long after I was using this stuff on the JVM.

Mathematica has had that syntax since the 1990's at least.

Plus there's good old q's implicit argument naming of x, y, z when you didn't give the args explicit names:

  each[{2*x}] 1 2 3

  1 2 3 {x*y}/: 4 5 6

To what extent is Perl 6 now stable? I was at a LISA conference in December 2011, and watched Tobias Oetiker present the wonders of Perl 6, and though I loved what I saw, something more than a tenth of his examples broke because of recent revisions, whether semantic or to implementation. God bless the language explorers, but my takeaway was "not yet". Is now the time?

I would say perl6 was stable as of the Christmas 2015 release of rakudo.

Been rock solid stable with respect to the language changing since the spec release over a year ago, especially if you specify that version in your program. I've been tinkering since 2010 and it was increasingly nuts how frequently things like list/string implementation and even syntax would change. So yeah its now a fully released stable language. The thing you might then wait for is performance. But it's getting better rapidly. The Text::CSV benchmark is probably the best to see perf getting there http://tux.nl/Talks/CSV6/speed4.html

    「Man is amazing, but he is not a masterpiece」
Is different than the other two, it can be thought of as short for

    Q 「Man is amazing, but he is not a masterpiece」
While the others are short for

    qq “Man is amazing, but he is not a masterpiece”
Which is short for

    Q :qq “Man is amazing, but he is not a masterpiece”
    Q :double “Man is amazing, but he is not a masterpiece”
Which is also short for

    Q :s :a :h :f :b :c “Man is amazing, but he is not a masterpiece”
    Q :scalar :array :hash :function :backslash :closure “Man is amazing, but he is not a masterpiece”
For more information see the [Quoting Constructs](https://docs.perl6.org/language/quoting) documentation.


There are modules for [debugging and tracing](https://github.com/jnthn/grammar-debugger) Grammars.

A regex is just a special kind of method by the way.

    say Regex.^mro;
    # ((Regex) (Method) (Routine) (Block) (Code) (Any) (Mu))
Which is part of the reason it doesn't have some of the niceties of parser generators built-in yet. The main reason is it got to a working state, then other features needed more designing at that point.


    # Perl 5
    /(Male|Female) (?:[Cc][Aa][Tt]|[Dd][Oo][Gg])/
    # is better written as
    /(Male|Female) (?i:cat|dog)/
In Perl 6 you can turn on and off sigspace mode

    /:s (:!s Male | Female ) [:!s:i cat | dog ]/
    # or fully spelled out
    /:sigspace (:!sigspace Male | Female ) [:!sigspace :ignorecase cat | dog ]/

    # or just use spaces more sparingly
    /:s ( Male| Female) [:i cat| dog]/
Note that in this case it is more like

    /( Male | Female ) \s+ [:i cat | dog ]/
In other contexts it could be slightly different. Basically it ignores insignificant whitespace.

Note that `( a || b )` is more like the Perl 5 behaviour, but `( a | b )` tries both in parallel with longest literal match.

Regular expressions are also the reason `:35minutes` is in the language by the way

    say 'a ab abc' ~~ m:3rd/ \S+ /;
    # 「abc」
Rather than make it a special syntax, it was generalized so it can be used everywhere.


The asterix in a Term position turns into a Whatever, when that is part of an expression it turns into a positional parameter of a WhateverCode.

    $deck.pick(*); # randomized deck of cards
    $deck.pick(Whatever.new); # ditto

    $dice.roll(*); # infinite list of random rolls of a die
    $dice.roll(Whatever.new); # ditto

    %a.sort( *.value ); # sort the Pairs by value (rather than key then value)
    %a.sort( -> $_ { .value } ); # ditto
Note that the last asterix was part of an expression, while the others weren't.

    my &shuffle = *.pick(*); # only the first * represents a parameter to the lambda
                             # the other is an argument to the pick method
The main reason I think for its addition to the language is for indexing in an array

    @a[ * - 1 ];
Rather than make it a special syntax exclusively for index operations, it was made a general lambda creation syntax.

I will agree that it takes some getting used to, but it is not intractable. WhateverCode lambdas should also only be used for very short code, as it can get difficult to understand in a hurry.


A `$_` inside of `{ }` creates a bare block lambda, basically this removes the specialness of Perl 5's `grep` and `map` keywords.

There is a similar feature of placeholder parameters `{ $^a <=> $^b }` to remove the specialness of Perl 5's `sort` keyword.

Another feature is pointy block, which removes the specialness of a `for` loop iterator value syntax.

    # Perl 5 (this is the only place where this is valid)
    for my $line (<>) { say $line }

    # Perl 6
    for lines() -> $line { say $line }

    # not special
    lines().map( -> $line { say $line } );

    # really not special
    if $a.method-call -> $result { say $result }

There is more to NativeCall that you haven't discovered yet.

For example, you can directly declare an external C function as a method in a class, and expose it with a different name. (if the first parameter is the instance)

Also it doesn't matter what you put in the code block for a NativeCall sub, as long as it parses. That is why it doesn't matter if you put a Whatever star (asterix) there or a stub-code ellipsis `...` in it. (you can also leave it empty)

    use NativeCall;
    sub double ( --> size_t ) is native() is symbol<fork> { say 'Hello World' }

    say double;
    say '$*PID == ',$*PID;
    # 1555
    # 0
    # $*PID == 1552
    # $*PID == 1555

Supplies can be pattern matched, just use `grep` on them as if they were a list. It in turn returns a Supply. You can also call `map`, `first`, `head`, and `tail` on them. Basically every List method is also on a Supply, along with special methods like `delayed`.


A lot about what you talked about with lists, and itemization is something that does take some time to get used to. It does get easier, but is always something you have to be cognizant of. Sort of like returning lists from subroutines are from Perl 5. It allows control over flattening that isn't available in Perl 5.

Are there any good examples of projects like this that drag on for an eternity and somehow, despite the odds, release, and also become extremely successful? It seems like after a certain point you have basically missed the boat on delivering value based on the assumptions you had when starting the project.

Do you consider Haskell to already be extremely successful? (Haskell planning began in 1987, the same year Perl 1 shipped.)

Lately, I've been seeing more pots on Perl. Is it just confirmation bias? or is Perl making a comeback?

Perl did show back up in the TIOBE rankings as #10 and then #9 (Perl5). There are plenty of blog posts and conferences...just not as much as Python, Java, C#...etc. Perl6 is starting to get checked out by the first wave of people who like to dive into new tech, so a bunch of blog posts have been showing up recently.

I think it's you, I've seen nearly nothing about perl anywhere for quite a while.

Perl6 is fascnating! And there arent a lot of 'woah' new languages about (Rust, Go, elixir, D, elm, nim, clojure, typescript, are all 'old hat' now...) so for people wanting to learn & play, perl(6) offers a lot of fun.

Hopefully it's making a comeback.

perl5 is certainly dying (but still strong on legacy). development stalled for 20 years.

perl6 is doing the worse-is-better approach, by focusing on all thinkable features (sans structural matching and proper destructuring), but with a performance making it unsuitable for production.

there are some perl11 projects (5+6): cperl and rperl which solve both problems. suitable for production, proper performance and proper features.

> Perl 6 has Perl’s regexes with a few changes: extending the Unicode support, moving the modifiers around, and reassigning some symbols, and also changing the whitespace rules to be more legible.

So… Perl 6… has Perl-incompatible regular expressions?? Amazing.

It also has all of the Perl 5 regex syntax too, so you can still use anything legacy or if you prefer to stick to something more portable. It's just the "default" regex is the new syntax. You can also put in any other "language" for them that you feel like, so POSIX maybe shell glob? I think at least POSIX probably exists in the ecosystem ;)

This line from the article best summarizes it for me:

Perl 6: The Ruby on Rails of command-line tools.

As a general comment, I would love to see more "reviews" of programming languages like this, even ones that are already in, use but maybe only in one niche, or should perhaps be more popular than they are.

I thought the same thing. In particular I would love to hear what the author has to say about the Nim programming language.

This reads like a literary review. I like the style a lot!

How's the toolset on Windows? Last time I checked, there were no out-of-the-box IDEs that supported debugging for Perl 6.

There are some great things in Atom for linted editing with doc integration https://github.com/azawawi/atom-perl6-editor-tools

If you want to get hold of the latest stable full release you can use chocolatey which is kept up to date https://chocolatey.org/packages/rakudostar or use a .msi installer from the official Rakudo site.

Thank you; I'll be sure to try it out.

Tooling is the main issue for me. I love reading about Perl6 but would be hard to break away from IDE like Pycharm or Visual Studio Pro/Ent.

Excellent, thanks.

It is not a review. It is an introduction or tutorial.

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