119 karma · joined January 20, 2010
http://masak.org/carl http://strangelyconsistent.org/ https://github.com/masak/bel
Here's the thing: I like Perl 6 because of the abstractions it gives me. In fact, I like learning new programming languages because of what I learn about ways of slicing the solution space. It's like learning new spoken languages, only easier. I spend the time I could spend complaining about some unknown language's syntax learning that language, trying to enrich my repertoire as a programmer.
my @fib := ...;
Bind something to an array variable. Assignment tends to follow infinite lists into the abyss. (But would also work, in this case, since the list is lazily evaluated.) 1, 2, *+* ...^ * >= 100;
This is all governed by the `...^` in the middle, which is a lazy list generator. Three components, the seed, the iteration and the end condition, surround it. (Those three are much like a C `for` loop, come to think of it.)The seed is simply `1, 2`.
The iteration is star-plus-star (which I can't figure out how to write out explicitly in this markup). This is ultimately syntactic sugar for a lambda with two parameters: `-> $a, $b { $a + $b }`. Or, put differently, this is a curried addition function.
The end condition is `* >= 100`. Also curried; we could desugar it as either `-> $c { $c >= 100 }` or simply `{ $_ >= 100}`. It's a block that takes one argument and checks whether it's 100 or greater.
The sequence operator `...^` has a little hat on it, meaning we're to discard the item that eventually matches the end condition. This is congruent with the fact that there is a range operator `..^` (note: two dots) which excludes its right endpoint.
For this particular change though, I think you will meet a bit of resistance. Many people might agree that the feature is goofy, but few will probably agree that it's bad and should be gotten rid of.
Some of those (such as testing culture) are mirrored in other languages' cultures, others (such as CPAN) are unparalleled in scope. Ignoring Perl 5 based on a single feature causes you to miss out on all the truly good parts.
No, the reason for the word 'flip' being used is not due to a bizzarre Perl idiosyncrasy about context-based evaluation -- quite the opposite. Note that the change to using 'flip' is in Perl 6 only (this is not one of those changes that newer versions of Perl 5 has adapted; nor, I suspect, will it ever). Perl 6 does not do the context-base idiosyncrasy thing, and the resulting consistency quite naturally led to the two concepts being separated.
Sure, we could still call both the list operation and the string operation the same thing ('reverse', say), but that would lead to unfavourable corner cases and breakage of the rule of Least Surprise. ("Hey, why does it write my list of one string backwards?")
So, after Perl 6 has removed a function being polymorphic based on list/scalar context, and then removed nasty corner cases, your objection that this is not how "every language from Javascript to Haskell" does it might still be valid, but it might not weigh as heavily against the gain in consistency.
But even regardless of the HN guidelines, I am curious: why does tptacek consider 'flip' to be a dumb name? And why does he consider the sentence he quotes to be 'even worse'? Opinions are easy to produce en masse; what's interesting to me is the reasoning or motivation behind them.
It's funny. I just registered on HN, and on my way in I took the time to read http://ycombinator.com/newswelcome.html where the expectations on comments are outlined:
"What we especially discourage are comments that are empty and negative—comments that are mere name-calling."
Do you wish to make your negative comment about 'flip' less empty? Or have you expended your fount of criticism already?
There is actually a class in Perl 6, called Buf, for when you want to talk about a sequence of bytes rather than a sequence of characters/graphemes. Buf is array-indexable; in fact it works a little like a string a little like an array. It's there to make it harder to screw encodings up. See http://use.perl.org/~masak/journal/39236 for how.
"Strangely enough, nothing happened when clicking the 'flip!' link... a moment's reflection gave the cause of this: a few days ago, [Larry Wall] has syntactically separated reversal of List (.reverse) from the reversal of Str (.flip); my code was like three weeks old and was still using .reverse for strings, which in the newest Rakudo got interpreted as one-elem lists, and list-reversed with no visible effect whatsoever. I fixed that, and found the fact that the link in the Lobster app was already called 'flip' an indication of the appropriateness of the name change. Perl 6 just keeps getting nicer and nicer."
The relevant piece of background is that I was porting the example application (Lobster) from the Rack framework, where the link was already called 'flip'. So, suddenly both the link and the method were called 'flip'.
As a simple example, which you'll find in various languages, not just Perl: brackets ('[ ]') construct list objects when standing alone, but when they occur after something, they do array indexing into that thing. This all falls out naturally, and humans are very well equipped at switching between this type of contexts.
The Perl 5 behaviour of overloading 'reverse' with double meaning could be said to be context-dependent in this way. But the flip/reverse/invert distinction goes in the other direction, saying "hey, maybe we do want to keep these three concepts separate rather than crowding them all into the same method".
A similar thing has happened with 'length'. In Perl 5, 'length' always meant 'number of characters in the supplied string', but newbies kept expecting the function to work for lists too. It doesn't. In Perl 6, there's a method '.elems' for lists and '.chars' for strings. Neither of them are accessible as 'length'.
In a lot of places where Perl 5 overloads words and depends on context for the right semantics, Perl 6 strives to make things consistent and eliminate mental lists of things you have to remember.
In Perl 5, 'reverse' did all of the three things: it reversed strings (in scalar context), or lists/hashes (in list context). The latter two weren't really distinguished, since a hash in Perl 5 is just an (even-element) list that you assign to a hash variable.
In Perl 6, 'wantarray' http://perldoc.perl.org/functions/wantarray.html is gone, and not even built-in methods rely on figuring out the void/scalar/list context of the caller. Which means that we don't do the trick described in the blog post to make 'reverse' do either string or list reversal.
Very well, no problem. What we lack in 'wantarray' we make up with a type system. We just stick the string-reversing 'reverse' method on the type Str, and the list-reversing one on the type List. All good and well. (In fact, we put the string-reversing one on Any, and let it coerce to Str when needed.)
But wait. There are some corner cases where this causes problems. Sometimes a scalar variable contains a list of things, and sometimes a list contains but one element. In either case, we try to magically guess between the two uses, and get it wrong. So maybe making those two behaviours homonyms wasn't too good an idea after all.
Hence the need for distinguishing 'flip' and 'reverse'. By distinguishing 'invert', we can make it a bit smarter in case of hash key collisions. The 'magical guessing' dilemma goes away, because it's clear you mean a list when you say 'reverse' and a string when you say 'flip'.
The names are fairly well-chosen, considering what they do. You flip a single thing (string), reverse the order of a sequence of elements (list), and invert a mathematical mapping (hash).