OTOH, Perl6 is effectively a new language. So knowing Perl5 is not that big an advantage.
I get that learning Perl is not a very attractive proposition these days, and Perl6 currently does not have the vast library/framework ecosystem Perl5 has.
But I think Perl6 is not just for Perl5 programmers. In fact, I think a lot of Perl5 people are going to stick with Perl5 for a while due to a) libraries/frameworks and b) existing code that needs to be maintained.
> actually not quite. given the plethora of libraries/frameworks etc. for perl-5, why would perl-5 programmers move to perl-6 ?
I'm a Perl 5 programmer. Perl 6 is a more perly Perl. I can use my Perl 5 modules if I really want, but I can write better specified, safer and more logical code. Just having simple functions like 'whenever' makes developing fun and easy.
My intuition is that current users of Perl 5 probably fall largely into two camps: using it because it looks like the best tool for the job or using it because it is the language of their soul.
People in the first group would switch if Perl6 looks like a better tool. Short of revelation the second group won't. Hardcore Perl programmers have had a long time to think about Perl 6 and come to their conclusions. It's not a community where evangelism is likely to make a difference these days. I don't think the Perl community is like the Python community for cultural reasons that stem from their histories.
I'm contributing toward language integration bindings, hoping to make it convenient and socially acceptable to call out to Perl 5, Python, Ruby, ... so that we will have (a subset of) CPAN, pypy, Rubygems, and so on. You can do this from any language really -- it is just binding to the c lib of the guest language.
It kinda makes me sad that the instinct for most of these things is to port a lib from language to language to language... when does it end?! I never want anyone to write pyplot again -- let's just call pyplot from ALL the languages thanks to the magic that is a little c library called libpython.
Depending on how you look at it, the advantage is either all of the Perl 5 ecosystem plus whatever Perl 6 brings to the table, or the lack of a disadvantage through not having a large module ecosystem, depending on how charitable you want to be.
Not to mention, you also have Inline::Python[1], and conceivably any other runtimes they want to embed. I think it would be interesting to see what you get by taking the best of class in each ecosystem and using them. It may or may not scale well due to data marshalling, but it's definitely something new (at least the ease of it is) and, IMO, worth looking into.
> Obviously most Perl users understand the benefits of Perl 6.
I've been using Perl since 1994, built a company around Perl 5 code and the attractiveness of Perl 6 for me so far is: 0. I know the price paid (later) for ease of writing (maintainability or lack thereof and lots of traps for the unwary - using Perl::Critic has a devastating effect on perceived "freedom" and simplicity) and a language crammed full of fancy features (the Perl 5 interpreter code base is widely considered unmaintainable these days). I honestly can't think of a single use case of Perl 6 with more than 10 lines or so where it'll work better than e.g. Go.
> the Perl 5 interpreter code base is widely considered unmaintainable these days
People love to say this, but having read a fair chunk of the sources to perl5, cpython, ruby, Tcl and erlang's VMs, my semi-educated conclusion is "reasonably fast interpreters written in portable C all end up as their own slightly bizarre CPP-supported C dialect, and all end up more similar than they are different".
> and all end up more similar than they are different".
It's not that simple. Tcl, Ruby and Python all have several competing implementations, while to my knowledge nobody has even written a complete Perl 5 parser (except the one in the official Perl 5 code).
While this is true, I was specifically addressing the comprehensibility of the core perl5 VM sources - so the existence of N other VMs seems orthogonal to me.
Or: I agree with everything you said apart from the implication that what you said is a counter argument to what I said - it seems to me that both can be true without conflict.
> Tcl, Ruby and Python all have several competing implementations, while to my knowledge nobody has even written a complete Perl 5 parser (except the one in the official Perl 5 code).
AFAIK, all the viable competing Ruby implementations use the parser from the mainline implementation; parsing Ruby is notoriously hard, and parsing isn't a weak point that alternative implementations usually try to improve.
I used to use perl, years ago, but moved across to Python for various reasons.
I've been reading about, playing with, and really enjoying perl6 since the christmas announcements.
The idea of a 'fun hackers language' really appeals. There's a lot of 'oh sweeeeeet!' moments. I still won't be using perl for any production projects / work stuff for a while, but as a fun out-of-hours playground, this really does look like a cool new language. I'm pretty excited by it.
- What's with the whole "language" and "compiler" distinctions no one cares about?
- Why is the first stable release of the compiler not optimized to the max?
- Is there a need for a new Perl? What is it good for?
- What is its business case?
- Why in the world would anyone use Perl 6?!
If I want to transform my 100.000 line program to a smaller one I won't grab Perl 6 to transform it to 50.000 but I will grab Clojure for example to transform it to an 5.000 one. Is that the only argument for using Perl 6?
Sorry for the sarcasm, but the author hasn't given a single reason beyond some trivial (and inconsequential, imo) syntactic shortcuts and his personal preference for the language.
> If I want to transform my 100.000 line program to a smaller one I won't grab Perl 6 to transform it to 50.000 but I will grab Clojure for example to transform it to an 5.000 one. Is that the only argument for using Perl 6?
What a weirdly arrogant and ignorant statement. If you're writing 20x as much code instead of using Clojure, then you're doing some pretty terrible programming.
I fail to believe that those 6 points could have been written by someone unbiased. Please show me some Clojure that's 10x more succinct than Perl 6. Otherwise then surely this counts as trolling.
It's funny since the claim I hear most waged against Perl is that... Perl is pretty concise, and at times a little too concise to the point of it being a write-only language.
Perl is pretty concise, but the list of criticisms above are almost meaningless. Who releases the first version of a language with most of the time spent on the optimiser?
Perl 6 loses quite a bit of the Write Only type syntax, and should be very succinct and expressive, but people just type nonsense :(
That language and compiler distinction is important. For instance, I generally approach developing in Clojure like developing in a dynamic language. I mean, if I want types then I can just use core.typed, right?
Things were going great until I used a validation library with HTML form input to check some numeric ranges. Boom: cannot convert java.lang.String to java.lang.Integer. Would the same thing happen in clojurescript? If it obeys js semantics then I won't get an exception, but "200" will become 200 and things will work as expected.
If you have a language defined by a test suite that exists separately from your compilers, then perhaps you can avoid these kinds of problems.
> - What's with the whole "language" and "compiler" distinctions no one cares about?
People care about distiguishing C89 and C99 from GCC and clang and their versions. If we don't want to block the road to future compilers for the same language (and we had other compilers in the past, they just aren't maintained anymore), we'd better be careful to distinguish them.
> - Why is the first stable release of the compiler not optimized to the max?
Because it's the first stable release, not the last. We expect to improve still.
I think Clojure is a great language. Using it requires taking dependencies on Java and the JVM or JavaScript and Closure. And those are what throw the exceptions and the context in which exceptions are described [Scala is similar]. That's the cost for the potential speed that comes from developing a new language as an embedded language versus from the ground up.
For Clojure's target audience of people who already know Java (or JavaScript) there's a lot of evidence that it was a good decision. Tools like Leiningen can use a familar tree structure and offer the potential benefit of configuration via code in comparison to other Java build tools. But the point of comparison is at a particular level of overhead and that level of overhead is assumed. With ClojureScript, the toolchain is more complicated than a typical JavaScript tool chain. Again that's a tradeoff.
Which again, I think Clojure is great. That doesn't mean I think that those tradeoffs are always appropriate. YMMV.
I'm a guy with a Camel tattoo who found Ruby and never went back to Perl, but have followed Perl 6 out of nostalgia. Here's the answers as I understand them:
- Version 6.c? Why not 6.0?
This is first, a reflection of the playfulness of Perl, and second, a statement about language design. The first release, an alpha, was 6.a. The second, a beta, was 6.b. The third, the actual 'final' release, was 6....c? Since it was being released on Christmas, and 'c' fits, it was decided that releases of Perl 6 would be named after holidays, and they went back and found them for A and B too.
As for the statement about language design, I'll add that onto the next one, as it makes more sense in that context.
- What's with the whole "language" and "compiler" distinctions no one cares about?
"Perl 6" is a _language_, not an _implementation_. There's a language spec, and any implementation of this spec is a Perl 6. This is a distinction that a lot of projects make, but is a lot fuzzier, because they don't have specs. Consider Ruby: yes, JRuby is also a Ruby, but since there's no language spec, people still assume MRI when you say "Ruby". Perl people don't want you to assume Rakudo when discussing the language itself.
This is why there's no minor version of "Perl 6". Language specifications change a lot less frequently than compilers.
- Why is the first stable release of the compiler not optimized to the max?
Like most projects, as long as performance is Good Enough, it's good to get people start using it, and then work on performance after. Especially for a language where performance isn't a main goal, like Perl. As long as you haven't painted yourself into a corner with language decisions, performance improvement is refinement work.
- Is there a need for a new Perl? What is it good for?
I don't know if there's a _need_, but Perl 6 sure improves on a ton of things about Perl 5. It's the stuff that makes Perl Perl, but turned up to 22, not just 11.
> This is first, a reflection of the playfulness of Perl, and second, a statement about language design. The first release, an alpha, was 6.a. The second, a beta, was 6.b. The third, the actual 'final' release, was 6....c? Since it was being released on Christmas, and 'c' fits, it was decided that releases of Perl 6 would be named after holidays, and they went back and found them for A and B too.
This sounds absolutely retarded.
Back when Perl 5 this kind of hacker clown routine was popular, but now I think most people prefer a bit more simplicity and clarity.
That both indicates to me why Perl 6 is cool, and also why it's a bit mad. Junctions, in the core language? Really? Wouldn't they be best placed just being a library?
Yes! "Cool and also a bit mad" is a great description of Perl 6 (and maybe a few other awesome languages. At least until people get used to them... I guess we're all a bit mad!)
Ah, but when it's part of the core, that enables some other cool features (such as automatic spooling of operations to multiple CPUs for where applicable), and well thought out and stable interaction with other core features.
Junctions are insanely useful once you get used to them and I use them frequently. Basically, any time you have a list and you're worried the properties of any, all, or none of the list members (hmm, just about all lists), then junctions are often a very clean way of expressing the issue.
if all(@ages) >= 18 {
# let 'em in the club
}
Or:
if any(@ages) < 18 {
# don't let 'em in the club
}
Or:
if none(@ages) < 18 {
# don't let 'em in the club
}
So I use logic like the above quite a bit, however, there are plenty of areas where the above can be better if it's deeply integrated into the language. In this case, as already mentioned, it's auto-threading where appropriate. That's not an easy feature to get right if it's not baked into the language, but it's a huge win if done right.
Perl 6 also has gradual typing baked in. Other languages have gradual typing as a library, but that often fails dramatically (http://blog.circleci.com/why-were-no-longer-using-core-typed...). In Perl 6, because it's built-in, not only are the failures described something Perl 6 can avoid, but there are also plenty of type checks Perl 6 can avoid at run time with integrated gradual typing (imagine that benefit in hot loops).
You could even combine that with native junction auto-threading and presumably have super-fast comparisons where the needs for checking types is eliminated at run time because it's already been done at compile time. If you do that with libraries, it's awfully tricky to get right, if not impossible.
It's not standard sets, it's a bit more than that, Perl 6 has sets of course, but Junctions should be able to autothread and express a sort of superposition of values.
It's not so much SIMD. Perl 6 has a number of different constructs in which multiple operations can be carried out like that. However, yes the intention is to enable a large number of these scenarios to be carried out on multiple CPUs.
I don't think Rakudo implements that yet, but there's quite a lot to improve first.
The | junctions seem a lot like sets to me, though I guess there is a lot of fancy you can use. One that comes to mind is that you can pretend that it is a single value, even if it is a complex junction of & and | things:
Kinda weird, especially & junctions. The docs[1] say "Junctions are meant to be used as matchers in boolean context; introspection of junctions is not supported. If you feel the urge to introspect a junction, use a Set or a related type instead."
So far in my Perl 6 exploration I don't think I've used/needed junctions -- strikes me as a specific sort of use-case, but maybe familiarity would help me spot more (useful) opportunities.
For example "if ($x == 2 || $x == 4 || $x == 5 || $x == "hello"
|| $x == 42 || $x == 3.14)" can be done in Perl6 as "if ($x == (2|4|5|"hello"|42|3.14))" but in Ruby this would equally easy been done with "if [2,4,5,"hello",42,3.14].include?(x)".
Ruby also has set operations defined on its container classes (e.g. [1,2,3]&[2,3,4] => [2,3]) and any?, all?, none? methods that take blocks.
Perl6 looks like a language that might have been great if it had been released in the 90s but nowadays I wonder if it will gain enough traction from non perl programmers.
>> but in Ruby this would equally easy been done with "if [2,4,5,"hello",42,3.14].include?(x)".
> But that isn't the same is it. That's only a related feature because Ruby doesn't have first class Junctions.
At least in this case, the only difference I see is that this is a language feature in Perl6 and a method from the standard lib in Ruby.
And it has to be a language feature in Perl 6 as there you don't have open classes as in Ruby or an equivalent feature for overriding operators or adding functionality to standard lib types.
> And it has to be a language feature in Perl 6 as there you don't have open classes as in Ruby or an equivalent feature for overriding operators or adding functionality to standard lib types.
I'm not sure what makes you think this. I'm not very familiar with Ruby's internals but Perl 6's MOP certainly supports modifying classes, you can add your own operators etc.
a includes b is trivial in any language and is not a justification for Junctions.
Please take another open minded look at the examples others have posted here. Post again if you still don't see what they do that's useful and not trivially doable in any language and I'll have a go at explaining them to you.
Of course the include operation on a set is a trivial operation but that's been the first example for junction I found when googling.
It's not a problem with an open mind but rather with understanding what data type a junction is trying to be.
If I go to the official specification (my fault, should have gone there from the beginning), I read the definition "A junction is a superposition of data values pretending to be a single data value". But that's a fuzzy definition and it is absolutely not clear what that's supposed to mean. The given examples don't help either.
Especially when I look at this discussion and see that several people including you are not sure what "all(@ar1) < any(@ar2)" is supposed to mean. That's not a complicated expression and that's already puzzling to people who know the language?
The autothreading feature is cool but also nothing too special. Every pure functional language can implement map/reduce/filter in parallel.
tl;dr I don't see what junctions bring to the table that's not expressed easier to understand with set operations or map/reduce/filter.
> what "all(@ar1) < any(@ar2)" is supposed to mean. That's not a complicated expression and that's already puzzling to people who know the language?
Afaik junctions are simple and have an obvious intuitive read. But I'm not yet 100% confident of expressing that view without qualification. Given Estragon's "no idea" comment I allowed that my intuitive read might be bogus.
In fact the intuitive read is correct:
if all(ar1) < any(ar2)
# if all in ar1 are numerically less than any in ar2
> The autothreading feature is cool
To be clear, the whole point of junctions is autothreading; passing junctions to any code that does not have an overload for junctional arguments is automatically (semantically, at least) data parallelized and that's the win that makes them significant.
> Every pure functional language can implement map/reduce/filter in parallel.
I note "can implement" and your choice of just three functions.
Which languages provide a mechanism equivalent to junctions and their most significant use-case -- automatically generating data parallelized versions of any sequential functionally pure code?
> I don't see what junctions bring to the table that's not expressed easier to understand with set operations or map/reduce/filter.
What equivalent of "all(ar1) < any(ar2)" -- all ar1 less than any ar2 -- is "expressed easier to understand"?
I think a good idea would be to look through Ruby Enumerable (which is most excellent!) and see how things correspond to P6, or where they are missing. Like in this case you can do:
[2,3,5,"hello",42,3.14].any ~~ $x
But that's not really the same, since it converts the entire array to a junction and then does the match. Really this is a lot closer:
[2,3,5,"hello",42,3.14].first($x):p
Which returns the first match (as a pair (hence the :p adverb) so it won't be false even if it is a false value)... but it isn't right either because it gets mad at comparing numbers and strings (I'm asking about this in #perl6 now on irc).
Ultimately: it would be trivial to port ALL Enumerable methods to Perl 6 List (or some role to cover all iterables or such), and do it in a library even if it wasn't in the core standard lib.
I'm always fascinated by how much of Ruby (and lots of other languages) are more about their Standard Lib than about their language. In the Ruby world, lots of people end up with ActiveSupport, which sprinkles in all sorts of cool stuff into the standard lib -- and I've ever seen a native 'for' loop rather than a .each in pragmatic Ruby.
I'm not sure this is how you're supposed to use junctions. I vaguely recall that the semantics is not obvious when you put a junction on both sides of a relational operator. It's much clearer when there is a junction on only one side.
More typical uses are:
die "unauthorized value" if $_ == 1|2;
grep none(1, 2), @values;
say "$a and $b are even" if ($a & $b) %% 2;
Basically : junctions are not sets. Don't try to use them for set operations. Perl 6 has a Set structure. Use that instead.
The first two seem to be set operations ("value in set" and "filter values not in set"), I've no idea what the third one is supposed to do, something like all ((==0).(`rem` 2))?
By set operations I was more specifically thinking of intersection and union. Testing if an element belongs to a set can indeed be done with junctions but that's pretty much it.
The third example shows the so-called auto-threading behavior. I think it's significantly different than what you can do with sets.
A Junction in Perl 6 is "a superposition of data values pretending to be a single value". So for instance any algebraic expression can be used with a junction as if it was a scalar. The result will be a junction.
In this example the expression is $_ %% 2, which is Perl 6's way of writing the boolean statement "the variable $_ is divisible by 2". We use this expression with ($a & $b) instead of $_.
So this is where I saw this. I distinctly remember seeing this feature in Perl many years ago, but then when I tried to find it I really, really couldn't, so I assumed it was something I had dreamt up.
However ridiculous it sounds, a weight is lifted from my chest.
So basically == is overloaded to also be an operator which means "intersects".
I mean, it's nice that this sort of functionality has nice and concise operators, but I'm coming from a school of thought where overloading the equality operator should not be done lightly :)
> So basically == is overloaded to also be an operator which means "intersects".
Junctions seem way more complex than that, first there are 4 different junction contains (any, all, one and none), second they overload 12 comparison operators each and third the other operand doesn't have to be a junction.
So e.g. any(@ar1) == any(@ar2) is an intersection but any(@ar1) == $val is a containment, and I've no idea what all(@ar1) < any(@ar2) would be, I guess it would check that max(ar1) < max(ar2)?
One that I recall that I'm hoping still applies is having a syntactically and conceptually lightweight way to express semantically parallel computation logic. Given the code:
junction1 = val1 | val2 | val3;
junction2 = val4 & val5;
if junction1 op junction2 { ... };
the compiler is free to fire off several threads, or set up a lower level SIMD parallel process, with short-circuiting, to compute the conditional result.
* $string ~~ /<first>/ & /<second>/ & /<third>/ # matches all three regexes. huh. kinda cool
* (5|6).foo maybe we can do that in cpu-parallel (it doesn't now)? That might be kinda cool
* sub is-prime($n where $n > 2) { $n % none(2..sqrt($n)) == 0 } # Logical O(1) prime test if only you had that quantum-coprocessor? That... would be kinda cool
* ... you might notice a pattern to the motivation for this feature :)
I'm very much not sure of the following but I'm going to say it anyway and let folk explain how I'm wrong. :)
Each operator and its overloads -- certainly built ins, users are recommended to follow suit -- conceptually maintains its own single high level semantics. Thus, while some langs have a `+` op that does numeric addition or string concat based on operand types, in Perl 6 a `+` will always mean numeric addition (unless a user breaks this convention).
`==` is always numeric value equality.
`==` does what most folk would expect between any pair of values that are a subclass of Any (the root of the type hierarchy for most purposes).
Junction is a direct subclass of Mu (the ultimate root of the type hierarchy), outside the Any hierarchy.
When a scalar operation is applied to one or more Junction values, the relevant operation is "autothreaded" over the superposed values inside the Junctions and returns a new Junction value.
If a Junction is treated as a boolean the Junction collapses to a regular single boolean value.
If operator overloading in perl6 was like operator overloading in most languages, that would be a very valid school of thought.
Thing is, operators in perl6 are basically multimethods under the hood, as is pretty much everything else - so it's a much saner, more predictable thing than, say, the bag of razorblades that is perl5 overloading (which I've used to good effect, but, still, razorblades ;).
If I want speed on massive concurrent cores I would choose pony. If I want safety, I would choose pony. If I want to keep my old libs and scripts I would choose cperl. But perl6 is a nice language still, a dinosaur like Common LISP.
Except that huge corporations use both Perl and Common Lisp on a daily basis. Craigslist, Google, etc.
So you have some old perl scripts laying around, but they work well enough and some guy takes care of them, updating them when they need. He knows perl and that's his job, so whatever. One day, the architecture changes and the scripts need to go parallel. That's a problem because the perl guy doesn't know Pony (a promising language with a community even smaller than perl6...) and really needs to get these scripts running again.
So he uses Perl6 along with the inline module, and things are working again. Over time, he hacks up a better system in vanilla Perl6, and deploys that too. He had such a great time using Perl6 that he even hacks up a few more tools he could use, etc etc, next thing you know he's a Perl6 developer.
I write ruby because it is modeled similarly to how I think about problems, but if I was a perl guy, I could see the appeal to Perl6, but saying that it's a dinosaur is both wrong and irrelevant to the FUD surrounding Perl6 right now. At this point, it's about adoption.
The universe of people writing Perl 6 code at the moment is very small. Responding to every critique of the language with "hey, it works for ME!" is a great way to ensure it never gets any bigger.
Sigils in Perl 6 are rough type constraints on their content. More specifically, the indicate a Role. $x is unconstrained, @x does the Positional role, %x does the Associative role, &x does Callable.
Twigils in Perl 6 are where the scope indicators come in, clarifying class instance vars, dynamic scope, and so on.
So if I see %.foo I can tell you that this variable can be used as the Associative role, that it is scoped as an instance variable, and that it has an accessor with the same name.
Because sigils tell you things. What if 'x' in your example is a list? Are you now checking the length of the list rather than the value? Sounds like room for a security bug to me.
> Because sigils tell you things. What if 'x' in your example is a list? Are you now checking the length of the list rather than the value? Sounds like room for a security bug to me.
Only if your language is really awful. A good language shouldn't even let you run "5 < x" when x is a list, but even a mediocre one would surely at least make that error out at runtime rather than giving a nonsense answer.
> Only if your language is really awful. A good language shouldn't even let you run "5 < x" when x is a list, but even a mediocre one would surely at least make that error out at runtime rather than giving a nonsense answer.
It depends what you consider "Nonsense". Python for example has no reliable way to differentiate between a string and a list. Strings are iterable, but lists can't be compared with the < syntax for example.
My point is simply that $x very clearly says (in Perl 6) "A single value called x" wheras @x is "A list of values called x". In python, "x" is indeterminate even at runtime.
Oh, and you can declare barewords with \x for example, if you really want to, it is Perl after all.
What version of Python can't differentiate between a string and a list, or compare lists?
Python 2.7.10 (default, Jun 10 2015, 19:42:47)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> type([1])
<type 'list'>
>>> type('1')
<type 'str'>
>>> type(1) == type('1')
False
>>> [1] < [2]
True
>>> [2] < [1]
False
>>>
I consider it "Nonsense" to abuse overloaded context sensitive strings of punctuation with arbitrary rules of precedence and associativity, instead of English words correctly spelled out of letters that people can look up alphabetically in a reference manual and google for tutorials to find out what they mean.
Sorry I should have made things more clear. I am talking about in things like function signatures.
Doing something like isinstance(x, str) is discouraged and considered non-pythonic, and recently hasattr() has also been talked about. However, both strings and lists can be iterated, so assuming that this will fail is incorrect:
x = "Hello"
for y in x:
print("{} is {}".format(y, type(y)))
I asked on IRC and ultimately the only answer I got was that the most pythonic way to do things was to name functions whatever_str and whatever_list.
edit: I also should have said above "lists can't be compared with strings using <". I was trying to point out Python did things potentially correctly there, but I see now it's ambiguous.
If it's so important to decorate variables with unique punctuation to visually distinguish between two particular kinds of many possible types, then why don't you also decorate function calls according to whether they return lists or scalars?
How should you decorate functions that return different types depending on what context they're used in? http://perlmaven.com/wantarray
If it's so important to visually distinguish the names of scalars and arrays, then shouldn't you also be able to distinguish a string from an int, like BASIC's a$ -vs- i%?
So why just distinguish lists and scalars? Why not go all the way to Hungarian Punctuation and use Unicode and Emoji characters to uniquely decorate variables for every other possible built-in and user defined type?
https://en.wikipedia.org/wiki/Hungarian_notation#Relation_to...
You might be a little confused, I'm pretty sure that wantarray and the concept of functions caring about context is entirely gone in Perl 6. Now you are expected to return objects which 'do the right thing'.
However, if you really want to do some of the other things you've listed they are possible to do. Perl 6's syntax can be augmented by the programs being executed.
I'm honestly interested though, was I ultimately wrong above? Is there a smart way to define a function in python that can take both a single item and a list of items? In Perl 6 I'd just define a multi sub where the list form applies the single item sub for each item in the list.
It might be gone from Perl 6, but the idea of dividing all possible types into two different classes, and then using punctuation to distinguish variables holding those two classes, is from Perl 5, just like the idea of functions caring about the context of their return value.
If Perl 6 is an entirely new language, then why is it riddled with so many bad ideas from another language that only coincidentally shares the first 4 alphabetic characters of its name?
Why the artificial scalar/array dichotomy? What is it that is so important about being able to distinguish variables holding scalar-like values and array-like values by punctuation, but it doesn't matter that you can't distinguish variables holding strings and integers by their punctuation?
And how can you be consistent about types that act like both scalars and arrays, like strings? Or user defined types that might behave like scalars or arrays but are represented by objects? Are those treated as arrays? Or are they references, treated as scalars?
Scalar -vs- array is a false dichotomy that's deeply and unnecessarily embedded in the very syntax of the language.
I'm not entirely sure you've illustrated that it's a bad idea. I believe that I illustrated that a simple pattern is not easily doable in Python but is in Perl 6. You'll have to show that this is a bad pattern or the implementation is bad or something at least to prove your point.
The difference in your examples are that scalars describe more the 'shape' of the variable than its type. Given that a lot of programming is dealing with lists or 'dictionaries' this is a fairly minimal intrusion into the code that very much improves succinctness, correctness and the ability to easily read what some code is doing.
Oh, and strings don't act like arrays in Perl 6 AFAIK. Because they could be split on characters, or codepoints, or bytes, you must be explicit:
> for "Hello".comb -> $c { say "Character $c" }
Character H
Character e
Character l
Character l
Character o
What's wrong with using "isinstance(lst, str)" when necessary?
The few cases when you need to make that distinction aren't worth infecting the rest of the code with punctuation marks. Using letters to explicitly spell out self-documenting words in the few function names that need to make that distinction is much less intrusive, more flexible, unambiguous and capable of precisely distinguishing many more nuances, than using a small set of punctuation characters throughout all of your code to mitigate rare problems with just a few cases.
Of course it can be taken to an extreme, but it's much easier to guess or google for the meaning of an Objective C selector than for a bunch of Perl punctuation.
> What's wrong with using "isinstance(lst, str)" when necessary?
In order for it to be like the Perl6 implementation I would have to check against every type of iterable AFAIK. For example, a generator would be perfectly acceptable, but is there a unique function I could check with hasattr?
Clearly you feel that sigils are intrusive in Perl 6, but having written a bunch I find it quite enjoyable, and they're pretty easy to find in the documentation too. Ultimately, you can use variables without sigils, but with caveats: http://doc.perl6.org/language/variables#Sigilless_variables
> In order for it to be like the Perl6 implementation I would have to check against every type of iterable AFAIK. For example, a generator would be perfectly acceptable, but is there a unique function I could check with hasattr?
Define what it is you want - which function you want to use - and then check that (e.g. if you want to iterate over it check for __iter__; if you want to want to test membership check for __contains__). In one part of the code a generator might be acceptable; in another it might not. Which is the point really - array vs scalar seems like a simple, sensible, widely usable distinction on first glance, but it turns out the meaning you actually want is very context-dependent, and a global distinction is a lot less useful than it appears.
If I check __iter__ I consume strings too which is what I'm trying to avoid. Both of you have taken the perspective that this distinction is irrelevant but neither of you have a good answer to this case:
> multi sub hi($a) { say "Hello there $a" }
> multi sub hi(@a) { hi($_) for @a }
> hi("lmm")
Hello there lmm
> hi(<lmm DonHopkins>)
Hello there lmm
Hello there DonHopkins
From a Python perspective, it looks to me like you're trying to take one particular style of programming (overloading functions) to an extreme (or at least fetishizing it), when it doesn't buy you anything particularly worthwhile, even though is comes at a high cost in terms of cognitive load (and runtime reflection in dynamic languages like Perl, Python or JavaScript).
Why should you have to write a special function that knows about looping, when the language already provides several perfectly fine ways to loop?
jQuery loves to do that kind of stuff too, slowly sniffing and savoring the arity of its arguments and reflecting on their types at runtime, then doing totally different things like getting, setting, configuring, instantiating, sending messages, and iterating, depending on the number and type of parameters, possibly selecting multiple items even if you only want one, etc...
Personally I don't think that style makes code any easier to read or write or guess what it will do, and it sure is a source of a lot of implicit behavior and inexplicable errors.
Having one function named "x" that gets x, sets x, iterates over the x dimension, searches for x, or creates x widgets depending on how it's called doesn't make my life any easier.
I'm willing to read and type a few more letters to use a set of longer self documenting function names. Using explicit descriptive consistent names, instead of heavily overloading short names and sigils, also makes the documentation easier to search and the IDE easier to use.
Explicit is better than implicit or inexplicit.
What is so important about the scalar/array dichotomy (which I think is fuzzy, arbitrary and artificial), that they get their own sigils to disginguish them, but you don't also use different sigils to distinguish ints from floats, numbers from strings, arrays from dictionaries, objects from classes, locals from globals, objects from proxies, inputs from outputs from references, etc?
The root of the sigil problem is that you quickly run out of unused ASCII punctuation characters to decorate all the concepts you feel the need to distinguish. Of course you could limit identifiers to a single character and require the use of Unicode, like Bjarne Stroustrup suggested in "Generalizing Overloading for C++2000" [1], but isn't it simpler and easier to just use letters that spell out what you mean as words, instead of context sensitive punctuation you have to look up in a legend?
I like the way C# uses "in", "out" and "ref" instead of punctuation or emojis.
> (overloading functions) ... comes at a high cost in terms of ... runtime reflection in dynamic languages like Perl, Python or JavaScript
In Perl 6 function overloading is generally resolved at compile-time.
> Explicit is better than implicit or inexplicit.
Explicit what?
(jk)
> What is so important about the scalar/array dichotomy
See my earlier reply to another of your comments.
> context sensitive punctuation you have to look up in a legend?
Sigils are not context sensitive.
> The root of the sigil problem is that you quickly run out of unused ASCII punctuation characters to decorate all the concepts you feel the need to distinguish.
The distinction corresponds to major distinctions known to be wired in to human brains: single vs plural, and number vs name.
If this seems arbitrary to you perhaps you lack self awareness?
> The distinction corresponds to major distinctions known to be wired in to human brains: single vs plural, and number vs name.
I think we get away with those in natural languages because humans are willing to be fuzzy about that. E.g. whether an organization is singular or plural differs based on context and dialect. Whereas the only distinctions it makes sense to use in programming languages are those that we can make precise.
> I think we get away with [distinguishing singular/plural and number/name] in natural languages because we are willing to be fuzzy about that ... Whereas the only distinctions it makes sense to use in programming languages are those that we can make precise.
I see no conflict between a mental process being a fuzzy "natural language" thing in our brains and the code modelling that concept using a precise formulation.
Indeed, to the degree I'm wrong we're in trouble. To read and write code we have to use what we've got -- our brains -- and we have to work with them the way they insist on working:
"Janet Siegmund and her colleagues observed 17 participants inside an fMRI scanner while they were comprehending short source-code snippets
...
The programmers in the study recruited parts of the brain typically associated with language processing and verbal oriented processing (ventral lateral prefrontal cortex)
...
Interestingly, even though there was code that involve mathematical operations, conditionals, and loop iteration, for these particular tasks, programming had less in common with mathematics and more in common with language. Mathematical calculations typically take place in the intraparietal sulcus, mathematical reasoning in the right frontal pole, and logical reasoning in the left frontal pole. These areas were not strongly activated in comprehending source code."
If we process code as if it were natural language, then that argues for having our programming languages emulate natural languages. Even in matters of precision such as legal contracts, we don't always conform exactly to the "rules" of grammar - indeed I'd say that legal language violates those rules even more than natural language does.
To my mind that suggests an ideal programming language would not "hardwire" rules of grammar, that sigils should be more like flexible hints to the reader than things that have rigid language-level meanings.
Apologies if I'm harping on about this too much but I would like to object to "If" as being too ambiguous in this context.
The most active non-memory/attention brain circuits used in comprehending the code samples in the study I referenced were consistently for natural language processing, not math/logic processing, for all 17 of the 17 participants in the study.
It's a small test but a pretty emphatic one nonetheless. For at least some folk (and it's at least plausibly most/all folk) for at least some code (and it's at least plausibly most/all code), it's "WHEN we comprehend code we use natural language circuits and so...", not "IF...".
> that argues for having our programming languages emulate natural languages.
Well, careful. Natural languages are fuzzy! We want programming languages that do TWO things -- leverage our natural processing capacities to the degree they're relevant AND render their fuzziness relatively harmless at the same time.
> Even in matters of precision such as legal contracts, we don't always conform exactly to the "rules" of grammar - indeed I'd say that legal language violates those rules even more than natural language does.
Yes. This is a very important point. Think in terms of thousands of DSLs. How does one enable that? How does one cope with that?
> To my mind that suggests an ideal programming language would not "hardwire" rules of grammar
Right. The Perl 6 project not only addresses this but is a full frontal assault on it. It's one of the various reasons it took 15 years to get to 6.c.
There's a standard Perl 6 grammar but Perl 6 Rules can relatively easily specify any grammar. And I mean any grammar, whether Chomsky hierarchy level 1 (regular languages -- where regexes originally came from) or level 2 (context-free -- where parser combinators have traditionally shone) or level 3 (context-sensitive -- various parser combinators extensions have recently started to nibble at this) or the final level 4 (recursively enumerable languages).
Aiui Perl 6 can reasonably be viewed as the world's first practical "universal unrestricted grammar" capable of accepting any other language.[1]
> sigils should be more like flexible hints to the reader than things that have rigid language-level meanings.
Sure.
For starters, sigils are just a part of standard Perl 6. You can write any language in Perl 6. So, for example, the ipso language is a sigil free lang (it's a lisp) in Perl 6[2] and Slang::SQL is for embedded SQL.[3]
If we stick to standard Perl 6, sigils just mean a few very general things, as follows.
First, that the associated term is primarily a "noun". This determines where it does and doesn't fit in the grammar.
Then particular sigils -- the main ones are $, @ and % -- establish some other properties of a given noun.
$ emphasizes the noun's singular nature rather than any potential plural nature it might also have.
@ emphasizes the noun's plural nature and having an integer index (the array `my @bananas[15]` corresponds to a bunch of 15 bananas indexed by 0 thru 14).
And finally % emphasizes plural nature and having an associative index (%colors<red> corresponds to the 'red' key'd value in the %colors dictionary).
You might argue that those are rigid. I'd counter that they correspond to human's natural processing circuits. But regardless, if you don't like them or want to repurpose them you can just create a slang or another lang that tweaks or entirely changes the grammar to suit your needs...
That sounds like a really perverse use case to me. Why would you want one function to have two completely different behaviours depending on what it was called with? If you want two different behaviours, write two different functions.
I resisted replying to Don as I didn't think he presented any actual argument. The "Write two functions" crew haven't thought this through though.
Ultimately, the scenario I came across this in was an atomic transaction decorated function. The data being provided to this function flows through a good 3 or 4 functions beforehand. I also require _single, _list and _listoflists behaviour. This would bloat a 4 function stack into something like 20 different functions. There are also issues with transaction decorators.
It just seems crazy to me that Python can't manage this (to me trivial) use case.
> I also require _single, _list and _listoflists behaviour.
So it sounds like your needs don't align exactly with perl's sigils anyway (and why should they? For different business requirements you'd categorize differently).
> This would bloat a 4 function stack into something like 20 different functions.
Not with good language/design. Separate your concerns. Let the difference in behaviour live somewhere more appropriate - either on an object that contains the data (OO style) or in a callback you pass into the function (functional style).
> There are also issues with transaction decorators.
Decorators have problems yes, that's why I prefer to have a type system handle that kind of thing.
> So it sounds like your needs don't align exactly with perl's sigils anyway (and why should they? For different business requirements you'd categorize differently).
Indeed but I can write constraints in my function signature to permit this. Hell I can even define something as SpecialList[SpecialKey] if I truly wanted. Perl has a type system.
> Not with good language/design. Separate your concerns. Let the difference in behaviour live somewhere more appropriate - either on an object that contains the data (OO style) or in a callback you pass into the function (functional style).
Doing this in Python is an exercise in horror, frustration and hatred. Doing it in Perl is the work of a few seconds. That is my point.
> Indeed but I can write constraints in my function signature to permit this. Hell I can even define something as SpecialList[SpecialKey] if I truly wanted. Perl has a type system.
Interesting. Is this a new thing?
> Doing this in Python is an exercise in horror, frustration and hatred. Doing it in Perl is the work of a few seconds. That is my point.
Then what's the perl example without using sigils? Does that not translate directly into python?
What is the single "thing" you're referring to and what is "new" relative to?
I interpret hahainternet's comment to refer to at least three new things in Perl 6 relative to Perl 5: Perl 6 has a carefully developed type system, roles support parametric polymorphism, and both static and dynamic type constraints on parameters are supported.
-----
You earlier wrote "If you want two different behaviours, write two different functions". But hahainternet had written two different functions. This suggests you hadn't then yet taken on board what multidispatch is (a fundamental innovation -- from the 80s iirc -- related to declaring and calling functions).
Then you responded to hahainternet's "This would bloat a 4 function stack into something like 20 different functions." with "Let the difference in behaviour live somewhere more appropriate ... on an object that contains the data (OO style) ..." without realizing that that's less appropriate, not more:
"In the presence of multiple dispatch, the traditional idea of methods as being defined in classes and contained in objects becomes less appealing" (from https://en.wikipedia.org/wiki/Multiple_dispatch).
> What is the single "thing" you're referring to and what is "new" relative to?
The type system and perl 5. That would have been a much more constructive response to "why perl 6?" (if it's as good as you say) than this article.
> You earlier wrote "If you want two different behaviours, write two different functions". But hahainternet had written two different functions. This suggests you hadn't then yet taken on board what multidispatch is (a fundamental innovation -- from the 80s iirc -- related to declaring and calling functions).
No need to be rude. Rather than argue over whether the cases of a multimethod are different functions or the same function, let me just clarify that if you want two different behaviours then it is clearer to give them different names.
> "In the presence of multiple dispatch, the traditional idea of methods as being defined in classes and contained in objects becomes less appealing" (from https://en.wikipedia.org/wiki/Multiple_dispatch).
That article is decidedly non-neutral. I'm well aware of multiple dispatch. I find it very bad for code maintainability, and often a sign of poor domain modeling. The interaction between two objects is an unnatural and opaque place for behaviour to live; usually the behaviour belongs to one or the other or on its own, or if their relationship is that complex it should probably be promoted to a first-class entity.
>> What is the single "thing" you're referring to and what is "new" relative to?
> The type system and perl 5.
Gotchya. Perl 6 is not a Perl 5 update. There are reasons it shares the name Perl, which usually become obvious if you know both langs, but for non-users it's best to think of Perl 6 as a completely new language.
> That would have been a much more constructive response to "why perl 6?"
I think the OP article was a mostly good humored response to the reality that a lot of responses to Perl 6 are absurd. Like individuals sincerely asserting that it should not be taken seriously by anyone for any commercial purpose -- because of perceived problems with the logo chosen by the language design team!
> (if it's as good as you say)
Uhoh. Did I say Perl 6 is good? I think, right now, it's a lot of fun if you're in to all sorts of PLs. But let me restore balance in the force. The language isn't equational and its type system isn't Hindley Milner. Compiled code is very slow and consumes a lot of RAM and fully fixing that is going to take many years worth of engineering. The doc needs tons more work. There are only a handful of modules. It's a new and unproven language. Balance restored?
> No need to be rude.
My apologies. I didn't mean to be rude.
(I looked over your other responses in this thread prior to posting my comment and none suggested to me that you were claiming familiarity with multidispatch and several suggested to me that you did not really have a feel for how they work out when properly used in Perl 6.)
> Rather than argue over whether the cases of a multimethod are different functions or the same function, let me just clarify that if you want two different behaviours then it is clearer to give them different names.
Gotchya.
Nit: multidispatch in Perl 6 works for any function and (almost) any operator (operators are actually just functions), not just methods.
The Perl 6 view is that multi functions/ops/methods have both a "short" name and a "long" name. The short name is the bit that goes before the parameters. The long name includes the signature. It's a different perspective on naming and I find it works well for me.
> I find it very bad for code maintainability, and often a sign of poor domain modeling. The interaction between two objects is an unnatural and opaque place for behaviour to live; usually the behaviour belongs to one or the other or on its own, or if their relationship is that complex it should probably be promoted to a first-class entity.
I hear you've encountered use of multiple dispatch that you don't like, and that it's often signaled poor design, and that you think that the code placement for a multimethod is fundamentally unnatural.
But I don't hear that you've encountered multiple dispatch for functions and/or operators rather than methods; or that you've seen the scenarios in which it is a good fit for coding (I presume you don't think there's literally no sweetspot use-case); or that you've had a chance to work with a language like Perl 6 in which multimethod placement is as you suggest. So it sounds like you have only encountered limited and perhaps poorly designed and/or used multiple dispatch and that's colored your perspective.
Anyhoo, thanks for the exchange, and I hope you get another chance to use Perl 6 for something it's good at and see that, whatever else may be true, it is a lot of fun. :)
There is no such division of types in Perl 6 in the normal CS sense of the word "types".
There are several kinds (in the English sense, not CS sense) of data containers. Elements of these containers can be of any type (CS meaning).
> just like the idea of functions caring about the context of their return value.
As the GP just said, Perl 6 dropped that.
> Why the artificial scalar/array dichotomy?
The distinction between singular and plural is natural, wired in to our brains, not artificial.
> What is it that is so important about being able to distinguish variables holding scalar-like values and array-like values by punctuation, but it doesn't matter that you can't distinguish variables holding strings and integers by their punctuation?
As explained above, it's not about the values but the containers. Strings and integers are data. Containers are not data.
> And how can you be consistent about types that act like both scalars and arrays, like strings?
Strings and integers are data, but containers are "magic". Right. The propensity for fuzzy magical thinking is wired into our brains, not artificial. But that doesn't mean it's a good way to design a programming language.
Containers can certainly be data. A string is a container of characters, and we're certainly interested in its value as data. A window is a container of sub-windows. In many systems, windows inherit from and/or behave like containers, so you can loop over them and manipulate them just like containers.
So should the window.Add(subWindow) method automatically loop over the subSubWindows of subWindow and add each of them as direct children of window, or should it simply add subWindow to window directly so its subSubWindows are grandchildren of window?
I was referring to Perl's scalar/array distinction as being artificial and fuzzy -- I wasn't claiming the singular/plural concepts in your brain weren't natural. They're vastly different things. It's fuzzy magical thinking to believe that Perl's dichotomy of scalar/array maps directly to your brain's concept of singular/plural.
Does everyone's brain's built-in concept of plurality naturally support nested polymorphic arrays? Do those arrays in people's brains also behave like keyed hash tables, like Perl and JavaScript arrays? Must the keys be strings, or might they be any hashable idea? What does it mean for an idea to be hashable? Do Perl references work exactly the same way as actual human neurons? What about dolphin brains?
Please show me some peer reviewed scientific studies that prove Perl arrays accurately model natural language and mirror human thought, and then I will concede that Perl is more linguistically or biologically "natural" than Python.
But until I see some proof to the contrary, I believe that Larry Wall is to linguistics as Deepak Chakra is to physics:
"While in graduate school at the University of California, Berkeley, Wall and his wife were studying linguistics with the intention of finding an unwritten language, perhaps in Africa, and creating a writing system for it. They would then use this new writing system to translate various texts into the language, among them the Bible. Due to health reasons these plans were cancelled, and they remained in the United States, where Larry instead joined the NASA Jet Propulsion Laboratory after he finished graduate school." https://en.wikipedia.org/wiki/Larry_Wall
> Strings and integers are data, but containers are "magic". Right.
I appreciate your sarcasm.
I've heard some folk say they find the distinction between values and variables (containers) to be confusing. Imo this is worth discussing, as are issues about coding and the brain, so I'll continue.
> The propensity for fuzzy magical thinking is wired into our brains, not artificial.
Are you saying that the brain's capacity to distinguish singular and plural things is "fuzzy magical thinking"?
> But [the fact that the brain distinguishes singular and plural] doesn't mean [taking that into account is] a good way to design a programming language.
It also doesn't mean it's not. More on this in a mo.
> Containers can certainly be data.
Yes. I thought use of Wittgenstein's ladder[1] was wise given the mistake you'd made that was the first thing I responded to in our exchange in this subthread.[2]
Anything can be data just as code is data (explicitly so in, eg, lisps). But it can be helpful to distinguish code from data and the same applies to containers vs data. On the few occasions when a conceptual distinction is not helpful, one should simply ignore the distinction. (This is perhaps somewhat like lisp macros that could be said to conceptually treat code as code or as data depending on whether or not it's helpful to the human writer or reader to treat it one way or the other.)
> A string is a container of characters
In Perl 6 a "string" is not a "container" even if you like to think of it that way and/or use the words that way.
> So should the window.Add(subWindow) method automatically loop over the subSubWindows of subWindow and add each of them as direct children of window, or should it simply add subWindow to window directly so its subSubWindows are grandchildren of window?
Exactly. Both interpretations can make sense.
This is why Perls provide notation to emphasize either the scalar or composite interpretation of an entity and to optionally switch to the other interpretation for any given mention of that entity in code.[3]
> It's fuzzy magical thinking to believe that Perl's dichotomy of scalar/array maps directly to your brain's concept of singular/plural.
Audience member, to Deepak Chopra: "You stated ... that 'all belief is a cover-up for insecurity', right?" Deepak: "Uhuh". Audience member: "Do you believe that?" Deepak: "Yes."[4]
I consider the notion that Perl's singular/plural distinction maps directly to the brain's to be at least plausible as an explanation of why it seems so natural to me.[5]
> Does everyone's brain's built-in concept of plurality naturally support nested polymorphic arrays?
Iirc, the results from neuroscience I've read that study brain circuits that process aspects related to nesting (hierarchy) suggest it's reasonable to view them as distinct from those that process the singular/plural distinction in most humans.
So, to the degree that separate brain circuits could be said to be mutually supporting, I'd say that one's brain circuits that process plurality support nesting (and vice-versa).
Something similar may apply for polymorphism.[6]
> Do those arrays in people's brains also behave like keyed hash tables, like Perl and JavaScript arrays?
I think there's more than a century's worth of science supporting the notion that association is deeply fundamental to how the brain works. Aiui it's an even more primitive mechanism than processing hierarchy and singular/plural aspects.
> Must the keys be strings, or might they be any hashable idea?
Again, I think I'm on solid ground when I say that humans' brains naturally support association of arbitrary "things".
Perl 6 supports any hashable entities as hash keys, not just strings.
I downvoted you, but perhaps too hastily. I think that sigils are a matter of opinion, and there are benefits to using them and also to not using them. I think that this downvote was really intended for your original comment, which I interpreted as essentially stating a personal preference as fact.
Also, the inclusion of non-ASCII operators harkens back to APL. Mind mind isn't yet made up on whether I like this. I anticipate code being easier to read and harder to type. Given perl5's reputation in this regard, I'm optimistic I'll find it to be an improvement.
In other languages this is solved by naming variables appropriately. There would be no variable "x" because it's a bad name. It would be something like coefficient-of-friction which is clearly a scalar. Having to write a symbol to denote that it's a scalar is superfluous. This explains why Perl code looks so messy, by the way. The language itself encourages poor variable naming.
As long as you view Perl, whether 5 or 6, in the light of C and assume it should function like C, then there will be lots of little things that seem odd and pointless. When you accept that Perl implements some things that C has no concept of whatsoever, and uses them to it's advantage throughout the language, then many of these little things start to make sense. Specifically, Perl uses context to change behavior, and lists behave differently depending on context.
This is really no different than how Lisp uses parenthesis in a different way than C, except that Lisp has the benefit of being more visually distinct so people that are familiar with C and C-like semantics don't immediately assume they know what's going on an why when they see Lisp constructs. Perl is different as well, but it often looks similar enough to cause people concern before they know what they are really looking at.
As for this specific example, arrays evaluated in scalar context (as opposed to list context) return the number of elements in the array. There is no array length function or method, as it's superfluous. 0+@x is the number of items in @x, and 5 < @x tests whether @x has more than 5 items, since < imposes scalar context. There are many, many places in the language where context is used to simplify operations, this is just a very simplistic example, but it should illustrate why sigils are important, as they change how operations are evaluated.
Put simply, it's not possible to make a coherent criticism of Perl's use of sigils without understanding context and how it's used within the language, and factoring the benefits and drawbacks of that into your criticism. To criticize without this knowledge is to do so from ignorance (in the literal sense, not as an insult).
I could give a list of features as to how Perl 6 will make my life as a developer better, but a list of features is not enough to justify adopting a whole new language with a small ecosystem. To adopt a language, it really has to improve your productivity. For instance, I think we've seen this with Go's adoption by people from dynamic languages, as it offered type safety, speed, and concurrency in a package that was generally more readily acceptable to them than Java/C#/Scala/etc.
jnthn has a great series of blog posts illustrating how many of Perl 6's features come together to make developing a library very easy. To me, this is a great example of "how does Perl 6 help a business": by allowing rapid development of a complex asynchronous application, which is a use case many of us face. He illustrates this by writing a STOMP client for RabbitMQ, going from toy to a serious library: https://6guts.wordpress.com/2016/01/04/not-guts-but-6-part-1...
I look at this workflow and think, "Wow, I wish I could do things that easily." But now I can, because Perl 6 is out. :)
I too have been admiring Jnthn's latest posts. The reactive programming displayed is really quite lovely. God it actually makes me want to develop an asynchronous client! The only other language that makes me feel that way is Go.
Perl tends to be a practical language: Perl programmers are too busy working on their product to rebuke scathing criticisms from angry bloggers and the peanut gallery. But that angry blogger? He'll get a mob together and start protesting outside your house if he catches you using the wrong Javascript library.
I say don't worry about the criticism and popular opinion: The specific language you use is pretty far down the list of problems that a given software might have. You'll build up some useful libraries in your niche and eventually other people will see that the most time-effective way to solve a problem in that niche is to use Perl 6 to get access your libraries.
Every other language I use derives from its specific purpose: Ruby because vendors like PayPal or AWS publish Ruby gems(and because of Rails); Haskell for writing parsers, interpreters, and compilers(ADTs and parsing monads); C if I'm trying to understand some code and need it to be portable or operationally simple; Perl 5 if it's a quick prototype script. Just the other week I needed a Bayesian variant of Prolog and would've used Perl 6 if it had a library for it.
I think I'm just surprised and saddened that HN heaps so much hatred on P6. I mean, we're a community of hackers: do we really need to ask "why another programming language"?
The hatred P6 receives here reminds me a lot of the hatred Go used to receive, where every article posted devolved into a discussion regarding the lack of generics. I bought into the "Go is a regression" meme for a long time until I started using it to solve real problems at work, and now I love it.
I hope that we programmers can learn to rejoice in each other's creations rather than to heap scorn and criticism on anything not from our particular tribe. It reminds me of people who insist that you can only like a single video game console... heaven forbid you use more than one, or one with inferior graphics (but with more fun games!), etc.
I don't see hatred in this discussion. I see lots of puzzlement and confusion though. This might be because the article doesn't really accomplish what the title promises as the features and examples given don't feel compelling to most of the people in this discussion.
I don't know if Perl programmers have been separated from the other scripting languages too much as not to understand that there are different mindsets out there.
Perl has always been quite a confusing language if you only skimmed it (lots of incoherent features and more than one way to do it), so I find it natural that Perl6 isn't any better.
But if you don't explain the confusing features of a language well enough, puzzlement and confusion is what you get.
I don't know if Perl programmers have been separated from the other scripting languages too much as not to understand that there are different mindsets out there.
My impression is rather that the P6 marketing has traditionally focused on presenting a long list of features instead of a user-focused business case.
> I mean, we're a community of hackers: do we really need to ask "why another programming language"?
If not us, then who? There is plenty of space for a language that delivers real innovation, or even one that puts real polish on old ideas. But when a language does neither, we absolutely should be asking what it's for. A community that prides itself on being pragmatic and delivering business value should know the costs of language proliferation.
> There is plenty of space for a language that delivers real innovation, or even one that puts real polish on old ideas. But when a language does neither, we absolutely should be asking what it's for
Oh please. Perl 6 does both of these very nicely. Dismissing it out of hand as you have just done is exactly what the parent is complaining about.
Gradual typing, reactive programming, PEG grammars and language extension via those grammars... the list goes on. Innovation and polish abounds, yet we have comments like yours, which are completely uninformed. I thought HN was better than this, but perhaps there's no escaping eternal september.
HN hates everything that isn't Go these days. Try having a civil discussion about node.js and the top comment will be from someone who tried it once for their first project and 3 years later it was an unmaintainable nightmare.
Hackers or not, we're all still human, and experience emotions like frustration and disappointment. Back when perl6 was first being discussed (what was it, 15 years ago now?), probably a lot of us were getting a ton of mileage out of the remarkable perl5 ecosystem.
When perl6 started getting promoted, it seemed like it took a lot of the wind out of the perl5 sails, like an Osborne effect for a programming language.
When the years ticked by and nothing came of it, and lots of moved onto other languages, I imagine a lot of people still remembered being disappointed at how the perl5->6 situation played out.
Probably some of the negativity is just remnants of that, because, like I said, we're all still human.
And schadenfreude, I'm sure, plays into it, like when the overhyped disappointments Daikatana and Duke Nukem Forever were released...
Perl 6 doesn't deserve as many HN postings as it gets. The original Perl was a version of awk and sed on steroids, back at a time when that was fresh and new (the early 90s). Over the years, people realized that "there is more than one way to do it" was a terrible idea, and languages like Python and Ruby were born to be "like Perl, but better." Now even those languages are showing their age, because of the limitations of dynamic typing and weak runtimes. Perl 6 is just more of the same, 15 years too late. Even the most smelly pile of lisp macros still smells as fresh as a rose compared to this toxic pile of syntax.
Much of the "hatred" seems to come from those who have a lot of preconceived notions about Perl (either 5 or 6). However, I look at the people who approach the language with curiosity and no baggage, and the reactions I often see range from "that's cool" to "holy shit, that's cool."
A language should be minimal, easy to learn. On top of it you can build libraries. It should NOT be build into the language... To bad thats the direction Perl went from the start. It was usefull for text formatting, if you know all the quirks... But as a language to build big systems... I would never chose it.
The trick of course is that then your libraries effectively define your language. There are various sweet-spots of native-language features, standard-lib features, and external libraries. I think it is a matter of taste and trade-offs.
I don't get why anyone has any hopes for Perl6. It took 16(!) years to implement features other languages already have. And CPAN is the dark, sad pit of forgotten and abandoned packages. Is there really a significant chance that people will switch to Perl6 from any other not-perl alternative or embrace it as a first language.
CPAN still works fine. Some of it is due to Perl not changing fundamentally in a long time so some old package from 2005 is still likely to work today. Most breakage I've found comes from external dependencies, packages that load data from websites tends to decay very quickly if not maintained for example.
That said, it is still good practice to try to avoid dependencies on packages that are not maintained, or you might find yourself the de-facto maintainer of the package. This is true across all languages.
Perhaps one of the most enduring legacies of Perl is that no language that comes after it can be considered complete until it has its own CPAN like package management system. That and the regular expression engine of course.
It didn't really took 16 years to implement. It was announced 16 years ago.
In any case, the fact that the project wasn't abandoned after all that speaks for itself. It's here and the future was never brigher for it than it is now.
Most languages/platforms adopted regular expressions from Perl. I rather suspect most will eventually adopt Perl 6 grammars and that may be its lasting impact.
Thanks for the interesting discussion on Perl6; will have to try some of these cool new syntactical features.
I haven't had much need of Perl recently; trying to force myself to switch to Python (a jarring psychological experience) not because I hate Perl but because Python seems to be where a lot of the demand is these days.
But I learned something else of great importance from this article: cowsay
I'd never heard of cowsay before but it's an amazing tool! I installed it on my SuSE workstation (sudo zypper install cowsay) and on my Mac (brew install cowsay) and it just makes me happy! My favorite command is:
151 comments
[ 3.0 ms ] story [ 209 ms ] threadThe issue is, why would anyone want to move from Ruby/Python/Js to Perl in 2016...
Obviously most Perl users understand the benefits of Perl 6.
I get that learning Perl is not a very attractive proposition these days, and Perl6 currently does not have the vast library/framework ecosystem Perl5 has.
But I think Perl6 is not just for Perl5 programmers. In fact, I think a lot of Perl5 people are going to stick with Perl5 for a while due to a) libraries/frameworks and b) existing code that needs to be maintained.
actually not quite. given the plethora of libraries/frameworks etc. for perl-5, why would perl-5 programmers move to perl-6 ?
I'm a Perl 5 programmer. Perl 6 is a more perly Perl. I can use my Perl 5 modules if I really want, but I can write better specified, safer and more logical code. Just having simple functions like 'whenever' makes developing fun and easy.
Please see http://jnthn.net/papers/2015-yapcasia-concurrency.pdf for context
People in the first group would switch if Perl6 looks like a better tool. Short of revelation the second group won't. Hardcore Perl programmers have had a long time to think about Perl 6 and come to their conclusions. It's not a community where evangelism is likely to make a difference these days. I don't think the Perl community is like the Python community for cultural reasons that stem from their histories.
It kinda makes me sad that the instinct for most of these things is to port a lib from language to language to language... when does it end?! I never want anyone to write pyplot again -- let's just call pyplot from ALL the languages thanks to the magic that is a little c library called libpython.
https://github.com/niner/Inline-Perl5
Not to mention, you also have Inline::Python[1], and conceivably any other runtimes they want to embed. I think it would be interesting to see what you get by taking the best of class in each ecosystem and using them. It may or may not scale well due to data marshalling, but it's definitely something new (at least the ease of it is) and, IMO, worth looking into.
1: https://github.com/niner/Inline-Python/
I've been using Perl since 1994, built a company around Perl 5 code and the attractiveness of Perl 6 for me so far is: 0. I know the price paid (later) for ease of writing (maintainability or lack thereof and lots of traps for the unwary - using Perl::Critic has a devastating effect on perceived "freedom" and simplicity) and a language crammed full of fancy features (the Perl 5 interpreter code base is widely considered unmaintainable these days). I honestly can't think of a single use case of Perl 6 with more than 10 lines or so where it'll work better than e.g. Go.
People love to say this, but having read a fair chunk of the sources to perl5, cpython, ruby, Tcl and erlang's VMs, my semi-educated conclusion is "reasonably fast interpreters written in portable C all end up as their own slightly bizarre CPP-supported C dialect, and all end up more similar than they are different".
It's not that simple. Tcl, Ruby and Python all have several competing implementations, while to my knowledge nobody has even written a complete Perl 5 parser (except the one in the official Perl 5 code).
Or: I agree with everything you said apart from the implication that what you said is a counter argument to what I said - it seems to me that both can be true without conflict.
AFAIK, all the viable competing Ruby implementations use the parser from the mainline implementation; parsing Ruby is notoriously hard, and parsing isn't a weak point that alternative implementations usually try to improve.
I've been reading about, playing with, and really enjoying perl6 since the christmas announcements.
The idea of a 'fun hackers language' really appeals. There's a lot of 'oh sweeeeeet!' moments. I still won't be using perl for any production projects / work stuff for a while, but as a fun out-of-hours playground, this really does look like a cool new language. I'm pretty excited by it.
- Version 6.c? Why not 6.0?
- What's with the whole "language" and "compiler" distinctions no one cares about?
- Why is the first stable release of the compiler not optimized to the max?
- Is there a need for a new Perl? What is it good for?
- What is its business case?
- Why in the world would anyone use Perl 6?!
If I want to transform my 100.000 line program to a smaller one I won't grab Perl 6 to transform it to 50.000 but I will grab Clojure for example to transform it to an 5.000 one. Is that the only argument for using Perl 6?
Sorry for the sarcasm, but the author hasn't given a single reason beyond some trivial (and inconsequential, imo) syntactic shortcuts and his personal preference for the language.
What a weirdly arrogant and ignorant statement. If you're writing 20x as much code instead of using Clojure, then you're doing some pretty terrible programming.
I fail to believe that those 6 points could have been written by someone unbiased. Please show me some Clojure that's 10x more succinct than Perl 6. Otherwise then surely this counts as trolling.
Perl 6 loses quite a bit of the Write Only type syntax, and should be very succinct and expressive, but people just type nonsense :(
Things were going great until I used a validation library with HTML form input to check some numeric ranges. Boom: cannot convert java.lang.String to java.lang.Integer. Would the same thing happen in clojurescript? If it obeys js semantics then I won't get an exception, but "200" will become 200 and things will work as expected.
If you have a language defined by a test suite that exists separately from your compilers, then perhaps you can avoid these kinds of problems.
People care about distiguishing C89 and C99 from GCC and clang and their versions. If we don't want to block the road to future compilers for the same language (and we had other compilers in the past, they just aren't maintained anymore), we'd better be careful to distinguish them.
> - Why is the first stable release of the compiler not optimized to the max?
Because it's the first stable release, not the last. We expect to improve still.
For Clojure's target audience of people who already know Java (or JavaScript) there's a lot of evidence that it was a good decision. Tools like Leiningen can use a familar tree structure and offer the potential benefit of configuration via code in comparison to other Java build tools. But the point of comparison is at a particular level of overhead and that level of overhead is assumed. With ClojureScript, the toolchain is more complicated than a typical JavaScript tool chain. Again that's a tradeoff.
Which again, I think Clojure is great. That doesn't mean I think that those tradeoffs are always appropriate. YMMV.
As for the statement about language design, I'll add that onto the next one, as it makes more sense in that context.
"Perl 6" is a _language_, not an _implementation_. There's a language spec, and any implementation of this spec is a Perl 6. This is a distinction that a lot of projects make, but is a lot fuzzier, because they don't have specs. Consider Ruby: yes, JRuby is also a Ruby, but since there's no language spec, people still assume MRI when you say "Ruby". Perl people don't want you to assume Rakudo when discussing the language itself.This is why there's no minor version of "Perl 6". Language specifications change a lot less frequently than compilers.
Like most projects, as long as performance is Good Enough, it's good to get people start using it, and then work on performance after. Especially for a language where performance isn't a main goal, like Perl. As long as you haven't painted yourself into a corner with language decisions, performance improvement is refinement work. I don't know if there's a _need_, but Perl 6 sure improves on a ton of things about Perl 5. It's the stuff that makes Perl Perl, but turned up to 22, not just 11.The last two are questions I can't really answer.
This sounds absolutely retarded.
Back when Perl 5 this kind of hacker clown routine was popular, but now I think most people prefer a bit more simplicity and clarity.
Perl 6 also has gradual typing baked in. Other languages have gradual typing as a library, but that often fails dramatically (http://blog.circleci.com/why-were-no-longer-using-core-typed...). In Perl 6, because it's built-in, not only are the failures described something Perl 6 can avoid, but there are also plenty of type checks Perl 6 can avoid at run time with integrated gradual typing (imagine that benefit in hot loops).
You could even combine that with native junction auto-threading and presumably have super-fast comparisons where the needs for checking types is eliminated at run time because it's already been done at compile time. If you do that with libraries, it's awfully tricky to get right, if not impossible.
http://doc.perl6.org/type/Junction
I could copy and paste the definition but it wouldn't be too helpful without context.
When it says autothread does it mean actual separate threads/CPUs?
I don't think Rakudo implements that yet, but there's quite a lot to improve first.
So far in my Perl 6 exploration I don't think I've used/needed junctions -- strikes me as a specific sort of use-case, but maybe familiarity would help me spot more (useful) opportunities.
[1] http://doc.perl6.org/type/Junction, though like all P6 docs needs more contributions
If you wanted, you could get pretty close in ruby with only a sprinkle of ill-advised metaprogramming.
would be possible.I guess I'm just curious if this is a situation that comes up often enough to need a built in literal syntax.
If I look at the examples on this page https://en.wikibooks.org/wiki/Perl_6_Programming/Junctions it doesn't seem to be.
For example "if ($x == 2 || $x == 4 || $x == 5 || $x == "hello" || $x == 42 || $x == 3.14)" can be done in Perl6 as "if ($x == (2|4|5|"hello"|42|3.14))" but in Ruby this would equally easy been done with "if [2,4,5,"hello",42,3.14].include?(x)".
Ruby also has set operations defined on its container classes (e.g. [1,2,3]&[2,3,4] => [2,3]) and any?, all?, none? methods that take blocks.
Perl6 looks like a language that might have been great if it had been released in the 90s but nowadays I wonder if it will gain enough traction from non perl programmers.
But that isn't the same is it. That's only a related feature because Ruby doesn't have first class Junctions.
> I wonder if it will gain enough traction from non perl programmers.
These days people have been taught to be arrogant. To assume their language is the best. This is what makes things a tough challenge.
At least in this case, the only difference I see is that this is a language feature in Perl6 and a method from the standard lib in Ruby.
And it has to be a language feature in Perl 6 as there you don't have open classes as in Ruby or an equivalent feature for overriding operators or adding functionality to standard lib types.
I'm not sure what makes you think this. I'm not very familiar with Ruby's internals but Perl 6's MOP certainly supports modifying classes, you can add your own operators etc.
Could you provide a more explicit example?
Please take another open minded look at the examples others have posted here. Post again if you still don't see what they do that's useful and not trivially doable in any language and I'll have a go at explaining them to you.
It's not a problem with an open mind but rather with understanding what data type a junction is trying to be.
If I go to the official specification (my fault, should have gone there from the beginning), I read the definition "A junction is a superposition of data values pretending to be a single data value". But that's a fuzzy definition and it is absolutely not clear what that's supposed to mean. The given examples don't help either.
Especially when I look at this discussion and see that several people including you are not sure what "all(@ar1) < any(@ar2)" is supposed to mean. That's not a complicated expression and that's already puzzling to people who know the language?
The autothreading feature is cool but also nothing too special. Every pure functional language can implement map/reduce/filter in parallel.
tl;dr I don't see what junctions bring to the table that's not expressed easier to understand with set operations or map/reduce/filter.
Afaik junctions are simple and have an obvious intuitive read. But I'm not yet 100% confident of expressing that view without qualification. Given Estragon's "no idea" comment I allowed that my intuitive read might be bogus.
In fact the intuitive read is correct:
> The autothreading feature is coolTo be clear, the whole point of junctions is autothreading; passing junctions to any code that does not have an overload for junctional arguments is automatically (semantically, at least) data parallelized and that's the win that makes them significant.
> Every pure functional language can implement map/reduce/filter in parallel.
I note "can implement" and your choice of just three functions.
Which languages provide a mechanism equivalent to junctions and their most significant use-case -- automatically generating data parallelized versions of any sequential functionally pure code?
> I don't see what junctions bring to the table that's not expressed easier to understand with set operations or map/reduce/filter.
What equivalent of "all(ar1) < any(ar2)" -- all ar1 less than any ar2 -- is "expressed easier to understand"?
Ultimately: it would be trivial to port ALL Enumerable methods to Perl 6 List (or some role to cover all iterables or such), and do it in a library even if it wasn't in the core standard lib.
I'm always fascinated by how much of Ruby (and lots of other languages) are more about their Standard Lib than about their language. In the Ruby world, lots of people end up with ActiveSupport, which sprinkles in all sorts of cool stuff into the standard lib -- and I've ever seen a native 'for' loop rather than a .each in pragmatic Ruby.
More typical uses are:
Basically : junctions are not sets. Don't try to use them for set operations. Perl 6 has a Set structure. Use that instead.In Ruby, you could express the same with `[2,4,6].reduce(true) {|even,num| even & num.even? }` or more clearer IMO `[2,4,6].map(&:even?).reduce(&:&)`.
The third example shows the so-called auto-threading behavior. I think it's significantly different than what you can do with sets.
A Junction in Perl 6 is "a superposition of data values pretending to be a single value". So for instance any algebraic expression can be used with a junction as if it was a scalar. The result will be a junction.
In this example the expression is $_ %% 2, which is Perl 6's way of writing the boolean statement "the variable $_ is divisible by 2". We use this expression with ($a & $b) instead of $_.
However ridiculous it sounds, a weight is lifted from my chest.
I mean, it's nice that this sort of functionality has nice and concise operators, but I'm coming from a school of thought where overloading the equality operator should not be done lightly :)
Junctions seem way more complex than that, first there are 4 different junction contains (any, all, one and none), second they overload 12 comparison operators each and third the other operand doesn't have to be a junction.
So e.g. any(@ar1) == any(@ar2) is an intersection but any(@ar1) == $val is a containment, and I've no idea what all(@ar1) < any(@ar2) would be, I guess it would check that max(ar1) < max(ar2)?
* Makes $x == 5|6 look kinda cool
* $string ~~ /<first>/ & /<second>/ & /<third>/ # matches all three regexes. huh. kinda cool
* (5|6).foo maybe we can do that in cpu-parallel (it doesn't now)? That might be kinda cool
* sub is-prime($n where $n > 2) { $n % none(2..sqrt($n)) == 0 } # Logical O(1) prime test if only you had that quantum-coprocessor? That... would be kinda cool
* ... you might notice a pattern to the motivation for this feature :)
It seems that it just expands the lists using the operator. The output from junctions is quite nice:
Each operator and its overloads -- certainly built ins, users are recommended to follow suit -- conceptually maintains its own single high level semantics. Thus, while some langs have a `+` op that does numeric addition or string concat based on operand types, in Perl 6 a `+` will always mean numeric addition (unless a user breaks this convention).
`==` is always numeric value equality.
`==` does what most folk would expect between any pair of values that are a subclass of Any (the root of the type hierarchy for most purposes).
Junction is a direct subclass of Mu (the ultimate root of the type hierarchy), outside the Any hierarchy.
When a scalar operation is applied to one or more Junction values, the relevant operation is "autothreaded" over the superposed values inside the Junctions and returns a new Junction value.
If a Junction is treated as a boolean the Junction collapses to a regular single boolean value.
Thing is, operators in perl6 are basically multimethods under the hood, as is pretty much everything else - so it's a much saner, more predictable thing than, say, the bag of razorblades that is perl5 overloading (which I've used to good effect, but, still, razorblades ;).
So you have some old perl scripts laying around, but they work well enough and some guy takes care of them, updating them when they need. He knows perl and that's his job, so whatever. One day, the architecture changes and the scripts need to go parallel. That's a problem because the perl guy doesn't know Pony (a promising language with a community even smaller than perl6...) and really needs to get these scripts running again.
So he uses Perl6 along with the inline module, and things are working again. Over time, he hacks up a better system in vanilla Perl6, and deploys that too. He had such a great time using Perl6 that he even hacks up a few more tools he could use, etc etc, next thing you know he's a Perl6 developer.
I write ruby because it is modeled similarly to how I think about problems, but if I was a perl guy, I could see the appeal to Perl6, but saying that it's a dinosaur is both wrong and irrelevant to the FUD surrounding Perl6 right now. At this point, it's about adoption.
Why not "if 5 < x < 100"? Sigils look awful.
Also you get to know if a variable is only block scope, method scope, class variable, etc.
Twigils in Perl 6 are where the scope indicators come in, clarifying class instance vars, dynamic scope, and so on.
So if I see %.foo I can tell you that this variable can be used as the Associative role, that it is scoped as an instance variable, and that it has an accessor with the same name.
For more, see the first few sections of http://doc.perl6.org/language/variables
Because sigils tell you things. What if 'x' in your example is a list? Are you now checking the length of the list rather than the value? Sounds like room for a security bug to me.
Only if your language is really awful. A good language shouldn't even let you run "5 < x" when x is a list, but even a mediocre one would surely at least make that error out at runtime rather than giving a nonsense answer.
It depends what you consider "Nonsense". Python for example has no reliable way to differentiate between a string and a list. Strings are iterable, but lists can't be compared with the < syntax for example.
My point is simply that $x very clearly says (in Perl 6) "A single value called x" wheras @x is "A list of values called x". In python, "x" is indeterminate even at runtime.
Oh, and you can declare barewords with \x for example, if you really want to, it is Perl after all.
Doing something like isinstance(x, str) is discouraged and considered non-pythonic, and recently hasattr() has also been talked about. However, both strings and lists can be iterated, so assuming that this will fail is incorrect:
I asked on IRC and ultimately the only answer I got was that the most pythonic way to do things was to name functions whatever_str and whatever_list.edit: I also should have said above "lists can't be compared with strings using <". I was trying to point out Python did things potentially correctly there, but I see now it's ambiguous.
How should you decorate functions that return different types depending on what context they're used in? http://perlmaven.com/wantarray
If it's so important to visually distinguish the names of scalars and arrays, then shouldn't you also be able to distinguish a string from an int, like BASIC's a$ -vs- i%?
So why just distinguish lists and scalars? Why not go all the way to Hungarian Punctuation and use Unicode and Emoji characters to uniquely decorate variables for every other possible built-in and user defined type? https://en.wikipedia.org/wiki/Hungarian_notation#Relation_to...
However, if you really want to do some of the other things you've listed they are possible to do. Perl 6's syntax can be augmented by the programs being executed.
I'm honestly interested though, was I ultimately wrong above? Is there a smart way to define a function in python that can take both a single item and a list of items? In Perl 6 I'd just define a multi sub where the list form applies the single item sub for each item in the list.
If Perl 6 is an entirely new language, then why is it riddled with so many bad ideas from another language that only coincidentally shares the first 4 alphabetic characters of its name?
Why the artificial scalar/array dichotomy? What is it that is so important about being able to distinguish variables holding scalar-like values and array-like values by punctuation, but it doesn't matter that you can't distinguish variables holding strings and integers by their punctuation?
And how can you be consistent about types that act like both scalars and arrays, like strings? Or user defined types that might behave like scalars or arrays but are represented by objects? Are those treated as arrays? Or are they references, treated as scalars?
Scalar -vs- array is a false dichotomy that's deeply and unnecessarily embedded in the very syntax of the language.
There's more to sigils than just scalars and arrays too, as you can see here: http://doc.perl6.org/language/variables#Sigils
The difference in your examples are that scalars describe more the 'shape' of the variable than its type. Given that a lot of programming is dealing with lists or 'dictionaries' this is a fairly minimal intrusion into the code that very much improves succinctness, correctness and the ability to easily read what some code is doing.
Oh, and strings don't act like arrays in Perl 6 AFAIK. Because they could be split on characters, or codepoints, or bytes, you must be explicit:
(Or to be perly)The few cases when you need to make that distinction aren't worth infecting the rest of the code with punctuation marks. Using letters to explicitly spell out self-documenting words in the few function names that need to make that distinction is much less intrusive, more flexible, unambiguous and capable of precisely distinguishing many more nuances, than using a small set of punctuation characters throughout all of your code to mitigate rare problems with just a few cases.
Of course it can be taken to an extreme, but it's much easier to guess or google for the meaning of an Objective C selector than for a bunch of Perl punctuation.
http://stackoverflow.com/questions/15152171/what-is-the-long...
In order for it to be like the Perl6 implementation I would have to check against every type of iterable AFAIK. For example, a generator would be perfectly acceptable, but is there a unique function I could check with hasattr?
Clearly you feel that sigils are intrusive in Perl 6, but having written a bunch I find it quite enjoyable, and they're pretty easy to find in the documentation too. Ultimately, you can use variables without sigils, but with caveats: http://doc.perl6.org/language/variables#Sigilless_variables
Define what it is you want - which function you want to use - and then check that (e.g. if you want to iterate over it check for __iter__; if you want to want to test membership check for __contains__). In one part of the code a generator might be acceptable; in another it might not. Which is the point really - array vs scalar seems like a simple, sensible, widely usable distinction on first glance, but it turns out the meaning you actually want is very context-dependent, and a global distinction is a lot less useful than it appears.
Why should you have to write a special function that knows about looping, when the language already provides several perfectly fine ways to loop?
jQuery loves to do that kind of stuff too, slowly sniffing and savoring the arity of its arguments and reflecting on their types at runtime, then doing totally different things like getting, setting, configuring, instantiating, sending messages, and iterating, depending on the number and type of parameters, possibly selecting multiple items even if you only want one, etc...
Personally I don't think that style makes code any easier to read or write or guess what it will do, and it sure is a source of a lot of implicit behavior and inexplicable errors.
Having one function named "x" that gets x, sets x, iterates over the x dimension, searches for x, or creates x widgets depending on how it's called doesn't make my life any easier.
I'm willing to read and type a few more letters to use a set of longer self documenting function names. Using explicit descriptive consistent names, instead of heavily overloading short names and sigils, also makes the documentation easier to search and the IDE easier to use.
Explicit is better than implicit or inexplicit.
What is so important about the scalar/array dichotomy (which I think is fuzzy, arbitrary and artificial), that they get their own sigils to disginguish them, but you don't also use different sigils to distinguish ints from floats, numbers from strings, arrays from dictionaries, objects from classes, locals from globals, objects from proxies, inputs from outputs from references, etc?
The root of the sigil problem is that you quickly run out of unused ASCII punctuation characters to decorate all the concepts you feel the need to distinguish. Of course you could limit identifiers to a single character and require the use of Unicode, like Bjarne Stroustrup suggested in "Generalizing Overloading for C++2000" [1], but isn't it simpler and easier to just use letters that spell out what you mean as words, instead of context sensitive punctuation you have to look up in a legend?
I like the way C# uses "in", "out" and "ref" instead of punctuation or emojis.
[1] http://www.stroustrup.com/whitespace98.pdf
In Perl 6 function overloading is generally resolved at compile-time.
> Explicit is better than implicit or inexplicit.
Explicit what?
(jk)
> What is so important about the scalar/array dichotomy
See my earlier reply to another of your comments.
> context sensitive punctuation you have to look up in a legend?
Sigils are not context sensitive.
> The root of the sigil problem is that you quickly run out of unused ASCII punctuation characters to decorate all the concepts you feel the need to distinguish.
The distinction corresponds to major distinctions known to be wired in to human brains: single vs plural, and number vs name.
If this seems arbitrary to you perhaps you lack self awareness?
(jk)
I think we get away with those in natural languages because humans are willing to be fuzzy about that. E.g. whether an organization is singular or plural differs based on context and dialect. Whereas the only distinctions it makes sense to use in programming languages are those that we can make precise.
http://www.learn-english-today.com/lessons/lesson_contents/g...
I see no conflict between a mental process being a fuzzy "natural language" thing in our brains and the code modelling that concept using a precise formulation.
Indeed, to the degree I'm wrong we're in trouble. To read and write code we have to use what we've got -- our brains -- and we have to work with them the way they insist on working:
"Janet Siegmund and her colleagues observed 17 participants inside an fMRI scanner while they were comprehending short source-code snippets
...
The programmers in the study recruited parts of the brain typically associated with language processing and verbal oriented processing (ventral lateral prefrontal cortex)
...
Interestingly, even though there was code that involve mathematical operations, conditionals, and loop iteration, for these particular tasks, programming had less in common with mathematics and more in common with language. Mathematical calculations typically take place in the intraparietal sulcus, mathematical reasoning in the right frontal pole, and logical reasoning in the left frontal pole. These areas were not strongly activated in comprehending source code."
~~ http://www.huffingtonpost.com/chris-parnin/scientists-begin-...
To my mind that suggests an ideal programming language would not "hardwire" rules of grammar, that sigils should be more like flexible hints to the reader than things that have rigid language-level meanings.
Apologies if I'm harping on about this too much but I would like to object to "If" as being too ambiguous in this context.
The most active non-memory/attention brain circuits used in comprehending the code samples in the study I referenced were consistently for natural language processing, not math/logic processing, for all 17 of the 17 participants in the study.
It's a small test but a pretty emphatic one nonetheless. For at least some folk (and it's at least plausibly most/all folk) for at least some code (and it's at least plausibly most/all code), it's "WHEN we comprehend code we use natural language circuits and so...", not "IF...".
> that argues for having our programming languages emulate natural languages.
Well, careful. Natural languages are fuzzy! We want programming languages that do TWO things -- leverage our natural processing capacities to the degree they're relevant AND render their fuzziness relatively harmless at the same time.
> Even in matters of precision such as legal contracts, we don't always conform exactly to the "rules" of grammar - indeed I'd say that legal language violates those rules even more than natural language does.
Yes. This is a very important point. Think in terms of thousands of DSLs. How does one enable that? How does one cope with that?
> To my mind that suggests an ideal programming language would not "hardwire" rules of grammar
Right. The Perl 6 project not only addresses this but is a full frontal assault on it. It's one of the various reasons it took 15 years to get to 6.c.
There's a standard Perl 6 grammar but Perl 6 Rules can relatively easily specify any grammar. And I mean any grammar, whether Chomsky hierarchy level 1 (regular languages -- where regexes originally came from) or level 2 (context-free -- where parser combinators have traditionally shone) or level 3 (context-sensitive -- various parser combinators extensions have recently started to nibble at this) or the final level 4 (recursively enumerable languages).
Aiui Perl 6 can reasonably be viewed as the world's first practical "universal unrestricted grammar" capable of accepting any other language.[1]
> sigils should be more like flexible hints to the reader than things that have rigid language-level meanings.
Sure.
For starters, sigils are just a part of standard Perl 6. You can write any language in Perl 6. So, for example, the ipso language is a sigil free lang (it's a lisp) in Perl 6[2] and Slang::SQL is for embedded SQL.[3]
If we stick to standard Perl 6, sigils just mean a few very general things, as follows.
First, that the associated term is primarily a "noun". This determines where it does and doesn't fit in the grammar.
Then particular sigils -- the main ones are $, @ and % -- establish some other properties of a given noun.
$ emphasizes the noun's singular nature rather than any potential plural nature it might also have.
@ emphasizes the noun's plural nature and having an integer index (the array `my @bananas[15]` corresponds to a bunch of 15 bananas indexed by 0 thru 14).
And finally % emphasizes plural nature and having an associative index (%colors<red> corresponds to the 'red' key'd value in the %colors dictionary).
You might argue that those are rigid. I'd counter that they correspond to human's natural processing circuits. But regardless, if you don't like them or want to repurpose them you can just create a slang or another lang that tweaks or entirely changes the grammar to suit your needs...
[1] https://en.wikipedia.org/wiki/Unrestricted_grammar
[2] https://github.c...
Ultimately, the scenario I came across this in was an atomic transaction decorated function. The data being provided to this function flows through a good 3 or 4 functions beforehand. I also require _single, _list and _listoflists behaviour. This would bloat a 4 function stack into something like 20 different functions. There are also issues with transaction decorators.
It just seems crazy to me that Python can't manage this (to me trivial) use case.
So it sounds like your needs don't align exactly with perl's sigils anyway (and why should they? For different business requirements you'd categorize differently).
> This would bloat a 4 function stack into something like 20 different functions.
Not with good language/design. Separate your concerns. Let the difference in behaviour live somewhere more appropriate - either on an object that contains the data (OO style) or in a callback you pass into the function (functional style).
> There are also issues with transaction decorators.
Decorators have problems yes, that's why I prefer to have a type system handle that kind of thing.
Indeed but I can write constraints in my function signature to permit this. Hell I can even define something as SpecialList[SpecialKey] if I truly wanted. Perl has a type system.
> Not with good language/design. Separate your concerns. Let the difference in behaviour live somewhere more appropriate - either on an object that contains the data (OO style) or in a callback you pass into the function (functional style).
Doing this in Python is an exercise in horror, frustration and hatred. Doing it in Perl is the work of a few seconds. That is my point.
Interesting. Is this a new thing?
> Doing this in Python is an exercise in horror, frustration and hatred. Doing it in Perl is the work of a few seconds. That is my point.
Then what's the perl example without using sigils? Does that not translate directly into python?
What is the single "thing" you're referring to and what is "new" relative to?
I interpret hahainternet's comment to refer to at least three new things in Perl 6 relative to Perl 5: Perl 6 has a carefully developed type system, roles support parametric polymorphism, and both static and dynamic type constraints on parameters are supported.
-----
You earlier wrote "If you want two different behaviours, write two different functions". But hahainternet had written two different functions. This suggests you hadn't then yet taken on board what multidispatch is (a fundamental innovation -- from the 80s iirc -- related to declaring and calling functions).
Then you responded to hahainternet's "This would bloat a 4 function stack into something like 20 different functions." with "Let the difference in behaviour live somewhere more appropriate ... on an object that contains the data (OO style) ..." without realizing that that's less appropriate, not more:
"In the presence of multiple dispatch, the traditional idea of methods as being defined in classes and contained in objects becomes less appealing" (from https://en.wikipedia.org/wiki/Multiple_dispatch).
A similar argument applies to callbacks.
All in all I'm guessing you haven't yet seen the light about multidispatch and a read of https://en.wikipedia.org/wiki/Multiple_dispatch#Perl_6 might help clear some things up.
The type system and perl 5. That would have been a much more constructive response to "why perl 6?" (if it's as good as you say) than this article.
> You earlier wrote "If you want two different behaviours, write two different functions". But hahainternet had written two different functions. This suggests you hadn't then yet taken on board what multidispatch is (a fundamental innovation -- from the 80s iirc -- related to declaring and calling functions).
No need to be rude. Rather than argue over whether the cases of a multimethod are different functions or the same function, let me just clarify that if you want two different behaviours then it is clearer to give them different names.
> "In the presence of multiple dispatch, the traditional idea of methods as being defined in classes and contained in objects becomes less appealing" (from https://en.wikipedia.org/wiki/Multiple_dispatch).
That article is decidedly non-neutral. I'm well aware of multiple dispatch. I find it very bad for code maintainability, and often a sign of poor domain modeling. The interaction between two objects is an unnatural and opaque place for behaviour to live; usually the behaviour belongs to one or the other or on its own, or if their relationship is that complex it should probably be promoted to a first-class entity.
> The type system and perl 5.
Gotchya. Perl 6 is not a Perl 5 update. There are reasons it shares the name Perl, which usually become obvious if you know both langs, but for non-users it's best to think of Perl 6 as a completely new language.
> That would have been a much more constructive response to "why perl 6?"
I think the OP article was a mostly good humored response to the reality that a lot of responses to Perl 6 are absurd. Like individuals sincerely asserting that it should not be taken seriously by anyone for any commercial purpose -- because of perceived problems with the logo chosen by the language design team!
> (if it's as good as you say)
Uhoh. Did I say Perl 6 is good? I think, right now, it's a lot of fun if you're in to all sorts of PLs. But let me restore balance in the force. The language isn't equational and its type system isn't Hindley Milner. Compiled code is very slow and consumes a lot of RAM and fully fixing that is going to take many years worth of engineering. The doc needs tons more work. There are only a handful of modules. It's a new and unproven language. Balance restored?
> No need to be rude.
My apologies. I didn't mean to be rude.
(I looked over your other responses in this thread prior to posting my comment and none suggested to me that you were claiming familiarity with multidispatch and several suggested to me that you did not really have a feel for how they work out when properly used in Perl 6.)
> Rather than argue over whether the cases of a multimethod are different functions or the same function, let me just clarify that if you want two different behaviours then it is clearer to give them different names.
Gotchya.
Nit: multidispatch in Perl 6 works for any function and (almost) any operator (operators are actually just functions), not just methods.
The Perl 6 view is that multi functions/ops/methods have both a "short" name and a "long" name. The short name is the bit that goes before the parameters. The long name includes the signature. It's a different perspective on naming and I find it works well for me.
> I find it very bad for code maintainability, and often a sign of poor domain modeling. The interaction between two objects is an unnatural and opaque place for behaviour to live; usually the behaviour belongs to one or the other or on its own, or if their relationship is that complex it should probably be promoted to a first-class entity.
I hear you've encountered use of multiple dispatch that you don't like, and that it's often signaled poor design, and that you think that the code placement for a multimethod is fundamentally unnatural.
But I don't hear that you've encountered multiple dispatch for functions and/or operators rather than methods; or that you've seen the scenarios in which it is a good fit for coding (I presume you don't think there's literally no sweetspot use-case); or that you've had a chance to work with a language like Perl 6 in which multimethod placement is as you suggest. So it sounds like you have only encountered limited and perhaps poorly designed and/or used multiple dispatch and that's colored your perspective.
Anyhoo, thanks for the exchange, and I hope you get another chance to use Perl 6 for something it's good at and see that, whatever else may be true, it is a lot of fun. :)
There is no such division of types in Perl 6 in the normal CS sense of the word "types".
There are several kinds (in the English sense, not CS sense) of data containers. Elements of these containers can be of any type (CS meaning).
> just like the idea of functions caring about the context of their return value.
As the GP just said, Perl 6 dropped that.
> Why the artificial scalar/array dichotomy?
The distinction between singular and plural is natural, wired in to our brains, not artificial.
> What is it that is so important about being able to distinguish variables holding scalar-like values and array-like values by punctuation, but it doesn't matter that you can't distinguish variables holding strings and integers by their punctuation?
As explained above, it's not about the values but the containers. Strings and integers are data. Containers are not data.
> And how can you be consistent about types that act like both scalars and arrays, like strings?
Perl treats strings as values.
Containers can certainly be data. A string is a container of characters, and we're certainly interested in its value as data. A window is a container of sub-windows. In many systems, windows inherit from and/or behave like containers, so you can loop over them and manipulate them just like containers.
So should the window.Add(subWindow) method automatically loop over the subSubWindows of subWindow and add each of them as direct children of window, or should it simply add subWindow to window directly so its subSubWindows are grandchildren of window?
I was referring to Perl's scalar/array distinction as being artificial and fuzzy -- I wasn't claiming the singular/plural concepts in your brain weren't natural. They're vastly different things. It's fuzzy magical thinking to believe that Perl's dichotomy of scalar/array maps directly to your brain's concept of singular/plural.
Does everyone's brain's built-in concept of plurality naturally support nested polymorphic arrays? Do those arrays in people's brains also behave like keyed hash tables, like Perl and JavaScript arrays? Must the keys be strings, or might they be any hashable idea? What does it mean for an idea to be hashable? Do Perl references work exactly the same way as actual human neurons? What about dolphin brains?
Please show me some peer reviewed scientific studies that prove Perl arrays accurately model natural language and mirror human thought, and then I will concede that Perl is more linguistically or biologically "natural" than Python.
But until I see some proof to the contrary, I believe that Larry Wall is to linguistics as Deepak Chakra is to physics:
"While in graduate school at the University of California, Berkeley, Wall and his wife were studying linguistics with the intention of finding an unwritten language, perhaps in Africa, and creating a writing system for it. They would then use this new writing system to translate various texts into the language, among them the Bible. Due to health reasons these plans were cancelled, and they remained in the United States, where Larry instead joined the NASA Jet Propulsion Laboratory after he finished graduate school." https://en.wikipedia.org/wiki/Larry_Wall
I appreciate your sarcasm.
I've heard some folk say they find the distinction between values and variables (containers) to be confusing. Imo this is worth discussing, as are issues about coding and the brain, so I'll continue.
> The propensity for fuzzy magical thinking is wired into our brains, not artificial.
Are you saying that the brain's capacity to distinguish singular and plural things is "fuzzy magical thinking"?
> But [the fact that the brain distinguishes singular and plural] doesn't mean [taking that into account is] a good way to design a programming language.
It also doesn't mean it's not. More on this in a mo.
> Containers can certainly be data.
Yes. I thought use of Wittgenstein's ladder[1] was wise given the mistake you'd made that was the first thing I responded to in our exchange in this subthread.[2]
Anything can be data just as code is data (explicitly so in, eg, lisps). But it can be helpful to distinguish code from data and the same applies to containers vs data. On the few occasions when a conceptual distinction is not helpful, one should simply ignore the distinction. (This is perhaps somewhat like lisp macros that could be said to conceptually treat code as code or as data depending on whether or not it's helpful to the human writer or reader to treat it one way or the other.)
> A string is a container of characters
In Perl 6 a "string" is not a "container" even if you like to think of it that way and/or use the words that way.
> So should the window.Add(subWindow) method automatically loop over the subSubWindows of subWindow and add each of them as direct children of window, or should it simply add subWindow to window directly so its subSubWindows are grandchildren of window?
Exactly. Both interpretations can make sense.
This is why Perls provide notation to emphasize either the scalar or composite interpretation of an entity and to optionally switch to the other interpretation for any given mention of that entity in code.[3]
> It's fuzzy magical thinking to believe that Perl's dichotomy of scalar/array maps directly to your brain's concept of singular/plural.
Audience member, to Deepak Chopra: "You stated ... that 'all belief is a cover-up for insecurity', right?" Deepak: "Uhuh". Audience member: "Do you believe that?" Deepak: "Yes."[4]
I consider the notion that Perl's singular/plural distinction maps directly to the brain's to be at least plausible as an explanation of why it seems so natural to me.[5]
> Does everyone's brain's built-in concept of plurality naturally support nested polymorphic arrays?
Iirc, the results from neuroscience I've read that study brain circuits that process aspects related to nesting (hierarchy) suggest it's reasonable to view them as distinct from those that process the singular/plural distinction in most humans.
So, to the degree that separate brain circuits could be said to be mutually supporting, I'd say that one's brain circuits that process plurality support nesting (and vice-versa).
Something similar may apply for polymorphism.[6]
> Do those arrays in people's brains also behave like keyed hash tables, like Perl and JavaScript arrays?
I think there's more than a century's worth of science supporting the notion that association is deeply fundamental to how the brain works. Aiui it's an even more primitive mechanism than processing hierarchy and singular/plural aspects.
> Must the keys be strings, or might they be any hashable idea?
Again, I think I'm on solid ground when I say that humans' brains naturally support association of arbitrary "things".
Perl 6 supports any hashable entities as hash keys, not just strings.
> Do Perl references work...
Also, the inclusion of non-ASCII operators harkens back to APL. Mind mind isn't yet made up on whether I like this. I anticipate code being easier to read and harder to type. Given perl5's reputation in this regard, I'm optimistic I'll find it to be an improvement.
my %clients vs my @clients
Do you name your variables
client_list .. client_dictionary? No? Then sigils aren't superfluous.
This is really no different than how Lisp uses parenthesis in a different way than C, except that Lisp has the benefit of being more visually distinct so people that are familiar with C and C-like semantics don't immediately assume they know what's going on an why when they see Lisp constructs. Perl is different as well, but it often looks similar enough to cause people concern before they know what they are really looking at.
As for this specific example, arrays evaluated in scalar context (as opposed to list context) return the number of elements in the array. There is no array length function or method, as it's superfluous. 0+@x is the number of items in @x, and 5 < @x tests whether @x has more than 5 items, since < imposes scalar context. There are many, many places in the language where context is used to simplify operations, this is just a very simplistic example, but it should illustrate why sigils are important, as they change how operations are evaluated.
Put simply, it's not possible to make a coherent criticism of Perl's use of sigils without understanding context and how it's used within the language, and factoring the benefits and drawbacks of that into your criticism. To criticize without this knowledge is to do so from ignorance (in the literal sense, not as an insult).
jnthn has a great series of blog posts illustrating how many of Perl 6's features come together to make developing a library very easy. To me, this is a great example of "how does Perl 6 help a business": by allowing rapid development of a complex asynchronous application, which is a use case many of us face. He illustrates this by writing a STOMP client for RabbitMQ, going from toy to a serious library: https://6guts.wordpress.com/2016/01/04/not-guts-but-6-part-1...
I look at this workflow and think, "Wow, I wish I could do things that easily." But now I can, because Perl 6 is out. :)
I say don't worry about the criticism and popular opinion: The specific language you use is pretty far down the list of problems that a given software might have. You'll build up some useful libraries in your niche and eventually other people will see that the most time-effective way to solve a problem in that niche is to use Perl 6 to get access your libraries.
Every other language I use derives from its specific purpose: Ruby because vendors like PayPal or AWS publish Ruby gems(and because of Rails); Haskell for writing parsers, interpreters, and compilers(ADTs and parsing monads); C if I'm trying to understand some code and need it to be portable or operationally simple; Perl 5 if it's a quick prototype script. Just the other week I needed a Bayesian variant of Prolog and would've used Perl 6 if it had a library for it.
The hatred P6 receives here reminds me a lot of the hatred Go used to receive, where every article posted devolved into a discussion regarding the lack of generics. I bought into the "Go is a regression" meme for a long time until I started using it to solve real problems at work, and now I love it.
I hope that we programmers can learn to rejoice in each other's creations rather than to heap scorn and criticism on anything not from our particular tribe. It reminds me of people who insist that you can only like a single video game console... heaven forbid you use more than one, or one with inferior graphics (but with more fun games!), etc.
I don't know if Perl programmers have been separated from the other scripting languages too much as not to understand that there are different mindsets out there.
Perl has always been quite a confusing language if you only skimmed it (lots of incoherent features and more than one way to do it), so I find it natural that Perl6 isn't any better.
But if you don't explain the confusing features of a language well enough, puzzlement and confusion is what you get.
My impression is rather that the P6 marketing has traditionally focused on presenting a long list of features instead of a user-focused business case.
If not us, then who? There is plenty of space for a language that delivers real innovation, or even one that puts real polish on old ideas. But when a language does neither, we absolutely should be asking what it's for. A community that prides itself on being pragmatic and delivering business value should know the costs of language proliferation.
Oh please. Perl 6 does both of these very nicely. Dismissing it out of hand as you have just done is exactly what the parent is complaining about.
Hackers or not, we're all still human, and experience emotions like frustration and disappointment. Back when perl6 was first being discussed (what was it, 15 years ago now?), probably a lot of us were getting a ton of mileage out of the remarkable perl5 ecosystem.
When perl6 started getting promoted, it seemed like it took a lot of the wind out of the perl5 sails, like an Osborne effect for a programming language.
When the years ticked by and nothing came of it, and lots of moved onto other languages, I imagine a lot of people still remembered being disappointed at how the perl5->6 situation played out.
Probably some of the negativity is just remnants of that, because, like I said, we're all still human.
And schadenfreude, I'm sure, plays into it, like when the overhyped disappointments Daikatana and Duke Nukem Forever were released...
Anyway, just one man's opinion, of course...
The trick of course is that then your libraries effectively define your language. There are various sweet-spots of native-language features, standard-lib features, and external libraries. I think it is a matter of taste and trade-offs.
Perl is still by and large the only language with that many amount of library options, the only other language I can think which rivals that is Java.
That said, it is still good practice to try to avoid dependencies on packages that are not maintained, or you might find yourself the de-facto maintainer of the package. This is true across all languages.
Perhaps one of the most enduring legacies of Perl is that no language that comes after it can be considered complete until it has its own CPAN like package management system. That and the regular expression engine of course.
In any case, the fact that the project wasn't abandoned after all that speaks for itself. It's here and the future was never brigher for it than it is now.
It might not prosper, but it will prevail.
Why should anybody have hopes for anything, they don't like.
>>It took 16(!) years to implement features other languages already have.
Like what? Have you even looked at the Perl 6 feature list?
>>And CPAN is the dark, sad pit of forgotten and abandoned packages.
Clearly you have no active involvement with the Perl community.
I haven't had much need of Perl recently; trying to force myself to switch to Python (a jarring psychological experience) not because I hate Perl but because Python seems to be where a lot of the demand is these days.
But I learned something else of great importance from this article: cowsay
I'd never heard of cowsay before but it's an amazing tool! I installed it on my SuSE workstation (sudo zypper install cowsay) and on my Mac (brew install cowsay) and it just makes me happy! My favorite command is:
ls|cowsay