Live data from Hacker News

Learning Clojure: comparing with Java streams

blog.frankel.ch

11–20 of 46 posts

Re: Learning Clojure: comparing with Java streams

#11
post #9

> and Clojure’s syntax is pretty limited Erm, what? I am confused by the use of the word 'limited' in this context.

I confirm: the syntax is limited. There are only a few keywords and langage constructs. The power is in the number of functions made available, or the ones you create for yourself.

Doesn't Clojure have reader macros? The whole point of lisps is that you can extend them.

Re: Learning Clojure: comparing with Java streams

#12
post #9

Earlier quoted context omitted.

I confirm: the syntax is limited. There are only a few keywords and langage constructs. The power is in the number of functions made available, or the ones you create for yourself.

Doesn't Clojure have reader macros? The whole point of lisps is that you can extend them.

When I worked with Clojure the community seemed to treat macros as a nuclear option. Only use them when absolutely necessary. For some, this translated to “you can’t hug your children with nuclear arms”. If the community hasn’t changed, perhaps macros out of favor.

Re: Learning Clojure: comparing with Java streams

#13
post #7

The equivalent of `flatMap` is not `flatten`. Semantically `flatMap` is equivalent to `(comp flatten map)` – hence the name! – but Clojure does offer it as a single function named `mapcat` (”map and catenate”).

> Semantically `flatMap` is equivalent to `(comp flatten map)`

With the caveat that `flatten` is recursive and can handle a mix of collections and non-collections, while `mapcat` is non-recursive and every value returned by the mapcatted function must be a collection or nil.

(Identity returns its argument.)

    (flatten [1 [2 3] [[4 5 6]]])
    > [1 2 3 4 5 6]

    (mapcat identity [1 [2 3] [[4 5 6]]])
    > IllegalArgumentException Don't know how to create ISeq from: java.lang.Long

    (mapcat identity [[1] [2 3] [[4 5 6]]])
    > (1 2 3 [4 5 6])

    (flatten [nil [1 2 3]])
    > (nil 1 2 3)

    (mapcat identity [nil [1 2 3]])
    > (1 2 3)

Re: Learning Clojure: comparing with Java streams

#14
post #7

The equivalent of `flatMap` is not `flatten`. Semantically `flatMap` is equivalent to `(comp flatten map)` – hence the name! – but Clojure does offer it as a single function named `mapcat` (”map and catenate”).

Flatten is a steam-roller and should be used wisely: it recursively flatten a sequential collection. Most of the time this is not what you want. Most of the rest of the time when you think that’s what you want it’s a code smell telling you that the shape of your items has gone out of control. And there’s the rare occurrence where you can really use it.

Re: Learning Clojure: comparing with Java streams

#15
post #9

Earlier quoted context omitted.

I confirm: the syntax is limited. There are only a few keywords and langage constructs. The power is in the number of functions made available, or the ones you create for yourself.

Doesn't Clojure have reader macros? The whole point of lisps is that you can extend them.

Actually, Clojure does not have reader macros, because it was thought to be the biggest cause of the lisp curse.

Re: Learning Clojure: comparing with Java streams

#16
post #15

Earlier quoted context omitted.

Doesn't Clojure have reader macros? The whole point of lisps is that you can extend them.

Actually, Clojure does not have reader macros, because it was thought to be the biggest cause of the lisp curse.

Nit: Clojure does not have user-defined reader macros. There are quite a few built-in reader macros, including #? added for reader conditionals.

Re: Learning Clojure: comparing with Java streams

#18

> and Clojure’s syntax is pretty limited Erm, what? I am confused by the use of the word 'limited' in this context.

I believe they mean "limited in a good way", as in it doesn't have a bunch of unnecessary syntax that increases the number of characters entered, but does not add value to the language.

No pun intended, by "value" I mean "things that are worthwhile". Clojure is totally into "values". :-D

Re: Learning Clojure: comparing with Java streams

#19
post #10

Also, this bit: (->> justice-league (map #(:vehicles %)) (filter #(not (nil? %))) (flatten)) can be simplified to just `(mapcat :vehicles justice-league)`

A few notes on why this is so:

- Keywords (i.e. `:vehicles`) can be used as getter functions, as covered in the OP.

- mapcat (like most collection functions in clojure) treats `nil` as an empty sequence

Re: Learning Clojure: comparing with Java streams

#20
post #16
post #15

Earlier quoted context omitted.

Actually, Clojure does not have reader macros, because it was thought to be the biggest cause of the lisp curse.

Nit: Clojure does not have user-defined reader macros. There are quite a few built-in reader macros, including #? added for reader conditionals.

By this definition of terms, every Lisp dialect that ever existed had reader macros because it accumulated characters into tokens, and dispatched a recursive scan upon encountering (.
Post reply on HN