Fork me on GitHub
#clojurescript
<
2016-02-27
>
echristopherson00:02:41

when did we get a leiningen emothingy?

jannis00:02:03

If I want to hand a JS object over to a macro that generates a defn for each property in the JS object... how would best I do that?

jannis00:02:33

The macro would be called like this from CLJS: (defcomponents js/MyJSObject) and if MyJSObject has the properties foo and bar it should define two CLJS functions, (defn foo-component [...] ...) and (defn bar-component [...] ...).

anmonteiro00:02:03

@jannis: At a first look I'd js->clj the object and map over it?

anmonteiro00:02:31

oh you don't have js->clj in macro expansion simple_smile

jannis00:02:46

Well, I can do '(let [components# (~'js->clj ~components)] ...) in the macro (where ' is the backtick) but after that?

jannis00:02:51

I can even get the macro to generate (do (clojure.core/defn Button-component [] foo) (clojure.core/defn Card-component [] foo) (clojure.core/defn Heading-component [] foo) (clojure.core/defn Layout-component [] foo) (clojure.core/defn Text-component [] foo))) for me but then I'd still need to evaluate it somehow for the defns to take effect.

mfikes00:02:30

@jannis: that's an interesting problem. Since the compiler is Clojure, there is really no JavaScript engine in sight be there to help with the runtime aspects (apart from Nashorn). … hmm

mfikes00:02:58

@jannis: whole different thing if using bootstrapped compiler from within JavaScript, though

jannis00:02:41

Yeah, then I could just have the compiler generate JS from the generated form, I suppose?

jannis00:02:45

Is that possible today?

jannis00:02:34

I have no idea how the bootstrapped compiler works or in what form it is available. I know it exists because people talk about it, that's all 😉

mfikes00:02:45

@jannis: hah, almost anything seems possible :)

mfikes00:02:13

@jannis: Snoop around this project to see how David was wielding Nashorn to do things with JavaScript from Clojure

jannis00:02:17

Another idea: If there was a way to apply js->clj before the data is passed to the macro then that might work too. My understanding of data readers is limited, could I do something like (defcomponents #clj js/MyJSObject)?

mfikes00:02:26

@jannis: at the core of this is the separation of runtime (where JavaScript exists) and compile time

mfikes00:02:25

@jannis: in other words js->clj is a runtime thing

jannis00:02:54

Yeah. I've written macros before that generated CLJS code - but from CLJ symbols and expression lists, not from JS objects that are unknown at compile time.

mfikes00:02:02

@jannis: so if you can start Nashorn (from a macro!), start bootstrapped ClojureScript inside of it, then you can do anything :)

jannis00:02:32

I'll take a look at jsx-fun

mfikes00:02:43

@jannis: Paul Graham has a cool essay talking about Lisp freely mixing things up. Bootstrapped ClojureScript leads to that ability.

dmitrig0100:02:02

@jannis: you can also consider using intern to actually do it at runtime

dmitrig0100:02:08

i don't know if it works in cljs though

jannis00:02:31

@mfikes: I have to admit jsx-fun is over my head right now. I see nashorn evaluating JS but I'm not sure how that helps in this case.

dmitrig0101:02:03

oh sweet (except that link doesn't work)

dmitrig0101:02:30

it's always an exercise to figure out how to solve a problem like this without a macro if possible

mfikes01:02:44

@jannis: right, using Nashorn from within a macro to run bootstrapped ClojureScript is definitely at the deep end of the pool :) but it sounds fun

jannis01:02:22

I assume Nashorn can only evaluate JS? So something would have to compile the generated CLJS expressions to JS before Nashorn can process them?

mfikes01:02:37

@dmitrig01: I fixed the link.

mfikes01:02:20

@jannis: right. I bet you can use the compiler from within a macro. Lots of interesting things could be done. Definitely a bigger problem than the one you set out to solve

jannis01:02:24

Where can I find the compiler to use it? 😉

jannis01:02:26

I've got Nashorn to eval "5" and return the value to CLJS. Now I just need to eval ClojureScript 😉

mfikes01:02:49

@jannis: indeed. You can load the ClojureScript runtime into Nashorn just like any other JavaScript target

mfikes01:02:46

@jannis: and you can compile additional ClojureScript firms to JavaScript to be executed in Nashorn

mfikes01:02:39

@jannis: it's probably very hacky, but I could see using macroexpansion in bootstrapped ClojureScript to generate your defn forms, etc. at that point you are cobbling together a compiler within s compiler. Hmm

mfikes01:02:33

@jannis: if you are just doing this as a one-off, to generate code, maybe you could use an existing bootstrapped ClojureScript environment to do it

