Fork me on GitHub
#lumo
<
2017-06-13
>
moxaj14:06:39

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)

mfikes15:06:42

@moxaj Yes. Planck has an ns-resolve that sits atop eval like this:

(defn ns-resolve
  [ns sym]
  (eval `(~'var ~sym) ns))

mfikes15:06:24

Additionally, ClojureScript itself is introducing a (compile-time) resolve macro.

moxaj15:06:27

@mfikes took at look at the new resolve, but the symbol wouldn't be available at compile time

moxaj15:06:55

for the resolve call, I mean

mfikes15:06:17

You have a case where the symbol is calculated at runtime?

moxaj15:06:57

well, the symbol is an input to a macro, which would use resolve during its macroexpansion

mfikes15:06:49

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.

mfikes15:06:57

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

mfikes15:06:05

^ concrete example

moxaj15:06:28

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

mfikes15:06:27

Ahh, understood. You want to write a library that depends on compiler state.

moxaj15:06:57

in clojure and jvm clojurescript, it's easy, since I have require and resolve

metametadata15:06:15

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.

mfikes15:06:40

Hmm. Your Lumo script might actually be inside a JAR file.

mfikes15:06:00

I guess in your case the script is on disk.

hlolli15:06:34

cljs.user=> js/__dirname
"."

metametadata15:06:38

yes, the idea is that it will always be on disk and invoked like ./subfolder/script.cljs or ./script.cljs

metametadata15:06:12

@hlolli right, but I would expect it to return /subfolder or the absolute path

hlolli15:06:20

🙂 not sure if that's expected, just wanted to point out the js/ prefix

mfikes15:06:50

@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"

mfikes15:06:32

Oh, wait. Sorry, that’s depending on a Planck-specific feature to ensure the file is fully qualified. In Lumo it behaves differently.

hlolli15:06:33

(.cwd js/process)

metametadata15:06:06

yes, I tried that, it returns the folder of my current shell, not the folder of the script

anmonteiro15:06:23

@metametadata __dirname should work if you run a script

anmonteiro15:06:34

Just like in Node

anmonteiro15:06:09

If you type __dirname at the Node REPL you also won't get anything meaningfull

anmonteiro15:06:29

Let me know if that's not the case

metametadata15:06:10

alright, one moment

anmonteiro15:06:29

I'll try in like 20min

metametadata15:06:56

~/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
.

metametadata15:06:12

it looks like it always returns .

metametadata15:06:27

ᐅ lumo             
Lumo 1.5.0
ClojureScript 1.9.542
Node.js v7.10.0

metametadata16:06:26

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.

anmonteiro16:06:44

please file a ticket

moxaj16:06:23

@anmonteiro I'd be interested to hear your thoughts of my 'suggestion' above (see the conversation between me and @mfikes)

anmonteiro16:06:18

@moxaj there’s lumo.repl/resolve-var

anmonteiro16:06:29

would that work for your use case?

moxaj16:06:45

> 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 🙂

anmonteiro16:06:55

@moxaj hrm can’t you use cljs.env/*compiler*?

moxaj16:06:13

would that be equal to your st?

anmonteiro16:06:14

isn’t it bound during your script?

anmonteiro16:06:35

not equal. the same

moxaj16:06:57

that'd be awesome! I'll report when I get to test it

anmonteiro16:06:38

@dominicm you had a nested require bug a while ago, remember that?

anmonteiro16:06:46

I wanna fix something but make sure I don’t break that 🙂

anmonteiro16:06:55

but I don’t remember how to repro

dominicm18:06:01

You mean requiring node modules?

dominicm18:06:12

No. Can't be that.

dominicm18:06:22

Don't remember right now

anmonteiro18:06:55

@dominicm something about preserving paths when requiring node modules

anmonteiro18:06:59

@moxaj let me know if tagged literals is something you’d like to work on

dominicm18:06:06

Shebang relative requires?

anmonteiro18:06:14

happy to coach you along the way

dominicm18:06:18

I have a convenient repo located on my GitHub

moxaj18:06:19

shall I comment here? or on the issue

anmonteiro18:06:46

if it’s something you think deserves to be saved in history, GitHub please 🙂

anmonteiro18:06:25

@moxaj what do you wanna achieve with data readers?

moxaj18:06:42

the same thing I'm now going to achieve with accessing the compiler state instead 😄

moxaj18:06:49

evaluating user input at compile time

anmonteiro18:06:56

your fork is a good start but there’s some things that need to be ironed out

moxaj18:06:58

data readers were my first attempt, but that smells like a hack

anmonteiro18:06:24

I’d love to have it implemented but we should make it work for the REPL / scripts first

anmonteiro18:06:29

and then use that in the closure namespace

moxaj18:06:42

what I have now seems to work in the repl

moxaj18:06:05

well, not the full story

moxaj18:06:23

just what I've mentioned at the issue

moxaj18:06:30

the data readers get loaded

moxaj18:06:51

I might be very far from the full solution, I have no idea

anmonteiro18:06:53

so here’s what I had thought before

anmonteiro18:06:18

just like we look for every deps.cljs file in JARs

anmonteiro18:06:32

we should also look for data reader files and load them

anmonteiro18:06:58

also just found a bug related to loading deps.cljs 😄 https://github.com/anmonteiro/lumo/issues/184

moxaj18:06:18

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

anmonteiro18:06:52

yeah, which is why I said it’s a good start

anmonteiro18:06:13

the problem is that you’re doing it in lumo.closure

anmonteiro18:06:18

and that’s not loaded when the REPL starts or when scripts execute

anmonteiro18:06:39

also we shouldn’t be checking for data_readers.clj

anmonteiro18:06:48

^ that’s reserved for Clojure

anmonteiro18:06:04

also unsure about data_readers.cljs, but it’s OK to punt on that for now

anmonteiro18:06:55

@moxaj was I clear or do you still have some questions?

anmonteiro18:06:27

do let me know if I’m not explaining the problem well enough

moxaj18:06:56

@anmonteiro it's still somewhat unclear. Which files exactly are available when the scripts execute? What should I hook into after loading the readers?

anmonteiro18:06:04

@moxaj when a script executes or the REPL starts we should have all the classpath paths

anmonteiro18:06:33

after loading the readers I don’t really recall right now where we should hook into

anmonteiro18:06:49

I’m stepping into a meeting right now but I’ll do a little bit or research later

moxaj18:06:03

alright, thanks!