replete-repl / replete-ios

ClojureScript REPL iOS app
Eclipse Public License 1.0
396 stars 25 forks source link

Issue with zero : Invalid number format [0] #8

Closed hiram-madelaine closed 9 years ago

hiram-madelaine commented 9 years ago

The literal 0 can not be used in expressions :

(+ 1 0)
(take 10 (iterate inc 0))

with the stack trace :

nvalid number format [0]
cljs$core$ExceptionInfo@file:///cljs/core.js:33152:19
cljs$core$IFn$_invoke$arity$3@file:///cljs/core.js:33214:36
cljs$core$IFn$_invoke$arity$2@file:///cljs/core.js:33210:55
cljs$core$ex_info@file:///cljs/core.js:33196:55
cljs$core$IFn$_invoke$arity$variadic@file:///cljs/tools/reader/reader_types.js:802:29
cljs$tools$reader$reader_types$reader_error@file:///cljs/tools/reader/reader_types.js:798:88
cljs$tools$reader$read_number@file:///cljs/tools/reader.js:459:56
file:///cljs/tools/reader.js:1578:42
cljs$tools$reader$reader_types$log_source@file:///cljs/tools/reader/reader_types.js:873:20
cljs$tools$reader$target@file:///cljs/tools/reader.js:1556:54
file:///cljs/core.js:30462:108
cljs$core$IFn$_invoke$arity$1@file:///cljs/core.js:30463:3
cljs$core$trampoline@file:///cljs/core.js:30450:58
file:///cljs/tools/reader.js:1565:33
cljs$tools$reader$reader_types$log_source@file:///cljs/tools/reader/reader_types.js:873:20
cljs$tools$reader$target@file:///cljs/tools/reader.js:1556:54
cljs$core$IFn$_invoke$arity$6@file:///cljs/tools/reader.js:1598:8
cljs$tools$reader$read_STAR_@file:///cljs/tools/reader.js:1541:66
cljs$tools$reader$read_delimited@file:///cljs/tools/reader.js:350:45
cljs$tools$reader$read_list@file:///cljs/tools/reader.js:373:53
file:///cljs/tools/reader.js:1582:17
cljs$tools$reader$reader_types$log_source@file:///cljs/tools/reader/reader_types.js:873:20
cljs$tools$reader$target@file:///cljs/tools/reader.js:1556:54
file:///cljs/core.js:30462:108
cljs$core$IFn$_invoke$arity$1@file:///cljs/core.js:30463:3
cljs$core$trampoline@file:///cljs/core.js:30450:58
file:///cljs/tools/reader.js:1565:33
cljs$tools$reader$reader_types$log_source@file:///cljs/tools/reader/reader_types.js:873:20
cljs$tools$reader$target@file:///cljs/tools/reader.js:1556:54
cljs$core$IFn$_invoke$arity$6@file:///cljs/tools/reader.js:1598:8
cljs$tools$reader$read_STAR_@file:///cljs/tools/reader.js:1541:66
cljs$tools$reader$read_delimited@file:///cljs/tools/reader.js:350:45
cljs$tools$reader$read_list@file:///cljs/tools/reader.js:373:53
file:///cljs/tools/reader.js:1582:17
cljs$tools$reader$reader_types$log_source@file:///cljs/tools/reader/reader_types.js:873:20
cljs$tools$reader$target@file:///cljs/tools/reader.js:1556:54
file:///cljs/core.js:30462:108
cljs$core$IFn$_invoke$arity$1@file:///cljs/core.js:30463:3
cljs$core$trampoline@file:///cljs/core.js:30450:58
file:///cljs/tools/reader.js:1565:33
cljs$tools$reader$reader_types$log_source@file:///cljs/tools/reader/reader_types.js:873:20
cljs$tools$reader$target@file:///cljs/tools/reader.js:1556:54
cljs$core$IFn$_invoke$arity$6@file:///cljs/tools/reader.js:1598:8
cljs$tools$reader$read_STAR_@file:///cljs/tools/reader.js:1541:66
cljs$tools$reader$read_delimited@file:///cljs/tools/reader.js:350:45
cljs$tools$reader$read_list@file:///cljs/tools/reader.js:373:53
file:///cljs/tools/reader.js:1582:17
cljs$tools$reader$reader_types$log_source@file:///cljs/tools/reader/reader_types.js:873:20
cljs$tools$reader$target@file:///cljs/tools/reader.js:1556:54
cljs$core$IFn$_invoke$arity$6@file:///cljs/tools/reader.js:1598:8
cljs$tools$reader$read_STAR_@file:///cljs/tools/reader.js:1541:66
cljs$core$IFn$_invoke$arity$2@file:///cljs/tools/reader.js:1665:41
cljs$tools$reader$read@file:///cljs/tools/reader.js:1643:60
cljs$core$IFn$_invoke$arity$2@file:///cljs/tools/reader.js:1711:35
cljs$tools$reader$read_string@file:///cljs/tools/reader.js:1690:67
cljs$core$IFn$_invoke$arity$1@file:///cljs/tools/reader.js:1700:42
cljs$tools$reader$read_string@file:///cljs/tools/reader.js:1686:67
replete$core$read_eval_print@file:///replete/core.js:40:46
ulsa commented 9 years ago

I see this too.

bsvingen commented 9 years ago

I get this by evaluating 0 alone.

kanaka commented 9 years ago

I can verify that this happens in the plain bootstrapped REPL too:

