[ANN] Proteus: local mutable variables for the masses

295 views
Skip to first unread message

Zach Tellman

unread,
Jul 11, 2013, 9:16:35 PM7/11/13
to clo...@googlegroups.com
There was some discussion a few days ago about how the lack of local mutable variables were harming performance, or possibly elegance, I'm not sure.  Regardless, I fixed it: https://github.com/ztellman/proteus

Enjoy!

Ben Wolfson

unread,
Jul 11, 2013, 9:35:21 PM7/11/13
to clo...@googlegroups.com
Note:

proteus> (defmacro aif [test then else]
           (let [it (first (filter #(not (contains? &env %))
                                   (cons 'it (map #(symbol (str "it-" %)) (iterate inc 1)))))]
             `(let [~it ~test] (if ~it ~then ~else))))
#'proteus/aif
proteus> (aif (get {:x {:y 3}} :x)
              (aif (get it :y)
                   [it it-1]
                   it)
              nil)
[{:y 3} 3]
proteus> (let-mutable [x 1]
                      (aif (get {:x {:y 3}} :x)
                           (aif (get it :y)
                                (set! x [it it-1])
                                (set! x it))
                           (set! x nil))
                      x)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: it-1 in this context, compiling:(NO_SOURCE_PATH:1:1)
proteus>




On Thu, Jul 11, 2013 at 6:16 PM, Zach Tellman <ztel...@gmail.com> wrote:
There was some discussion a few days ago about how the lack of local mutable variables were harming performance, or possibly elegance, I'm not sure.  Regardless, I fixed it: https://github.com/ztellman/proteus

Enjoy!

--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure." [Larousse, "Drink" entry]

Zach Tellman

unread,
Jul 11, 2013, 9:48:36 PM7/11/13
to clo...@googlegroups.com
Yeah, for safety's sake I need to macroexpand everything, which wipes out the &env for internal macros.  There might be a gentler way to do this, but it's not obvious to me.  If anyone has suggestions, I'd be interested in hearing them.

Zach

Ben Wolfson

unread,
Jul 11, 2013, 9:54:16 PM7/11/13
to clo...@googlegroups.com
On Thu, Jul 11, 2013 at 6:48 PM, Zach Tellman <ztel...@gmail.com> wrote:
Yeah, for safety's sake I need to macroexpand everything, which wipes out the &env for internal macros.  There might be a gentler way to do this, but it's not obvious to me.  If anyone has suggestions, I'd be interested in hearing them.

The core.async internals do something similar (or did at the time of release, that code has been rewritten, apparently).

You're also missing some binding forms:

proteus> (clojure.pprint/pprint (macroexpand-1 '(let-mutable [x 1] (try (/ 1 0) (catch Exception x (set! x 2) x)))))
(clojure.core/let
 [x (new proteus.Containers$L 1)]
 (do
  (try
   (. clojure.lang.Numbers (divide 1 0))
   (catch Exception (.x x) (do (.set x 2) nil) (.x x)))))


proteus> (clojure.pprint/pprint (macroexpand-1 '(let-mutable [x 1] (letfn [(x [] 4)] (set! x 4) x))))
(clojure.core/let
 [x (new proteus.Containers$L 1)]
 (do (letfn* [x (fn* x ([] 4))] (do (.set x 4) nil) (.x x))))

Zach Tellman

unread,
Jul 11, 2013, 10:02:23 PM7/11/13
to clo...@googlegroups.com
It looks like the macroexpansion code in conditions.free is fairly generic.  What would you say to putting it into its own library?


You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/7HNNiJJTte4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

Ben Wolfson

unread,
Jul 11, 2013, 10:46:11 PM7/11/13
to clo...@googlegroups.com
Sure, I was considering that anyway. I'm not sure, though, whether it should be in its own library all by its lonesome or in one with at least a fairly generic name, since I've got some other macro-related utilities (specifically https://github.com/bwo/macroparser) that could all be usefully (I think) grouped together.
Reply all
Reply to author
Forward
0 new messages