http://freegeek.in/blog/2011/06/10-clojure-one-liners/
Tell me that is not Perl all over again.
http://freegeek.in/blog/2011/06/10-clojure-one-liners/
Tell me that is not Perl all over again.
The Perl one-liners that actually resemble line-noise get far more done than any of the examples given above. Perl one-liners that do the same as the above examples are actually quite legible.
use List::Util qw(sum max min);
# 1
map { $_ * 2 } 1..10;
# 2
sum 1..1000;
# 3
my @wordlist = ("scala", "akka", "play framework", "sbt", "typesafe");
my $tweet = "This is an example tweet talking about scala and sbt.";
grep { $tweet =~ m/\b$_\b/ } @wordlist;
# 4
my $file_text = do { local $/ = undef; open my $fh, '<', 'data.txt'; <$fh> };
chomp( my @file_lines = do { open my $fh, '<', 'data.txt'; <$fh> } );
# 5
say "Happy Birthday " . ($_ == 3 ? "dear Barry" : "to You") for 1..4;
# 6
my ($passed, $failed) = do {
my @p; \@p, [map { $_ > 60 ? push(@p, $_) && () : $_ } (49,58,76,82,88,90)]
};
# 8
min(14, 35, -7, 46, 98);
max(14, 35, -7, 46, 98); my $file_text = do { local $/ = undef; open my $fh, '<', 'data.txt'; <$fh> };
I have absolutely no idea what this line does. local? undef? '<'?, <$fh>? This is how you read a file in Perl?Nope. I use Path::Class from CPAN...
use Path::Class 'file';
my $file_text = file('data.txt')->slurp;If you don't know Perl, why should you expect to? I didn't know that #(...) represented a lambda in Scala until a moment ago.
Yes, lots of tutorials explain it badly, and yes, lots of people say "Why should a programming language take cues from natural language?", but implicit variables and context are concepts that primary school children have mastered. They're not that difficult.
Seriously, in what other language don't you ever finish discovering what's on the default namespace, what side-effects any given statement, or hell, expression has, or which syntactic forms are supported, and on and on?
Well, PHP, but we know what the connotations of that are.
And by the way, I'm doing rather 'fine' in Perl, if not for the ever-present worrying about type mismatches (particularly arrays), the frustration of how dirty many operations are (unless you are using a recent version, regex substitution must mutate a variable), the laboriousness of the stock error handling mechanisms (make your own stack trace!) and so on.
Those are neither line-noise, nor fickle one-line imperative solutions.
On the contrary, they are elegant and easy to read --you just have to understand the basics of functional programming, map, reduce, filter and the like (which, in themselves are trivial concepts).
Stuff like those in the article:
(pmap process-line lines)
(dotimes [n 4] (println "Happy Birthday " (if (= n 2) "dear Rich" "to You")))
(reduce max [14 35 -7 46 98])
(def file-text (slurp "data.txt"))
(partition-by #(> % 60) [49 58 76 82 88 90])
(clojure.xml/parse "http://search.twitter.com/search.atom?&q=clojure)
are so easy and clutter-free that what I cannot even begin to comprehend how someone would accuse them of the bad readability that characterises the "Perl one-liner".
(partition-by #(> % 60) [49 58 76 82 88 90])
to so-called line noise code seems reasonable enough. As with Perl, if you immediately know what all the punctuation means and what the underlying structure of the language is, it’s concise, but if you don’t, it’s quite a mess of random-looking symbols.For comparison, here’s a Haskell version, which in this case has a more intuitive syntax, IMHO:
filter (>60) [49, 58, 76, 82, 88, 90]
And here’s a version in Scala, with a more explicit function value: List(49, 58, 76, 82, 88, 90).filter(n => n > 60)The Haskell version doesn't actually do the same thing. The Haskell returns [76, 82, 88, 90]; the Clojure returns ((49 58) (76 82 88 90))---it groups the input according to the result of the function, it doesn't just filter it.
In any case, my point here was about syntax, so I used a standard and easily recognisable function in the other languages instead of getting bogged down in trying to reproduce the exact same behaviour. Apologies if this wasn’t clear.
Yeah, a less noisy way to do it in Clojure would be
(partition-by (partial < 60) [49 58 76 82 88 90])
in Perl:
grep { $_ > 60 } ( 49, 58, 76, 82, 88, 90)
Sorry, hate is such a strong word.
I mean that I still find the language's typographic irregularities hopelessly distracting to the point where I won't touch it with a bargepole.
They compare to perl one liners more than they do to Lisp one-liners due to their greater syntactic cruft.
FYI, the square brackets are not an arbitrary deviation from lisp syntax. Square brackets are Clojure's vector syntax, the use of square brackets in function and macro definitions reflects the fact that they are actually vectors.
Not sure what you meant with your objection to slashes though.