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

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[] [...@12aea3e>

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

Patch attached.
--Chouser

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

commit 407a65779f0ebc07772fded00e95225ccb7c8423
Author: Chouser <chou...@n01se.net>
Date:   Sun Jan 25 12:13:59 2009 -0500

    Fix definline

diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 5c01215..8d3eef2 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -3031,14 +3031,13 @@
 (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."
+  it were a macro. Cannot be used with variadic (&) args." 
   [name & decl]
-  (let [[args expr] (drop-while (comp not vector?) decl)
-        inline (eval (list `fn args expr))]
+  (let [[pre-args [args expr]] (split-with (comp not vector?) decl)]
     `(do
-       (defn ~name ~args ~(apply inline args))
-       (let [v# (var ~name)]
-         (.setMeta v# (assoc ^v# :inline ~inline))))))
+       (defn ~name ~...@pre-args ~args ~(apply (eval (list `fn args expr)) args))
+       (alter-meta! (var ~name) assoc :inline (fn ~args ~expr))
+       (var ~name))))
 
 (defn empty
   "Returns an empty collection of the same category as coll, or nil"

Reply via email to