# Lazy list of Fibonacci numbers up to (but excluding) 100:
my @fib := 1, 2, *+* ...^ * >= 100; # Lazy list of Fibonacci numbers up to (but excluding) 100:
my @fib := 1, 2, *+* ...^ * >= 100;Still you are perfectly free to not learn Perl6 nor Chinese :-)
Here, you get a mash of so many concepts in one line that it's hard to claim any readability really... From the start, you get list (@), one of 3 possible assignments (:=), separators and operators at different levels (, , ...^, (star), >=), math symbols in two different contexts (+, (star)), meaningful position in a list (seed, seed, function). On top of that, to read it without parens you have to keep all operator priorities in mind.
Readable? I have a hard time finding one (apart from J, K, APL, etc. family and silly ones) that is less readable than this sample. The "looks like Chinese" comparison is really apt - Chinese takes considerably more effort to learn than many other languages.
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.
Interesting. With modern Perl use (autodie, testing, Best Practices, etc)?
Are you trolling or do you have a few specific examples of what makes you lose more work weeks a year than CPAN saves you?
Also, what would be worse with Perl 6 -- that you can say already now (or do you have Rakudo in production)?
So yes - of course you can write the best modern Perl and live happily. In practice I have to mess with old code and tricky things left by people saying "Perl is not that bad once you know more of it" - really, it's just setting up someone less experienced for failure. And you can be sure that there will be someone less experienced working on your code (while you're not available for any review). I prefer more explicit code, stopping completely before you do something that might not be exactly what you want.
Re. Perl 6 - it brings in more new syntax, more operators, more different ways to do things, more unknown problems and less people who know it well enough to use it properly. I really don't see the reason to play with it now.
I really don't want this to look like trolling, so I'm not even advocating languages I prefer. You may not agree with me, but this is just something I experienced for the last 3 or so years - those simple problems occur over and over again.
Well, I've had similar problems with others' code in other languages. (Unicode problems are hardly Perl specific. 3rd party libraries will always have different problems. '='/'==', etc.)
What you are really saying is that expressibility is bad?
Cargo cult programmers might get more problems in expressible languages. But these languages are arguably more capable tools for competent programmers. (Moose is the standard example this day -- the OO subsystem ripped out of Perl 5 and replaced with something like Perl 6/Common Lisp.)
I like Perl because of the nice, smart and laid back community -- and because Perl is fun. This makes me motivated. The main disadvantage is the learning curve. (-: Well, and the trolling from the competition... :-)
Almost the opposite, actually. I quite like Haskell and Scala, which can be extremely expressive (no dynamically modifiable parsers though ;) ) - but at the same time the area where you can make a mistake is minimal compared to Perl programs. Things where Perl will leave you a warning (which might get lost in other output), simply won't compile in others (for example ==/eq "problem"). On the other hand you don't need the type annotations for majority of code, so it doesn't induce the verbosity you'd get in Java or others.
It all goes back to the preference in the end ;)
Anyone that ignores warning messages will suffer. :-)
Note that Perl 6 is a scripting language which can declare types.
The '=='/'eq' thing is common among scripting languages. It is a detail, you find things like this in all complex packages of rules.
Most scripting languages will get (some) problems with typing, especially in function parameters for the external APIs in libraries. If you use strict, you get away from some classical problems, e.g. variable name misspellings.
With Moose (or other CPAN stuff), you can have powerful typing handling etc.
>>It all goes back to the preference in the end ;)
Let me note -- that is not where you started a few comments ago. :-)
Argh - I have to learn to stop in a good time ;) Actually what I meant is that even if though I really believe in what I wrote above, if I had 10 people skilled in Perl feeling more comfortable with Perl than anything else... it might be a better choice. Should've actually said that experience decides in the end... but let's just stop here already :)
I am pretty sure they are not exactly as easy, but I have no idea which is easier! That's an interesting question though; do you know of any studies on that subject?
The analogy is halting because he used natural languages -- he probably didn't want to insult you by explaining curried functions and CS... :-)
And yes, I needed masak's explanation, too. The Pascal ":=" brings back happy memories of childhood...
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.
The ..^ operator (including the right endpoint?) doesn't do what I was expecting:
> 1, 2, * + * ..^ * >= 100;
1 2 _block298
Also, this seems a little unfortunate: > 1, * + * ...^ * >= 100;
===SORRY!===
Method 'Bridge' not found for invocant of class 'Failure'
(I was expecting some warning about the closure expecting two arguments, and only getting one.) from itertools import islice
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
for k in islice(fib(), 1, 100):
print(k)
It uses a generator function to produce an infinite iterable sequence. islice() is used to produce just a slice of that sequence.This could probably be written using fewer characters, but I don't think it could be anywhere near a short (and terse) as the Perl version.
def fib(max):
a, b = 0, 1
while a < max:
yield a
a, b = b, a + b
for k in fib(100):
print(k) takeWhile (< 100) fibs
where fibs = 0 : 1 : zipWith (+) fibs $ tail fibs
I don't think fibs can be expressed as a list comprehension in haskell, can it? It's cute that perl6 is able to use one, but OTOH I can't think of
many other lists I'd want to use that trick to calculate.And, despite having written perl for 15 years, I find the haskell version much clearer, and its use of laziness and infinite lists (zipping them up in particular) much more advanced than perl6's.