Fork me on GitHub
#cljs-dev
<
2016-10-29
>
anmonteiro19:10:26

@dnolen hrm, could this be everything that's needed for tagged literals to work? no self-host support yet https://github.com/anmonteiro/clojurescript/commit/e905d3bafa1530697d617fa77cc4174c1049296f

juhoteperi20:10:49

Been testing the Closure npm support.. and.. this will need some work still 😄

juhoteperi20:10:53

React depends on fbjs and corejs, and those include some crazy code

juhoteperi20:10:08

Perhaps those can safely be skipped, not sure

juhoteperi20:10:34

The module processing will try to process all files in foreign-deps, and will fail if single file can't be processed

juhoteperi20:10:46

Even if that file is not required by anything

anmonteiro20:10:08

@juhoteperi "crazy code" that Closure still doesn't understand?

juhoteperi20:10:09

But I'll start with trying to use some simpler npm module

juhoteperi20:10:34

hmm, success, kind of

juhoteperi20:10:49

(ns circle-color.core
  (:require [object-assign]))

(js/console.log (js/module$cljsjs_npm$object_assign$index #js {:foo 0} #js {:bar 1}))

juhoteperi20:10:34

Had to use js/ as I don't think it is possible to refer to the function exported in object-assign root

juhoteperi20:10:56

Though in this case it probably works because object-assign name is defined by deps.cljs entry

juhoteperi20:10:55

Oh, the Closure npm require resolving works for files inside node_modules

juhoteperi20:10:07

Though I guess that makes some sense

anmonteiro20:10:08

I think that's what they intended by implementing the node resolution algorithm 🙂

juhoteperi20:10:00

For example file resources/public/js/libs/Circle.js can't use npm modules

juhoteperi20:10:14

but could probably use the generated Closure module name

anmonteiro20:10:33

I'm not following

juhoteperi20:10:39

The file path doesn't contain node_modules

juhoteperi20:10:48

So the npm module logic is not used

juhoteperi21:10:28

This is one dependency of fbjs that causes problems

juhoteperi21:10:56

but there are 85 processing errors with React, and that is without core-js which causes Exception

anmonteiro21:10:08

@juhoteperi what if you use the browserified stuff?

anmonteiro21:10:30

(I know it's not the purpose of the experiment, but still..)

juhoteperi21:10:05

I'd presume then everything works as previously as there won't be npm modules

anmonteiro21:10:27

hrm there still is

anmonteiro21:10:33

react-dom -> react

anmonteiro21:10:49

I had to change that require to be ./react

juhoteperi21:10:04

I think it will need mock package.json

anmonteiro21:10:06

oh but you'll run into the same problems, nevermind

Yehonathan Sharvit21:10:55

does somebody know why with the default eval context of eval-str - :`statement` expressions like (if 1 2 3) are nillified?

Yehonathan Sharvit21:10:24

I looked in the code of the compiler and I saw a couple of places with code like this:

Yehonathan Sharvit21:10:41

(when-not (= :statement (:context env)) …)

anmonteiro21:10:20

@viebel because those are expressions

anmonteiro21:10:28

so you need to use :context :expr

Yehonathan Sharvit21:10:32

For instance:

(defmethod emit* :constant
  [{:keys [form env]}]
  (when-not (= :statement (:context env))
    (emit-wrap env (emit-constant form))))

Yehonathan Sharvit21:10:58

I know that :context :expr solves the problem

Yehonathan Sharvit21:10:26

my question is: why those expressions are ignored in :statement context? what is the rationale?

anmonteiro21:10:31

I think statements are supposed to not return anything

anmonteiro21:10:37

"The :context basically tells the compiler if the return value is required (:statement vs. :expr). A :statement does not need to return something and "if" in javascript does not return something."

Yehonathan Sharvit21:10:45

what’s the point of not returning something?

Yehonathan Sharvit21:10:00

is it for optimization reason - in order not to generate code that does nothing?

Yehonathan Sharvit21:10:27

anyway, in klipse I have no workaround I can think of

Yehonathan Sharvit21:10:11

When I use :statement - which is default in klipse - expressions are nillified http://app.klipse.tech/?cljs_in=(let%20%5Ba%204%5D%0A%20%20(if%20(%3E%20a%202)%203))

Yehonathan Sharvit21:10:35

I was thinking of overriding all the emit* functions that ignore pieces of code

Yehonathan Sharvit21:10:53

For instance instead of

(defmethod emit* :constant
  [{:keys [form env]}]
  (when-not (= :statement (:context env))
    (emit-wrap env (emit-constant form))))

Yehonathan Sharvit21:10:03

I will override it by:

Yehonathan Sharvit21:10:15

(defmethod emit* :constant
  [{:keys [form env]}]
    (emit-wrap env (emit-constant form)))

mfikes22:10:08

@viebel Consider (do 1 (prn 2) 3 4). As an optimization, the constants 1 and 3 are elided.

Yehonathan Sharvit22:10:19

@mfikes that’s only for optimization purposes?

mfikes22:10:50

@viebel Seems like a reasonable interpretation. Perhaps that’s what Rich meant by “minimize bootstrap js” here https://github.com/clojure/clojurescript/commit/86ad57839aa471b03d17c7ce1418736c7e9c7388

Yehonathan Sharvit22:10:24

OK. Thx @mfikes. I hope @dnolen will see this thread and give interesting insights

Yehonathan Sharvit22:10:11

Another thing related to compilation @mfikes: I found an interesting way to prevent infinite loops in boostrapped cljs

Yehonathan Sharvit22:10:40

Both in klipse and planck

(loop [x 1] (recur x))

Yehonathan Sharvit22:10:51

will stuck the process or the browser

Yehonathan Sharvit22:10:28

In planck, it’s less an issue than in KLIPSE, because you have Ctrl-C

Yehonathan Sharvit22:10:54

Anyway, I had this idea of emitting guard() function calls at interesting points of the code

Yehonathan Sharvit22:10:21

guard() will check how much time has elapsed since the beginning of the evaluation

Yehonathan Sharvit22:10:38

and if too much time has elapsed, it will throw an exception

mfikes22:10:39

If you could get guard() to read some volatile variable that you could set, then you could cooperatively interrupt evaluation, perhaps in the spirit of https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/interruptible_eval.clj#L265

Yehonathan Sharvit22:10:14

It’s very easy to make guard() read a volatile variable

Yehonathan Sharvit22:10:43

The tricky question is: where to insert the guard() calls?

Yehonathan Sharvit22:10:53

I thought about two places:

Yehonathan Sharvit22:10:07

1. before every if statement

Yehonathan Sharvit22:10:23

2. before continue emitted be recur

mfikes22:10:03

If you sort that out, you could propose a useful compiler mode. Perhaps it would be well-received if not too complicated.

Yehonathan Sharvit22:10:30

it seems to work and it’s not a lot of code

Yehonathan Sharvit22:10:35

I came to this idea after a discussion with @jrheard

Yehonathan Sharvit22:10:25

@mfikes what do u mean by a useful compiler mode? a flag to cljs.js/eval?

mfikes22:10:41

A general compiler flag, or perhaps a REPL option flag. For example, :def-emits-var was deemed sufficiently useful to take on the complexity of essentially a different “mode."

Yehonathan Sharvit22:10:38

If you have time to take a quick look at https://github.com/viebel/klipse/pull/131/files it’d be great - it’s just a couple of lines

mfikes23:10:50

Opinion: Interruptibility of accidentally long-running computations during dev, if achievable without excessive compiler complexity, and without harming dev perf, might pass muster.

mfikes23:10:33

@viebel Since you can do it outside of the compiler, you can spend some time learning if it works. 🙂 (I’m doing essentially same with eval.)

Yehonathan Sharvit23:10:58

Can u think of other interesting hooks beside if and continue?

mfikes23:10:57

No. This is one of those things that I think you can either spend time analyzing thoroughly, or you can just accumulate some time with it. (Or both.)

Yehonathan Sharvit23:10:50

thx for your inputs