cljs.analyzer: how to use it?

823 views
Skip to first unread message

Yehonathan Sharvit

unread,
Nov 22, 2015, 11:19:29 AM11/22/15
to ClojureScript
Following this (great) talk by https://www.youtube.com/watch?v=Elg17s_nwDg
I tried to comile cljs in cljs.

The following code didn't work

(->> (cljs.tools.reader/read-string "(inc 2)")
(cljs.analyzer/analyze {}))

I got a js error:

Uncaught #error {:message "Cannot read property 'findInternedVar' of null", :data {:tag :cljs/analysis-error}


Who could help?

Maria Geller

unread,
Nov 23, 2015, 12:34:00 AM11/23/15
to ClojureScript
For evaluating ClojureScript in ClojureScript you need to use the cljs.js namespace (https://github.com/cljsinfo/cljs-api-docs/blob/catalog/refs/library/cljs.js.md). Here is a gist with a small example: https://gist.github.com/mneise/36c0bbae83b19c056781

Yehonathan Sharvit

unread,
Nov 24, 2015, 11:52:33 AM11/24/15
to clojur...@googlegroups.com
Thanks Maria.
It works fine.
What is the level of support for macros?
I tried to eval/compile with custom macros but it didn't work:

(defmacro my [n]
 n)
(macroexpand '(my 3)) 

eval returns: (my 3)
compile returns: cljs.user.my = (function cljs$user$my(_AMPERSAND_form,_AMPERSAND_env,n){ return n; }); cljs.user.my.cljs$lang$macro = true; cljs.core.list(new cljs.core.Symbol(null,"my","my",584828258,null),3);

So I tried to run macroexpand on a clojure macro (macroexpand  '(and 3 4))
It works:
eval returns: 
(let* [and__19224__auto__ 3] (if and__19224__auto__ (cljs.core$macros/and 4) and__19224__auto__))

compile returns: 
cljs.core.list(new cljs.core.Symbol(null,"let*","let*",1920721458,null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Symbol(null,"and__19224__auto__","and__19224__auto__",-1924552325,null),3], null),cljs.core.list(new cljs.core.Symbol(null,"if","if",1181717262,null),new cljs.core.Symbol(null,"and__19224__auto__","and__19224__auto__",-1924552325,null),cljs.core.list(new cljs.core.Symbol("cljs.core$macros","and","cljs.core$macros/and",48320334,null),4),new cljs.core.Symbol(null,"and__19224__auto__","and__19224__auto__",-1924552325,null)));


--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/5ZUvk7RPB9I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.



--
"Are we what we become or do we become what we are?" - Prof. Beno Gross

bpb...@gmail.com

unread,
Nov 27, 2015, 7:19:35 AM11/27/15
to ClojureScript
can I ask, how do you evaluate expressions that refer to local bindings ? Say I have an expression (+ x 4) that refers to x (not bound in the expression) and I create a new expression from it that puts it inside a (let [x 5] (+ x 4)) say, I get an error if I try to evaluate this.

Yehonathan Sharvit

unread,
Dec 1, 2015, 7:09:33 AM12/1/15
to clojur...@googlegroups.com
`(let [x 5] (+ x 4))`  works fine for me.

--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/5ZUvk7RPB9I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

bpb...@gmail.com

unread,
Dec 1, 2015, 8:51:36 AM12/1/15
to ClojureScript
On Tuesday, December 1, 2015 at 12:09:33 PM UTC, Yehonathan Sharvit wrote:
> `(let [x 5] (+ x 4))`  works fine for me.
>

sorry I should have been clearer - I meant where the value is something passed in:

`(let [x# ~y] (+ x 4))

Mike Fikes

unread,
Dec 13, 2015, 12:23:56 AM12/13/15
to ClojureScript
There are a couple of ways to make use of macros in cljs.js.

One would be to put the macros in a namespace and use cljs.js to require that namespace as a macros namespace. This would involve using cljs.js/*load-fn* to provide the source in the macro namespace. Then you can subsequently use cljs.js to compile and evaluate code that makes use of those macros.

Another approach, if you are just looking to expand a macro is detailed in this post:
http://blog.fikesfarm.com/posts/2015-09-05-runtime-macroexpand.html

Andray Shotkin

unread,
Jan 20, 2016, 11:28:43 AM1/20/16
to ClojureScript

Hi, Maria!

I tried to eval clojurescript form in clojurescript via eval-str and it works for code without functions.
If i add 'defn' form then error occurs. I debugged it and first of all following thing is suspicious: during analyzing defn we are dispatched into core$macros.js functions where .core.cst$sym$cljs$core$macros_SLASH_fn is not defined but similar cljs.core.cst$sym$cljs$core_SLASH_fn symbol is defined in constants_table.js
Can you advice me where i can have a look to resolve my problem?

Thanks in advance

ps by the way can you explain me when core$macros.js and constants_table.js come to play during transpiling?

Mike Fikes

unread,
Jan 20, 2016, 11:41:10 AM1/20/16
to clojur...@googlegroups.com
Hi Andray,

Can you provide an example. FWIW this is working for me:

foo.core=> (cljs/eval-str st "(defn square [x] (* x x))" 'test {:eval cljs/js-eval} cb)
#object[cljs$user$square "function cljs$user$square(x){
return (x * x);
}"]
nil
foo.core=>


Hi, Maria!

I tried to eval clojurescript form in clojurescript via eval-str and it works for code without functions.
If i add 'defn' form then error occurs. I debugged it and first of all following thing is suspicious: during analyzing defn we are dispatched into core$macros.js functions where .core.cst$sym$cljs$core$macros_SLASH_fn is not defined but similar cljs.core.cst$sym$cljs$core_SLASH_fn symbol is defined in constants_table.js
Can you advice me where i can have a look to resolve my problem?

Thanks in advance

ps by the way can you explain me when core$macros.js and constants_table.js come to play during transpiling?

--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.

To post to this group, send email to clojur...@googlegroups.com.

Andray Shotkin

unread,
Jan 20, 2016, 12:11:59 PM1/20/16
to ClojureScript

Hi, Mike!
I am doing similar things:

(defn node-eval [{:keys [name source]}]
(js/eval source)
)

(defn add-code [code]
(def st (empty-state))
(eval-str st
; "(ns foo.bar)\n
; (print (rest [1 2 3]))"

; "(ns foo.bar)
; (print (+ 1 2))"

; "(ns foo.bar)
; (def x 1)
; (def y 2)
; (print x)
; (print y)
; (print (+ x y))"

"(defn my-func [x] (print x))"
'foo.bar
{:verbose true
:source-map true
:eval node-eval
;:load node-load
}
(fn [{:keys [error] :as res}]
(print "continuation")
(if error
(do
(println error)
(println (.. error -cause -stack)))
(println res))))


i am using clojurescript 1.7.228
I have following difference: i cant explicitly import cljs.core/js because of its circular dependency on cljs.core->cljs.core if my cljs file contains only require on cljs.core/js, i didnt resolve this compile time error and copy paste cljs.core/js.cljs content into my own executor.cljs.

Andray Shotkin

unread,
Jan 20, 2016, 12:55:26 PM1/20/16
to ClojureScript

Mike, thanks!
THe issue was with lein with auto mode watching file changes. I restarted lein and cicrular dependency gone. Now all works. Thanks!
Andrew

Andray Shotkin

unread,
Jan 21, 2016, 8:03:51 AM1/21/16
to ClojureScript
Mike,
any idea how can i pass outer variables bindings into eval-str?
i see :locals field in options but these locals are not forwarded into env which is used during analyzing clojurescript form?

Andray

Mike Fikes

unread,
Jan 21, 2016, 9:21:26 AM1/21/16
to clojur...@googlegroups.com
Hi Andray,

I don’t know. I’ve always assumed eval-str treated its contents essentially as a top-level form. Having said that, if you have evaluated `def`s in your environment and maintain the analysis cache, then your evaluated string will “see” those `def`s.

- Mike

Yehonathan Sharvit

unread,
Jan 25, 2016, 9:10:02 AM1/25/16
to clojur...@googlegroups.com
I have an issue when requiring cljs.js and compiling in `:optimizations :whitespace`
I get the following error in the browser: goog.require could not find: cljs.core$macros

Any idea why it happens and how to solve it?


You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/5ZUvk7RPB9I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.

Yehonathan Sharvit

unread,
Feb 8, 2016, 2:05:12 AM2/8/16
to clojur...@googlegroups.com
I have opened a jira ticket for this issue: http://dev.clojure.org/jira/browse/CLJS-1565
Reply all
Reply to author
Forward
0 new messages