Hi Ken,
Thanks again. However, I still have one nagging gap in understanding this macro.
If I replace
(defmacro time-limited [ms & body]
`(let [f# (future ~@body)]
(. get f# ~ms java.util.concurrent.TimeUnit/MILLISECONDS)))
which expands to:
(macroexpand-1 '(time-limited 1000 (println "Hello")))
(clojure.core/let [f__1760__auto__ (clojure.core/future (println "Hello"))]
(.get f__1760__auto__ 1000 java.util.concurrent.TimeUnit/MILLISECONDS))
with:
(defmacro time-limited-2 [ms & body]
`(let [f (future ~@body)]
(. get f ~ms java.util.concurrent.TimeUnit/MILLISECONDS)))
which expands to:
(macroexpand-1 '(time-limited-2 1000 (println "Hello")))
(clojure.core/let [user/f (clojure.core/future (println "Hello"))] (.get user/f
1000 java.util.concurrent.TimeUnit/MILLISECONDS))
So far so good. Now time-limited-2 bombs out with the following exception:
Can't let qualified name: user/f
[Thrown class java.lang.Exception]
Why is that?
>>
>> (defmacro time-limited [ms & body]
>> `(let [f# (future ~@body)]
>> (. get f# ~ms java.util.concurrent.TimeUnit/MILLISECONDS)))
>>
>> If I do a (macroexpand '(time-limited 100 (println "Hello World"))) it
>> expands to:
>> (let* [f__1760__auto__ (clojure.core/future (println "Hello"))] (.get
>> f__1760__auto__ 100 java.util.concurrent.TimeUnit/MILLISECONDS))
>>
>> My questions are:
>> 1) Where does the let* come from?!?
>
> The clojure.core/let is a macro that expands into let*, which is the
> true special form and doesn't do destructuring.
>
> Use macroexpand-1 instead of macroexpand to avoid that cruft.
>
>> 2) Why does f need to be a auto generated variable? Wouldn't (let* [f
>> (clojure.core/future (println "Hello"))] (.get f 100
>> java.util.concurrent.TimeUnit/MILLISECONDS)) suffice?
>
> It would crap out if you did something like:
>
> (let [f (my-thingie)]
> (time-limited 1000
> (adjust-thingie f)))
>
> Specifically adjust-thingie would throw a ClassCastException
> resembling this one:
>
> #<CompilerException java.lang.ClassCastException:
> clojure.core$future_call$reify__5500 cannot be cast to
> java.lang.Number (foo.clj:112)>
>
> It would probably not be very obvious why that was happening, either.
>
>> 3) What's .get ??
>
> A Java method call on the future object.
>
> user=> (parents (type (future 17)))
> #{java.util.concurrent.Future
> clojure.lang.IDeref
> clojure.lang.IObj
> java.lang.Object}
>
> A Clojure future is just a Java future with a couple of Clojure
> interfaces slapped on to allow @foo and metadata to be used with it.
>
> @foo and (deref foo) don't let you specify a timeout, though; the Java
> Future.get() method does.
>
> --
> 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
--
“There is a strong correlation between being smart and being a nerd, and an
even stronger inverse correlation between being a nerd and being popular”
(Paul Graham)
--
**********************************************************
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772 Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: [email protected]
************www.leica-geosystems.com*************
when it has to be right, Leica Geosystems
Please consider the environment before printing this email.
--
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