jannis01:02:06

I wouldn't say it's a one-off. I have a JS React component library and I want to generate a function for each of the components that takes props and children and returns the result of (js/React.createElement <component> #js <props> <children>).

jannis01:02:24

My assumption was that the best way to approach this was to define these functions in the client after it has required the library via :foreign-libs. It exports a single JS object whose keys are component names and whose values are their implementations (`<component>` in the above snippet).

jannis01:02:56

So I thought I'd take that library object and generate the defns for its components on the fly.

jannis01:02:00

Not that easy apparently 😉

jannis01:02:53

I wonder... instead of receiving the JS object from CLJS, could I instead load the corresponding .js file from classpath with Nashorn, evaluate it, get the library object and generate CLJS code from it? So that I can then just use (defcomponents "my-library.js") in CLJS?

jannis01:02:59

@mfikes: ^ What do you think?

mfikes01:02:41

@jannis: Yes, I suspect creative approaches like that might do it.

jannis01:02:52

I'm trying it as we speak

jannis01:02:46

Perhaps not: :message ReferenceError: "window" is not defined in <eval> at line number 19320 at line 11

johanatan02:02:15

Hi, suppose I have N objects and M operations (some of which are doing network I/O). I want to call the sequence of operations in order for each of the N objects but allowing parallelism (across the objects) where possible. There is one synch (fan-in) point in the pipeline let's say at operation M-1. What's the best/easiest way to do this in core.async?

mccraigmccraig07:02:22

@johanatan: cats or promesa's alet will do this for you.... dunno about core.async based solutions

val_waeselynck08:02:58

@johanatan: I wrote my own helper to get the equivalent of the Promise.all() fn you find in js promise libs

johanatan08:02:28

@mccraigmccraig: ahh cool. I'll take a look. Thx!

johanatan08:02:41

@val_waeselynck: promise.all() would be only one aspect of the solution here though no? Core.async already has into for that.

val_waeselynck08:02:13

well you asked for a core.async based solution simple_smile

val_waeselynck08:02:02

you could also look into pipelynce-async i guess

kmandrup15:02:07

What are the translation rules to Javascript for clojure ^export functions. - becomes _ but what about all the other special characters??

noisesmith15:02:07

kmandrup: good question, I wonder if it follows the munge rules?

kmandrup15:02:33

munge rules?

noisesmith15:02:44

kmandrup: clojure uses a function called munge

noisesmith15:02:51

it has a matching function called demunge

kmandrup15:02:04

where can I find info on this?

noisesmith15:02:07

(the names here are historical, names for automated name translations)

noisesmith15:02:22

kmandrup: those functions are available in the repl, and have doc strings, etc. in clojure

noisesmith15:02:15

the idea is that by having that job done by a function, you can accurately do the same translation you expect the compiler to do (in both directions)

noisesmith15:02:40

kmandrup: and as I expected, cljs uses the same function name (different implementation) https://crossclj.info/ns/receipt/1.0.1/cljs.compiler.html#_munge

kmandrup15:02:44

Thanks simple_smile I'm trying to add some basic docs to Datascript https://github.com/tonsky/datascript/wiki/Javascript-API

kmandrup16:02:05

Is there a way to generate a list of the fully exported Javascript API? There ought to be... just metadata after all

mfikes16:02:59

@kmandrup: I’d take a look at how cljs.test finds all of the test functions as described in the bottom of http://swannodette.github.io/2014/12/17/whats-in-a-var/ and modify the approach to look for ^:export metadata instead

noisesmith17:02:03

@mfikes: why imitate it instead of using it?

richiardiandrea17:02:20

For whoever missed it, here is some ClojureScript light in the React.js recent conference,good job @jaredly! https://t.co/eRTJI5p08g

mfikes17:02:30

@noisesmith: yes, clients could hard-code the JavaScript needed to call munge and just call it. Not a bad idea.

noisesmith17:02:06

oh, I thought you had an interesting reason I had not thought of and I might be about to learn something, heh

nashio18:02:06

Howdy peoples, what would you say its the first boilerplate or tutorial you would recommend for someone starting with clojurescript

noisesmith18:02:25

nashio: figwheel starter / demo is awesome

noisesmith18:02:41

figwheel is a great tool, and it's good to start by just forking the demo

kmandrup19:02:54

Anyone interested in starting a Visual Studio code extension for Clojure via https://github.com/clojure/tools.analyzer ??

kmandrup19:02:42

Visual Studio code looks to me like an IDE/editor that hits the "sweet spot" and is easy to extend... 😉

venantius20:02:45

probably a better question for the #C03S1KBA2 channel