Recently I discovered my old blog on Blogspot with an article about oneliners in Python written far in 2010:

It’s not so crazy as it could be with perl, but still weird with a little of functional magic:

to get the recurcive list of full-path-names under working directory:

import os; print map(lambda x: os.sep.join(x),
reduce(lambda x,y: x+y, map(lambda x: zip(*x),
[((l[0],)*len(l[2]),l[2]) for l in os.walk(os.getcwd())])))

That makes me smile now if I think about Clojure as you always can drop “\n” from code and get a valid oneliner.

I also wonder how much ideomatic becomes same program:

(use '[])
(map #(.getAbsolutePath %) (rest (file-seq (file (System/getProperty "user.dir")))))

Thats ok, moreover it returns a LazySeq and will work well with very large filestructures.

But there is a thing that bothers me - both programs do violence to your brain, because they force you to read it right-to-left, from inside os.walk / file-seq to outside. Readability matters. Unless you’re doing perl :)

And wonders happen: there is a way to cure clojure version using thread-last

(->> (System/getProperty "user.dir") file file-seq rest (map #(.getAbsolutePath %)))

Still a LazySeq but it reads much better:

  • get cwd
  • turn it to an instance
  • walk a tree
  • exclude first element (cwd itself)
  • and apply some function

I don’t know how to recover a python version remaining functional. Just do your usual way with assigning variables and operate on them. Probably, it’s not worth trying to stay with the functional paradigm in Python, as the example above seems to be a violence to the programming language, Python isn’t born with this idea.

P.S. perl programmers may be offended by the joke above, so I apologize: RosettaCode says there is a concise way to achive the goal in Perl6:

use File::Find;
.say for find(dir => '.');

Moreover, clojure version is nice but I won’t use it as oneliner, not because of JVM startup time, but just not to do violence - in shell I would use find and pipes :)