What happened here?
user=> (take 20 (interpose '.' "The quick brown fox"))
(\T . \h . \e . \space . \q . \u . \i . \c . \k . \space .)
Naturally, I meant to use a character literal as the first argument to
interpose, but my C / Java habits led me to use the apostrophes instead
of the proper character literal notation.
Is it a reader bug? (That the second apostrophe appeared to be ignored.)
Randall Schulz
Is it a reader bug? (That the second apostrophe appeared to be ignored.)
Right. My residual preconceptions continued to keep me from seeing what
really happened.
Thanks.
RRS
Yeah, Robert made me see that.
> I've been interested in a way to see what the reader returns for
> things like this in the past.
>
> It turns out we can get that using macroexpand:
>
> user=> (prn (macroexpand '(interpose '.' "The quick brown fox")))
> (interpose (quote .) (quote "The quick brown fox"))
>
> (I hadn't thought of macroexpand expanding reader macros as well as
> non-reader macros, but that's the effect here.)
I think the reader is doing "expanding" on reader macros. Macro-expand
is just nilpotent when no macros are in play.
In this case, it's no different than just printing the list you passed
to macroexpand:
user=> '(interpose '.' "The quick brown fox")
(interpose (quote .) (quote "The quick brown fox"))
It's a good technique, though, to see what the compiler is going to be
asked to translate after all players between the form as submitted and
the compiler have done their thing.
> --Steve
Randall Schulz
In this case, it's no different than just printing the list you passed
to macroexpand:
user=> '(interpose '.' "The quick brown fox")
(interpose (quote .) (quote "The quick brown fox"))
It's a good technique, though, to see what the compiler is going to be
asked to translate after all players between the form as submitted and
the compiler have done their thing.
Or is it?
Can you tell what a newbie I am? I'm working my way through Stuart H.'s
book. I'm on the sequence section (4.2) and just got to "for". Here's
what I did / found:
user=> (doc for)
-------------------------
clojure.core/for
([seq-exprs expr])
Macro
List comprehension. ...
(take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))
nil
So seeing that "for" is a macro, I thought I'd see what it produces. I
started with the example included in the doc string:
user=> (macroexpand '(take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y])))
(take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))
So next I tried macroexpand -ing just the (for ...) sub-form:
user=> (macroexpand '(for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))
(let* [iter__3869 (clojure.core/fn iter__33
[s__34] (clojure.core/when-first [x s__34] (if true
(clojure.core/let [iterys__3867 (clojure.core/fn iter__35
[s__36] (clojure.core/when-first [y s__36] (if (< y x)
(clojure.core/lazy-cons [x y] (iter__35 (clojure.core/rest s__36)))
nil))) fs__3868 (iterys__3867 (range 1000000))] (if fs__3868
(clojure.core/lazy-cat fs__3868 (iter__33 (clojure.core/rest
s__34))) (recur (clojure.core/rest s__34)))) nil)))] (iter__3869
(range 100000000)))
I'm somewhat confused by this, but I gather it has something to do
with "take" being lazy?
> > --Steve
Randall Schulz
And, continuing my exploration, the confirmation of this hunch comes
shortly after, in section 4.3.
This does, at least, impose a caveat on the use of macroexpand as a tool
for understanding what your code really says (and does).
Randall Schulz
I'm somewhat confused by this, but I gather it has something to do
with "take" being lazy?
OK. So it's not the laziness of "take," but rather the nature of
macroexpand.
Thanks for the reference. I'll review that post.
> --Steve
Randall Schulz