jlarocco 1 day ago

Coming from Common Lisp, I find both versions are pretty hard to read, and I find Clojure in general difficult to grok. Every example of Clojure I see looks like the author is "code golfing". Why the instistence on such terse, cryptic identifiers? Every other Lisp, going back to the 60s, uses readable text names, and it just baffles me that Clojure decided to go a different way.

The sentence generator in my Markov text generator CL package looked like this:

    (defun generate-random-sentence (mtab &key (first (random-elt (first-words mtab))))
      (with-slots (prob-table) mtab
        (format nil "~{~a~^ ~}"
                (loop 
                  :for next-word = first
                  :then (pick-random-word (gethash next-word prob-table))
                  :while next-word
                  :collecting next-word
                  :until (ends-with-end-sentence-punctuation-p next-word)))))

3
funcDropShadow 1 day ago

You mean such readable and understandable names like car, cdr, cadr, .... ? For the uninitiated, car is not about vehicles.

jlarocco 1 day ago

But you can use `first`, `rest`, etc. in new code. CL and Scheme are stuck with the old names for backward compatibility reasons going back over 60 years.

Clojure had a chance to do better because they were starting a new thing.

It's not necessarily a flaw with the language, in any case, just something I've noticed in Clojure articles.

I suppose I'm agreeing with the author - refactoring Clojure to make it more readable is a good idea.

iLemming 23 hours ago

> Clojure had a chance to do better because they were starting a new thing.

And it did. The seq abstraction is way more practical than the old-school list obsession in other Lisps. You get to treat collections uniformly while keeping the performance benefits of each implementation. Pretty smart move, honestly.

actuallyalys 1 day ago

In my experience, short identifiers in Clojure tend to be pretty standard things, e.g., f for a function, coll for a collection. Certainly this article has some pretty cryptic examples, but the author agrees with you and me and ends up fixing them.

iLemming 23 hours ago

> short identifiers in Clojure tend to be pretty standard things

No it's not. There's no style-guide rule, or PEPx, or core team recommendation to use short or long names. Clojurists are pragmatists to the core — they use whatever makes sense in the context. If `m` and `f` feels like a reasonable choice instead of `map` and `function` — that's how they'd name the vars, but it's not a universal rule.

Clojure's syntax (and Lisp's in general) is very flexible, you may encounter names like `bar->foo` — for transforming, or `bar+foo` — for data combining functions. For uninitiated these kind of names may look cryptic — when you encounter a function name like that for the first time, you'd think it's some kind of special language construct. Matter of fact, because Lisp syntax is so minimal, the overhead of learning mental parsing of the code is also (relatively) small. No one after a few months of writing Clojure conceives it as a atypically "cryptic language", but of course, there are programmers capable of writing cryptic code in any language, no matter how generally terse or verbose it is.

actuallyalys 20 hours ago

I probably shouldn’t have said “standard,” but in my experience, they do (usually!) follow certain conventions. They’re not formal conventions, sure, but they are conventions.

iLemming 1 day ago

> it just baffles me that Clojure decided to go a different way.

Have you scrolled to the end, or you're judging by the initial examples in the code, because author did use more sensible names in the refactored example.

But if I'd have to re-write your CL snippet in Clojure, perhaps it would look something like this (I don't know if that actually works, haven't tested it):

    (defn generate-random-sentence 
      ([mtab] (generate-random-sentence mtab (rand-nth (:first-words mtab))))
      ([mtab first-word]
       (->> (iterate #(pick-random-word (get (:prob-table mtab) %)) first-word)
            (take-while some?)
            (partition-by ends-with-end-sentence-punctuation?)
            (take 2)
            (apply concat)
            (clojure.string/join " "))))
             
I don't know why would anyone find it more (or less) readable. IMO Clojure version is a bit more functional, data-transformation oriented, while CL Loop gives you explicit control flow, there's memory efficiency, it's a single-pass processing, etc. At the end of the day, it all boils down to familiarity; you dislike Clojure maybe due to lack of exposure, yet it's not a bad Lisp, it really does shine in some areas and definitely it is a simpler Lisp than CL or even Elisp - the complexity of the loop macro alone is like learning another PL, yet for someone who knows it already it may feel easier to use.