<< Back to previous view

[CLJS-1617] Evaluation order of arguments to 'list' is right-to-left Created: 07/Apr/16  Updated: 17/Apr/16  Resolved: 08/Apr/16

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Sam Roberton Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

    (.log js/console "Evaluation order test")
    (let [result (list
                    (.log js/console "1")
                    (.log js/console "2")
      (.log js/console "Result: " (pr-str result))))


Evaluation order test
Result:  (1 2)

Comment by Kevin Downey [ 07/Apr/16 1:46 PM ]

`list` is sometimes a function and sometimes a macro in clojurecript, I am not sure how the compiler chooses between them, but this is behavior is the result of the macro version.

replacing the macro with something like

(core/defmacro list
  ([] '(.-EMPTY cljs.core/List))
  ([x & xs]
     `(let [x# ~x]
        (-conj (list ~@xs) x#))))

should fix it

Comment by Kevin Downey [ 07/Apr/16 1:49 PM ]

why the macro version exists, I have no idea

Comment by David Nolen [ 08/Apr/16 2:40 PM ]

fixed https://github.com/clojure/clojurescript/commit/29eb8e014f60d57c974fef46f8609ca0be0fd247

Comment by Kevin Downey [ 08/Apr/16 7:28 PM ]

this fix seems like it would cause macros as arguments to list to be expanded twice, which I know causes problems in clojure (a number of the macros in clojure.core have side effects at expansion time), maybe it is a bad idea in clojurescript as well

Comment by Mike Fikes [ 09/Apr/16 7:57 PM ]

Hey Kevin, the ~x appears only once on both branches of the if so evaluation should occur once. This test pans out:

(let [x (atom 0)]
  [(list (swap! x inc) (swap! x inc)) @x])

properly yielding [(1 2) 2]. (FWIW, an example of double evaluation in a macro is in CLJS-1518, which is solvable there by letting once as is done in this ticket's fix.)

Comment by Kevin Downey [ 10/Apr/16 1:27 AM ]

I am not talking about double evaluation, I am talking about double macro expansion.

The analyzer does macro expansion so the list macro that calls the analayzer is sort of like

(defmacro x [y]
  (macroexpand y)

y will then be macroexpanded again as compilation continues, so macroexpansion happens twice.

I suspect this is more of an issue in clojure than it is in clojurescript, because the compilation environment is isolated from the runtime environment in clojurescript. In clojure while hacking on the compiler, it would be very nice to analyze a form and then make decisions based on that analysis, and then re-analyze the form differently, but the double macro expansion breaks things (a long with other stateful bits in the compiler). Regardless it seems like a bad idea.

Comment by Mike Fikes [ 10/Apr/16 7:38 AM ]

Ahh, sorry Kevin. I completely missed what you were saying earlier.

So, perhaps your concern does come in to play with bootstrap ClojureScript where there is no separation (macros are expanded in the runtime environment, so side effects could have a consequence).

FWIW, I ran the ClojureScript compiler's unit tests in bootstrap ClojureScript with this change and they pass.

I suppose one corollary example of what you are saying is that it is no longer possible to evaluate

(macroexpand '(list (when-let) 1))
Comment by Kevin Downey [ 17/Apr/16 12:08 AM ]

http://dev.clojure.org/jira/browse/CLJS-1625 is a similar issue

[CLJS-1553] browser repl "EOF while reading string" when evaluating symbol "enable-console-print!" Created: 28/Jan/16  Updated: 05/Mar/16  Resolved: 05/Mar/16

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.228
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Scott Bale Assignee: Scott Bale
Resolution: Declined Votes: 0
Labels: repl

On client side: Chrome browser (47.0.2526.111) On Mac OS 10.10.5 Yosemite

On server side:

  • Amazon EC2 instance running amazon linux

java -version
openjdk version "1.8.0_65"
OpenJDK Runtime Environment (build 1.8.0_65-b17)
OpenJDK 64-Bit Server VM (build 25.65-b01, mixed mode)

Attachments: GZip Archive cljs-hello-world.tar.gz    


Just playing around in the browser repl, running through the CLJS quickstart, I happened upon this. I crashed the repl by attempting to evaluate enable-console-print!.

Below is output of my repl. As you can see, I can doc, source, or even invoke the function, but if I try to simply evaluate the symbol, the repl crashes with a Java runtime exception. (I was expecting the repl to output a toString representation of the enable-console-print! function object, as it would for any other symbol that resolves to a function.)

I've attached a .tar.gz file of my project, but I excluded the cljs.jar file from the root. (The IP address in core.cljs is the public IP address of the ec2 instance I was using.)

The command I used to start the repl is:

java -cp cljs.jar:src clojure.main repl.clj

REPL output:

cljs.user=> (doc enable-console-print!)
  Set *print-fn* to console.log
cljs.user=> (source enable-console-print!)
(defn enable-console-print!
  "Set *print-fn* to console.log"
  (set! *print-newline* false)
  (set! *print-fn*
    (fn [& args]
      (.apply (.-log js/console) js/console (into-array args))))
  (set! *print-err-fn*
    (fn [& args]
      (.apply (.-error js/console) js/console (into-array args))))
cljs.user=> (enable-console-print!)
cljs.user=> enable-console-print!
Exception in thread "Thread-138" java.lang.RuntimeException: EOF while reading string
        at clojure.lang.Util.runtimeException(Util.java:221)
        at clojure.lang.LispReader$StringReader.invoke(LispReader.java:525)
        at clojure.lang.LispReader.read(LispReader.java:263)
        at clojure.lang.LispReader.readDelimitedList(LispReader.java:1200)
        at clojure.lang.LispReader$MapReader.invoke(LispReader.java:1158)
        at clojure.lang.LispReader.read(LispReader.java:263)
        at clojure.lang.LispReader.read(LispReader.java:196)
        at clojure.lang.LispReader.read(LispReader.java:185)
        at clojure.lang.RT.readString(RT.java:1821)
        at clojure.lang.RT.readString(RT.java:1816)
        at clojure.core$read_string.invoke(core.clj:3663)
        at cljs.repl.server$dispatch_request.invoke(server.clj:148)
        at cljs.repl.server$handle_connection.invoke(server.clj:157)
        at cljs.repl.server$server_loop$fn__5056.invoke(server.clj:167)
        at clojure.core$binding_conveyor_fn$fn__4444.invoke(core.clj:1916)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.lang.Thread.run(Thread.java:745)

Comment by Mike Fikes [ 31/Jan/16 8:34 PM ]

I tried reproducing with the attached cljs-hello-world.tar.gz, revising the IP address to be localhost, and running everything on my local Mac with Chrome 48.0.2564.97, and I was unable to repro.

Perhaps, since this involved a network connection between AWS and your local Mac, the connection was closed during the phase when it was reading the response? In other words, I wonder if this is reproducible in general or was just a connectivity outage.

Comment by Scott Bale [ 08/Feb/16 8:33 PM ]

Thanks for checking on that Mike. I'm also unable to reproduce the crash if I run my example locally on a macbook pro (Chrome 48.0.2564.97 also; Mac's Java 8 build 1.8.0_65-b17).

However, the original behavior I'm seeing is not sporadic; it is reproducible 100% of the time. I was able to reproduce it again just now. So I guess the next step would be for me to build a debug version of cljs.jar which provides some insight into what is tripping up the LispReader$StringReader.

Comment by David Nolen [ 12/Feb/16 2:29 PM ]

Patch welcome for this one, not really use case we ever had in mind for Browser REPL.

Comment by Scott Bale [ 05/Mar/16 1:16 PM ]

I've tinkered around with this enough to satisfy myself that it is nothing to do with cljs. Sorry for the distraction.

Fwiw: I have a small clj test script that reads the body of a POST (similar to cljs browser repl env). If I run that within an ec2 instance, and send a POST from outside of ec2, then about half the time a large chunk of the post body is truncated. Length is reported correctly in header, but a bunch of characters are just missing. Openjdk bug? >shrug<

[CLJS-1592] Self-host: Robustness for core tests Created: 25/Feb/16  Updated: 18/Mar/16  Resolved: 18/Mar/16

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Mike Fikes Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: bootstrap

Attachments: Text File CLJS-1592.patch    
Patch: Code and Test


There are a couple minor things that can be improved in the core tests which facilitates running them in bootstrapped environments:

1. Restore *print-newline*
2. Add a little more order robustness for hash-based collections

Will attach patch for consideration.

Comment by David Nolen [ 18/Mar/16 1:38 PM ]

fixed https://github.com/clojure/clojurescript/commit/ba18d9f72e946114199471f6a3e50498ad9792ee

[CLJS-1597] Redundant IPrintWithWriter test in pr-writer-impl Created: 03/Mar/16  Updated: 11/Mar/16  Resolved: 11/Mar/16

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.228
Fix Version/s: None

Type: Defect Priority: Trivial
Reporter: Mike Fikes Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File CLJS-1597.patch    
Patch: Code


This cond branch cannot be followed


owing to this test


and can be removed as effectively dead code.

Comment by David Nolen [ 11/Mar/16 1:08 PM ]

fixed https://github.com/clojure/clojurescript/commit/032077b52fd7c4359f18004f14faadab0d1a0782

Generated at Wed May 25 08:14:49 CDT 2016 using JIRA 4.4#649-r158309.