Martin Coxall <[email protected]> writes:
> I might try to knock up "optional parens inference for Clojure" and
> add in some manner of curly infix as an exercise. It doesn't look like
> it will be too hard. Since {} is taken for literal maps, I'd need
> something else for curly infix. [|...|], %...%, $...$?
Let's just try a few example functions from contrib.
(defn subset?
"Is set1 a subset of set2?"
[set1 set2]
(and (<= (count set1) (count set2))
(every? set2 set1)))
Drop the outer parens.
defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and (<= (count set1) (count set2))
(every? set2 set1)
Lets break after "and" so we can drop some more parens.
defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and
<= (count set1) (count set2)
every? set2 set1
Now lets introduce infix with say, |...|.
defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and
|(count set1) <= (count set2)|
every? set2 set1
Maybe they need spaces?
defn subset?
"Is set1 a subset of set2?"
[set1 set2]
and
| (count set1) <= (count set2) |
every? set2 set1
Has that suddenly made things more readable? Maybe. I don't know. It
certainly felt really weird writing it. That "and" by itself does
remind me of Haskell. The code is definitely looking very tree-like
now, maybe that's a good thing? My eyes *are* jumping to the "words"
easier and it's definitely less noisy.
Yet, this no longer obviously looks like a list. Is that bad? I don't
know. Do we need to be constantly reminded our code has a list
representation? Does it make macros harder to think about?
Lets try some more examples. How about arity overloading?
defn reductions
"Returns a lazy seq of the intermediate values of the reduction (as
per reduce) of coll by f, starting with init."
[f coll]
if (seq coll)
rec-seq self (cons (first coll) (map f self (rest coll)))
cons (f) nil
[f init coll]
rec-seq self (cons init (map f self coll))
Or a macro?
defmacro rec-seq
"Similar to lazy-seq but binds the resulting seq to the supplied
binding-name, allowing for recursive expressions."
[binding-name & body]
`let [s# (atom nil)]
reset! s# (lazy-seq (let [~binding-name @s#] ~...@body))
It becomes weirdly tempting to insert more line breaks just to get rid
of the rest of the parens.
defmacro rec-seq
"Similar to lazy-seq but binds the resulting seq to the supplied
binding-name, allowing for recursive expressions."
[binding-name & body]
`let [s# (atom nil)]
reset! s#
lazy-seq
let [~binding-name @s#] ~...@body
Hmm. Have we solved anything? Will this just make the complaints go
(from (too (many (parens))))
to
too
many
nesting
levels?
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en