cljs-bootstrap.repl> 0
Error
    at new cljs$core$ExceptionInfo (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33157:10)
    at Function.cljs.core.ex_info.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33219:9)
    at Function.cljs.core.ex_info.cljs$core$IFn$_invoke$arity$2 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33215:26)
    at cljs$core$ex_info (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33201:26)
    at Function.cljs.tools.reader.reader_types.reader_error.cljs$core$IFn$_invoke$arity$variadic (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader/reader_types.js:802:25)
    at cljs$tools$reader$reader_types$reader_error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader/reader_types.js:798:52)
    at cljs$tools$reader$read_number (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader.js:442:52)
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader.js:1546:38
    at cljs$tools$reader$reader_types$log_source (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader/reader_types.js:873:16)
    at cljs$tools$reader$target (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader.js:1524:50)
kanaka commented 9 years ago

http://dev.clojure.org/jira/browse/CLJS-1326

asheldo commented 9 years ago

I think confirming what David said in CLJS-1326... on the left are reader.js and tools/reader.js from the cljs-bootstrap-kanaka, and on the right are the same from cljs-bootstrap. You can see bottom-left that the kanaka tools/reader.js is the one missing the wrapping truth_ calls (can't say that I grok the purpose of reader versus tools/reader):

tools and tools reader

mfikes commented 9 years ago

If cljs.reader is used, 0 works, but ::x fails to expand.

mfikes commented 9 years ago
(cljs.tools.reader/read-string "0")

produces the error, while

(cljs.reader/read-string "0")

produces 0

asheldo commented 9 years ago

One way to get zero working in cljs-bootstrap-kanaka, and I assume replete: rebuild clojurescript with the compiler.cljc "unchecked" condition removed in the :if emitter. Bootstrapped tools/reader.js will then include the expected cljs.core.truth_ wrappers. (Presumably the unchecked-if atom is not getting reset to false.)

diff --git a/src/main/clojure/cljs/compiler.cljc b/src/main/clojure/cljs/compiler.cljc
index 0d815a4..fea5780 100644
--- a/src/main/clojure/cljs/compiler.cljc
+++ b/src/main/clojure/cljs/compiler.cljc
@@ -415,7 +415,9 @@
 (defmethod emit* :if
   [{:keys [test then else env unchecked]}]
   (let [context (:context env)
-        checked (not (or unchecked (safe-test? env test)))]
+        checked (not (or 
+           ;; unchecked ;; Workaround replete issue #8
+           (safe-test? env test)))]
     (cond
       (truthy-constant? test) (emitln then)
       (falsey-constant? test) (emitln else)
mfikes commented 9 years ago

@kanaka Found a workaround. TL;DR: build main file before macros

[08:07 PM]  <mfikes>    dnolen: Yep. I took a look at the "0" reader issue and couldn't repro it with your cljs-bootstrap repo. It vexes me, and thus must be squashed.
[08:07 PM]  <mfikes>    I have a handful of others in addition to that one to attempt to sort through.
[08:08 PM]  <dnolen>    mfikes: it looks to me like something weird with Joel's build proces
[08:08 PM]  <dnolen>    it's not clear to me how that code could ever get generated
[08:08 PM]  <mfikes>    Yeah... I'll spend some time on it. It is fortunately deterministic. :)
[08:10 PM]  <dnolen>    some hints
[08:10 PM]  <dnolen>    if the compiler cannot infer that the type of a value is boolean it protects primitive boolean tests with a call to cljs.core.truth_
[08:10 PM]  <dnolen>    this is to catch cases like
[08:10 PM]  <dnolen>    if(cljs.core.truth_(0)) { ... }
[08:11 PM]  <dnolen>    0 is true in Clojure(Script) false in JavaScript
[08:11 PM]  <mfikes>    dnolen: Ahh that helps. I didn't even know inference was part of the game. Cool!
[08:11 PM]  <dnolen>    only if the the compiler can prove that the value is boolean OR if something set!s *unchecked-if* to true
[08:11 PM]  <dnolen>    can you end up with
[08:12 PM]  <dnolen>    if(0) { ... }
[08:12 PM]  <dnolen>    again, ClojureScript never generates such a thing, but somehow Joel's tools.reader got corrupted
[08:12 PM]  <dnolen>    perhaps because it was generated from a bootstrapped thing? I don't know.
[08:14 PM]  <mfikes>    dnolen: I got it too, from your tools.reader, in Replete. I'll dig into it.
[08:16 PM]  <dnolen>    mfikes: right but I don't see it in when I compile tools.reader via cljs-bootstrap
[08:18 PM]  <mfikes>    dnolen: Yeah. Someone commented on a Replete ticket, showing it in the lower-left corner. I'll get to the bottom of it. :) https://github.com/mfikes/replete/issues/8#issuecomment-118623935
[08:21 PM]  <mfikes>    My best hunch is :static-fns or somesuch... we'll see
[08:25 PM]  <dnolen>    mfikes: yes, I noticed something weird today around :static-fns
[08:25 PM]  <dnolen>    not a lack of call to truth but weird interaction with boolean inference.
[10:07 PM]  <mfikes>    dnolen: I have a solution to the "0" problem, even though I don't yet understand why. I copied Joel's build script into Replete, and the issue occurs at build time when running that build.clj. If I move this (macros) line down so that it compiles "cljs/core.cljc" after "replete/core.cljs" (which is the namespace requiring tools reader), then it works: https://github.com/mfikes/replete/blob/master/ClojureScript/replete/script/build.clj#L37
[10:08 PM]  <mfikes>    dnolen: I only tried this based on your suggestion of statefulness of *unchecked-if*
[10:22 PM]  <dnolen>    mfikes: right probably just a bug some where around *unchecked-if*
[10:22 PM]  <mfikes>    dnolen: I did the due-dilligence to see if it was inadvertently flipped on... no avail. Anyway, I'm glad I have a workaround for now.