definline example?

269 views
Skip to first unread message

Anand Patil

unread,
Jan 25, 2009, 7:06:45 AM1/25/09
to Clojure
Hi all,

I'd like to repeat my request for an example of definline usage; I
feel I've tried everything.

user=> (definline f [x] x)
java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:1)
user=> (definline [x] x)
java.lang.NullPointerException (NO_SOURCE_FILE:2)
user=> (definline (f [x] x))
java.lang.NullPointerException (NO_SOURCE_FILE:3)
user=> (definline (defmacro f [x] x))
java.lang.NullPointerException (NO_SOURCE_FILE:4)
user=> (definline f)
java.lang.NullPointerException (NO_SOURCE_FILE:12)

Thanks,
Anand

Timothy Pratley

unread,
Jan 25, 2009, 7:47:27 AM1/25/09
to Clojure
Hi Anand,

Here is an example from core.clj:
(definline doubles
"Casts to double[]"
[xs] `(. clojure.lang.Numbers doubles ~xs))

As you can see it is using macro magic as you would expect for in-
lining.


Regards,
Tim.


On Jan 25, 11:06 pm, Anand Patil <anand.prabhakar.pa...@gmail.com>
wrote:

Chouser

unread,
Jan 25, 2009, 8:01:33 AM1/25/09
to clo...@googlegroups.com
On Sun, Jan 25, 2009 at 7:06 AM, Anand Patil
<anand.prab...@gmail.com> wrote:
>
> I'd like to repeat my request for an example of definline usage; I
> feel I've tried everything.

I looked into this yesterday, and it seems to me that definline has
been broken since SVN rev 1065. I don't know why the usages of it in
core.clj don't cause errors at compile time, but they don't seem to
work quite right.

When used as a function, they work fine:

user=> (apply ints [(into-array Integer/TYPE [1 2 3])])
#<int[] [I@2f8b5a>

But when used as a macro, they return nil:

user=> (ints (into-array Integer/TYPE [1 2 3]))
nil

--Chouser

Chouser

unread,
Jan 25, 2009, 12:27:26 PM1/25/09
to clo...@googlegroups.com
On Sun, Jan 25, 2009 at 8:01 AM, Chouser <cho...@gmail.com> wrote:
> On Sun, Jan 25, 2009 at 7:06 AM, Anand Patil
> <anand.prab...@gmail.com> wrote:
>>
>> I'd like to repeat my request for an example of definline usage; I
>> feel I've tried everything.
>
> I looked into this yesterday, and it seems to me that definline has
> been broken since SVN rev 1065. I don't know why the usages of it in
> core.clj don't cause errors at compile time, but they don't seem to
> work quite right.

I wrote a new definline that seems to work correctly:

(defmacro definline
"Experimental - like defmacro, except defines a named function whose
body is the expansion, calls to which may be expanded inline as if
it were a macro. Cannot be used with variadic (&) args."
[name & decl]
(let [[pre-args [args expr]] (split-with (comp not vector?) decl)]
`(do
(defn ~name ~@pre-args ~args ~(apply (eval (list `fn args expr)) args))
(alter-meta! (var ~name) assoc :inline (fn ~args ~expr))
(var ~name))))

Using definline work, and return the Var, just like defn does:
user=> (definline inc2 "returns x plus 2" [x] `(+ 2 ~x))
#'user/inc2

The defined function works as a function:
user=> (map inc2 [1 2 3])
(3 4 5)

It also works inlined:
user=> (inc2 5)
7

And even the docstring works, which I think it didn't before:
user=> (doc inc2)
-------------------------
user/inc2
([x])
returns x plus 2
nil

This means that 'ints', 'doubles', and friends now work too:

user=> (doubles (into-array Double/TYPE [1 2 3]))
#<double[] [D@12aea3e>

user=> (doc doubles)
-------------------------
clojure.core/doubles
([xs])
Casts to double[]
nil

Patch attached.
--Chouser

definline-fix.patch

Anand Patil

unread,
Jan 25, 2009, 1:08:05 PM1/25/09
to Clojure
On Jan 25, 5:27 pm, Chouser <chou...@gmail.com> wrote:
> On Sun, Jan 25, 2009 at 8:01 AM, Chouser <chou...@gmail.com> wrote:
> > On Sun, Jan 25, 2009 at 7:06 AM, Anand Patil
> > <anand.prabhakar.pa...@gmail.com> wrote:
>
> >> I'd like to repeat my request for an example of definline usage; I
> >> feel I've tried everything.
>
> > I looked into this yesterday, and it seems to me that definline has
> > been broken since SVN rev 1065.  I don't know why the usages of it in
> > core.clj don't cause errors at compile time, but they don't seem to
> > work quite right.
>
> I wrote a new definline that seems to work correctly:
>
> (defmacro definline
>   "Experimental - like defmacro, except defines a named function whose
>   body is the expansion, calls to which may be expanded inline as if
>   it were a macro. Cannot be used with variadic (&) args."
>   [name & decl]
>   (let [[pre-args [args expr]] (split-with (comp not vector?) decl)]
>     `(do
>        (defn ~name ~@pre-args ~args ~(apply (eval (list `fn args expr)) args))
>        (alter-meta! (var ~name) assoc :inline (fn ~args ~expr))
>        (var ~name))))
>
> Using definline work, and return the Var, just like defn does:
> user=> (definline inc2 "returns x plus 2" [x] `(+ 2 ~x))
> #'user/inc2
>

Terrific, thanks very much!

Anand

Rich Hickey

unread,
Jan 25, 2009, 2:31:43 PM1/25/09
to Clojure


On Jan 25, 12:27 pm, Chouser <chou...@gmail.com> wrote:
Patch applied, svn 1233 - thanks!

Rich
Reply all
Reply to author
Forward
0 new messages