in self hosted clojurescript, is it possible to resolve a symbol to a function/var (at compile time, if that matters)? With lumo, I reckon it would be possible with the new eval
, or by having access to the underlying compiler state (and perhaps rolling your own eval
), but ideally it should be independent from the environment (= whether it's lumo, planck, klipse, whatever)
@moxaj Yes. Planck has an ns-resolve
that sits atop eval
like this:
(defn ns-resolve
[ns sym]
(eval `(~'var ~sym) ns))
Additionally, ClojureScript itself is introducing a (compile-time) resolve
macro.
@mfikes took at look at the new resolve
, but the symbol wouldn't be available at compile time
for the resolve
call, I mean
You have a case where the symbol is calculated at runtime?
well, the symbol is an input to a macro, which would use resolve
during its macroexpansion
Right. If your symbol is known at compile time, you can use ClojureScript’s new resolve
macro. If not, in self-hosted you can use eval
to do things at runtime.
cljs.user=> (def abc 3)
#'cljs.user/abc
cljs.user=> (resolve 'abc)
#'cljs.user/abc
cljs.user=> (resolve (symbol "abc"))
^
Doesn't support namespace: abc at line 1
cljs.user=> (require '[planck.core :refer [resolve]])
nil
cljs.user=> (planck.core/resolve (symbol "abc"))
#'cljs.user/abc
^ concrete example
hm, I suspected that was the case ... But for my use case, it would have to be independent from the env (library code), so that got me thinking: what if there was a default compiler state defined in cljs.js
, which all self hosted environments used? That wouldn't be that big of a change - theoretically - I believe
Ahh, understood. You want to write a library that depends on compiler state.
yep
in clojure and jvm clojurescript, it's easy, since I have require
and resolve
Hello. So I'm trying to port a Bash script to Lumo and wonder how to port this line:
cd "${BASH_SOURCE%/*}"
I.e. I want to change the working directory to the folder in which my Lumo script resides.
It looks like Node's __dirname
does not work in Lumo. I kinda managed to get script path via (.-argv js/process)
but I doubt it's going to be reliable enough as it returns smt. like [/usr/local/Cellar/lumo/1.5.0/bin/lumo nexe.js ./subfolder/script.cljs other args]
on my machine.
Hmm. Your Lumo script might actually be inside a JAR file.
I guess in your case the script is on disk.
cljs.user=> js/__dirname
"."
yes, the idea is that it will always be on disk and invoked like ./subfolder/script.cljs
or ./script.cljs
@hlolli right, but I would expect it to return /subfolder
or the absolute path
🙂 not sure if that's expected, just wanted to point out the js/ prefix
okay 🙂
@metametadata We added :file
info to self-hosted at one point, and it might be the reason this works:
cljs.user=> (require 'foo.core)
nil
cljs.user=> (:file (meta #'foo.core/x))
"/Users/mfikes/src/foo/core.cljs"
Oh, wait. Sorry, that’s depending on a Planck-specific feature to ensure the file is fully qualified. In Lumo it behaves differently.
(.cwd js/process)
yes, I tried that, it returns the folder of my current shell, not the folder of the script
@metametadata __dirname
should work if you run a script
Just like in Node
If you type __dirname
at the Node REPL you also won't get anything meaningfull
Let me know if that's not the case
alright, one moment
I'll try in like 20min
~/dev/foo ᐅ tree
.
└── bar
└── script.cljs
1 directory, 1 file
~/dev/foo ᐅ cat bar/script.cljs
#!/usr/bin/env lumo
(ns core.script)
(println js/__dirname)
~/dev/foo ᐅ ./bar/script.cljs
.
it looks like it always returns .
ᐅ lumo
Lumo 1.5.0
ClojureScript 1.9.542
Node.js v7.10.0
@metametadata looking into it
anmonteiro: thank you! I have to leave now but when I'm back to keyboard I can file a GitHub issue if it turns out to be something to be fixed in the future releases.
@metametadata definitely a bug
please file a ticket
@anmonteiro I'd be interested to hear your thoughts of my 'suggestion' above (see the conversation between me and @mfikes)
@moxaj there’s lumo.repl/resolve-var
would that work for your use case?
> But for my use case, it would have to be independent from the env (library code), so that got me thinking: what if there was a default compiler state defined in cljs.js
, which all self hosted environments used? That wouldn't be that big of a change - theoretically - I believe
this one, to be specific 🙂
@moxaj hrm can’t you use cljs.env/*compiler*
?
would that be equal to your st
?
isn’t it bound during your script?
yeah
not equal. the same
that'd be awesome! I'll report when I get to test it
👍
@dominicm you had a nested require
bug a while ago, remember that?
I wanna fix something but make sure I don’t break that 🙂
but I don’t remember how to repro
You mean requiring node modules?
No. Can't be that.
Don't remember right now
yeah
@dominicm something about preserving paths when requiring node modules
@moxaj let me know if tagged literals is something you’d like to work on
Shebang relative requires?
I did
happy to coach you along the way
I have a convenient repo located on my GitHub
shall I comment here? or on the issue
if it’s something you think deserves to be saved in history, GitHub please 🙂
@dominicm might be
alright
@moxaj what do you wanna achieve with data readers?
the same thing I'm now going to achieve with accessing the compiler state instead 😄
evaluating user input at compile time
your fork is a good start but there’s some things that need to be ironed out
data readers were my first attempt, but that smells like a hack
I’d love to have it implemented but we should make it work for the REPL / scripts first
and then use that in the closure namespace
what I have now seems to work in the repl
how come
well, not the full story
just what I've mentioned at the issue
the data readers get loaded
right
I might be very far from the full solution, I have no idea
so here’s what I had thought before
https://github.com/anmonteiro/lumo/blob/master/src/cljs/snapshot/lumo/js_deps.cljs#L21
just like we look for every deps.cljs
file in JARs
we should also look for data reader files and load them
also just found a bug related to loading deps.cljs
😄 https://github.com/anmonteiro/lumo/issues/184
as far as I can tell, that's what I'm doing - checking for data_readers.clj(s|c|)
in the classpath directories and jars, and loading them
yeah, which is why I said it’s a good start
the problem is that you’re doing it in lumo.closure
and that’s not loaded when the REPL starts or when scripts execute
also we shouldn’t be checking for data_readers.clj
^ that’s reserved for Clojure
noted
also unsure about data_readers.cljs
, but it’s OK to punt on that for now
@moxaj was I clear or do you still have some questions?
do let me know if I’m not explaining the problem well enough
@anmonteiro it's still somewhat unclear. Which files exactly are available when the scripts execute? What should I hook into after loading the readers?
@moxaj when a script executes or the REPL starts we should have all the classpath paths
after loading the readers I don’t really recall right now where we should hook into
I’m stepping into a meeting right now but I’ll do a little bit or research later
alright, thanks!