ClojureScript: the future of js* and numerics

134 views
Skip to first unread message

David Nolen

unread,
Sep 22, 2011, 7:33:35 PM9/22/11
to cloju...@googlegroups.com
There's been some rumblings about allowing direct use of js*.

However, looking at the places where it is used it is quite clear that what js* does is still needed. What about js* usage only in :inline metadata?

This would give the following benefits:

* Disallow free usage of js*
* high performance aget/set/length/etc when not used higher-order
* Make ClojureScript acceptable for arithmetic heavy operations like graphics. Chris Granger has already run into very large slow downs compared to JavaScript when trying to write code that targets the Canvas tag.

I don't really see the benefits of Clojure's numeric guarantees in ClojureScript given we only have floating point. Does anyone see problems with this approach to improving ClojureScript numeric performance?

David

Rich Hickey

unread,
Sep 23, 2011, 8:03:28 AM9/23/11
to cloju...@googlegroups.com
ClojureScript has a form of compiler macros. They obviate :inline. They already deliver high performance aget/aset (i.e. the versions you see in core.cljs are not used by direct calls - look at the macro defs in core.clj). They have not yet been extended to the math ops - doing so is a longstanding TODO. Patches welcome.

What's a compiler macro? In the case of cljs, all macros are expanded until they are no longer macro calls. Having a function of the same name in cljs code is not a problem.

:inline should not be used in cljs.

Rich

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

David Nolen

unread,
Sep 23, 2011, 8:49:14 AM9/23/11
to cloju...@googlegroups.com
On Fri, Sep 23, 2011 at 8:03 AM, Rich Hickey <richh...@gmail.com> wrote:
ClojureScript has a form of compiler macros. They obviate :inline. They already deliver high performance aget/aset (i.e. the versions you see in core.cljs are not used by direct calls - look at the macro defs in core.clj). They have not yet been extended to the math ops - doing so is a longstanding TODO. Patches welcome.

What's a compiler macro? In the case of cljs, all macros are expanded until they are no longer macro calls. Having a function of the same name in cljs code is not a problem.

:inline should not be used in cljs.

Rich

Aha! :)

David 

David Nolen

unread,
Sep 23, 2011, 10:43:03 AM9/23/11
to cloju...@googlegroups.com
OK seems to work great, https://github.com/clojure/clojurescript/blob/4-math-op-macros/src/clj/cljs/core.clj

Is there anything else that people would like to see here, something I missed?

David

Alan Dipert

unread,
Sep 23, 2011, 12:11:32 PM9/23/11
to cloju...@googlegroups.com
Cool! I created a ticket, http://dev.clojure.org/jira/browse/CLJS-79,
for doing the same with bit ops, which have not yet been added to
ClojureScript.

If anyone's interested, feel free to grab it.
Alan

Michał Marczyk

unread,
Sep 23, 2011, 1:36:27 PM9/23/11
to cloju...@googlegroups.com
On 23 September 2011 16:43, David Nolen <dnolen...@gmail.com> wrote:
> OK seems to work
> great, https://github.com/clojure/clojurescript/blob/4-math-op-macros/src/clj/cljs/core.clj

Great!

> Is there anything else that people would like to see here, something I
> missed?
> David

One thing: the single arity cases of +, - and * should not
syntax-quote x and / should unquote x.

Sincerely,
Michał

David Nolen

unread,
Sep 23, 2011, 1:43:43 PM9/23/11
to cloju...@googlegroups.com
Thanks, fixed.

David

David Nolen

unread,
Sep 23, 2011, 1:15:57 PM9/23/11
to cloju...@googlegroups.com
Done.

Chouser

unread,
Sep 24, 2011, 10:47:42 PM9/24/11
to cloju...@googlegroups.com
On Fri, Sep 23, 2011 at 8:03 AM, Rich Hickey <richh...@gmail.com> wrote:
> ClojureScript has a form of compiler macros. They obviate :inline. They already deliver high performance aget/aset (i.e. the versions you see in core.cljs are not used by direct calls - look at the macro defs in core.clj). They have not yet been extended to the math ops - doing so is a longstanding TODO. Patches welcome.
>
> What's a compiler macro? In the case of cljs, all macros are expanded until they are no longer macro calls. Having a function of the same name in cljs code is not a problem.

Sorry if I'm being dense -- how is this different from regular macros
in Clojure. Don't they also expand until they are no longer macro
calls?

--Chouser

Alan Malloy

unread,
Sep 24, 2011, 11:00:29 PM9/24/11
to Clojure Dev
I've actually wanted (a feature of) compiler macros in Clojure, once.
The idea (summarized at http://www.ida.liu.se/imported/cltl/clm/node101.html)
is a macro that is only called when compiling, rather than
interpreting. In Clojure, of course, this is not very interesting,
since we are always compiling. The neat thing compiler macros let you
do is "decline" to do any expansion, by returning exactly the form
passed in (that is, pointer-equal: eq or identical?).

I don't quite understand what Rich is saying about them here, but the
relevant application to David's work seems to be that you could define
+ as a function, which performs slowly, and attach a compiler macro to
it that can expand to something faster when calling it by name.

On Sep 24, 7:47 pm, Chouser <chou...@gmail.com> wrote:

Michał Marczyk

unread,
Sep 25, 2011, 4:02:13 AM9/25/11
to cloju...@googlegroups.com
In Clojure, regular macros can decline to expand by providing an
identical? form too, although it's not terribly useful:

(defmacro foo [& args] &form)

(macroexpand '(foo 1 2 3))
; => (foo 1 2 3)

(Incidentally, this doesn't work with the macrolet of tools.macro --
mostly due to &form and &env not being handled as magic args. Patch in
progress. @Alan: I completely forgot about this use of &form when we
were discussing the test-tagging thing recently; anyway, it wouldn't
have worked without a patched tools.macro anyway. I guess I'll be
having another look at that code after writing the patch up...)

In Common Lisp, the almost-equivalent (defmacro foo (&whole form &rest
args) form) (macroexpand '(foo 1 2 3)) would not terminate.

Anyway, agreed about the application as an elaborate, tunable inlining
mechanism being possible due to different namespacing. (I.e. macros in
cljs living in a separate namespace from functions which only comes
into play for symbols occurring in the operator position.)

Sincerely,
Michał

Rich Hickey

unread,
Sep 26, 2011, 7:47:38 AM9/26/11
to cloju...@googlegroups.com
The second sentence explains how - they are in different namespaces from functions with the same name. We can't do the same (currently) in Clojure due to the macro and function colliding.

We could move to a uniform compiler-macro system for both if a) we had a different place to put them (i.e. not in the var), and b) they expanded only once. This would yield the additional benefit CL compiler macros have in that they can expand into themselves (i.e. into forms with the same first symbol).

Rich

Reply all
Reply to author
Forward
0 new messages