Earlier quoted context omitted.
What made it click for me is the nature of scheme: a few, very well thought out abstractions, that compose well to build a really neat language. I never really made friends with other languages. Where scheme composes the primitives for problem solving, I find that languages like python or ruby provide either one way for each different thing, or a very large hammer for every problem you might find, be it list comprehe…
> a very large hammer for every problem you might find, be it list comprehensions or generators or whatever OO voodoo you can come up with. List comprehensions, to me, are what makes Python a productive (or the most productive) prototyping language. It allows me to think and program in mathematical relations without much fuss. Add to that nice sets and dicts (needed for asymptotic efficiency), and I can easily forgiv…
S = {x² : x in {0 ... 9}}
V = (1, 2, 4, 8, ..., 2¹²)
M = {x | x in S and x even}
Python (from that page) S = [x**2 for x in range(10)]
V = [2**i for i in range(13)]
M = [x for x in S if x % 2 == 0]
I did not see 10 or 13 in the original definitionsPerl 6 closest syntax to original
my \S = ($_² for 0 ... 9);
my \V = (1, 2, 4, 8 ... 2¹²); # almost identical
my \M = ($_ if $_ %% 2 for S);
Perl 6 closest syntax to Python my \S = [-> \x { x**2 } for ^10];
my \V = [-> \i { 2**i } for ^13];
my \M = [-> \x { x if x % 2 == 0 } for S];
Perl 6 more idiomatic my \S = (0..9)»²;
my \V = 1, 2, 4 ... 2¹²;
my \M = S.grep: * %% 2;
Perl 6 with infinite sequences my \S = (0..*).map: *²;
my \V = 1, 2, 4 ... *;
my \M = S.grep: * %% 2;
---Python
string = 'The quick brown fox jumps over the lazy dog'
words = string.split()
stuff = [[w.upper(), w.lower(), len(w)] for w in words]
Perl 6 my \string = 'The quick brown fox jumps over the lazy dog';
my \words = string.words;
my \stuff = [[.uc, .lc, .chars] for words]
I wouldn't say Python's list comprehensions are really that big of a selling point. I mean based on what I've seen to understand it the biggest difference is that feature in Python runs from the inside out. noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
range(2, 8)
for i in
range(i*2, 50, i)
for j in
j
[ ]
Whereas Perl 6 is either left-to-right my \noprimes = (2..^8).map: { |($^i*2, $i*3 ...^ 50).map: { $^j }}
(2..^8)
.map:
{ |($^i*2, $i*3 ...^ 50) }
.map:
{ $^j }
or right-to-left my \noprimes = ({ $^j } for ({ |($^i*2, $i*3 ...^ 50) } for 2..^8))
2..^8
for
{ |($^i*2, $i*3 ...^ 50) }
( )
for
{ $^j }
( )
Here are a couple other translations using Set operators primes = [x for x in range(2, 50) if x not in noprimes]
my \primes = (2..^50).grep: * ∉ noprimes;
my \prime-set = 2..^50 (-) noprimes; # a Set object
my \primes = prime-set.keys.sort;
Also I'm fairly certain Python doesn't have a way of using them on a Supply concurrently. # create a prime supply and act on it in the background
Supply.interval(1).grep(*.is-prime).act: &say;
say 'main thread still running';
# says 'main thread still running' immediately
# deadlock main thread,
# otherwise the program would terminate
await Promise.new;
# waits 2 seconds from the .act call, says 2
# waits 1 second , says 3
# waits 2 seconds, says 5
# waits 2 seconds, says 7
# waits 4 seconds, says 11
# and so on until it is terminated
Basically the only selling point of that feature in Python over say Perl6 is that is at times a bit closer to what a mathematician would normally write.I'm not a mathematician.
To me it seems a bit verbose and clunky. It probably also only works as a single line, which seems odd in a line oriented programming language. Basically it seems like a little DSL for list generation, sort of like Perl's regexes are a DSL for string operations.
Perhaps you may want to reread the last paragraph from the original article. Maybe in a few years the world will have passed you by. Then again maybe not.