<< Back to previous view

[CLJS-1328] Support defrecord reader tags Created: 04/Jul/15  Updated: 04/Jul/15

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

Type: Enhancement Priority: Major
Reporter: Herwig Hochleitner Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: reader, readertags


 Description   

Currently, defrecord instances print similar to how they do in clojure

> (pr-str (garden.units/px 5))
#garden.types.CSSUnit{:unit :px, :magnitude 5}

This representation cannot be read by the compiler, nor at runtime by cljs.reader/read-string

> #garden.types.CSSUnit{:unit :px, :magnitude 5}
clojure.lang.ExceptionInfo: garden.types.CSSUnit {:type :reader-exception, :line 1, :column 22, :file "NO_SOURCE_FILE"}
...
> (cljs.reader/read-string "#garden.types.CSSUnit{:unit :px, :magnitude 5}")
#<Error: Could not find tag parser for garden.types.CSSUnit in ("inst" "uuid" "queue" "js")>
...

Analysis

The two requirements - using record literals in cljs source code and supporting runtime reading - can be addressed by using the analyzer to find defrecords and registering them with the two respective reader libraries.

Record literals

Since clojurescript reads and compiles a file at a time, clojure's behavior for literals is hard to exactly mimic. That is, to be able to use the literal in the same file where the record is defined.
A reasonable compromise might be to update the record tag table after each file has been analyzed. Thus the literal form of a record could be used only in requiring files.

EDIT: Record literals can also go into the constant pool

cljs.reader

To play well with minification, the ^:export annotation could be reused on defrecords, to publish the corresponding reader tag to cljs.reader.

Related Tickets






[CLJS-1327] Use Transit JSON for analysis caches Created: 03/Jul/15  Updated: 03/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

Type: Task Priority: Minor
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

A significant amount of time is spent reading caches both during cold builds and REPL start. Switching to Transit for the analysis cache format should deliver a very large performance boost.






[CLJS-1326] In bootstrapped cljs, read-number of "0" gives "invalid number format" Created: 03/Jul/15  Updated: 03/Jul/15  Resolved: 03/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: Next
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Joel Martin Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bootstrap
Environment:

cljs-bootstrap REPL (https://github.com/kanaka/cljs-bootstrap)



 Description   

tools.reader/read-number (https://github.com/swannodette/tools.reader) of "0" throws an error. The same for "1" works fine.

cljs-bootstrap.repl> 0
Error: Invalid number format [0]
    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:446:52)
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/tools/reader.js:1550: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:1528:50)

This is because reader/read-number has:

(or (match-number s) (reader-error rdr "Invalid number format [" s "]")))

which compiled to this JS:

var or__4073__auto__ = cljs.tools.reader.impl.commons.match_number.call(null,s);
if(or__4073__auto__){
return or__4073__auto__;
} else {
return cljs.tools.reader.reader_types.reader_error.call(null,rdr,"Invalid number format [",s,"]");
}

Since match_number returns a JS number, or_4073auto_ is 0, therefore falsey.



 Comments   
Comment by Joel Martin [ 03/Jul/15 9:31 AM ]

FYI, to reproduce, run this in https://github.com/kanaka/cljs-bootstrap

lein run -m clojure.main script/build.clj
node repl.js
cljs-bootstrap.repl> 0
Error: Invalid number format [0]
...
Comment by David Nolen [ 03/Jul/15 2:55 PM ]

This ticket doesn't have nearly enough information. I checked the output of tools.reader and I don't see this generated code at all. The test is wrapped in the required call to truth_.





[CLJS-1325] defrecord broken in bootstrapped cljs (error during set!) Created: 03/Jul/15  Updated: 03/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: Next
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Joel Martin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bootstrap
Environment:

cljs-bootstrap node.js RELP (https://github.com/kanaka/cljs-bootstrap)



 Description   

This is a follow-on to http://dev.clojure.org/jira/browse/CLJS-1321 for getting defrecord to work in the bootstrap node REPL.

cljs-bootstrap.repl> (defprotocol IFoo (foo [this]))
nil
cljs-bootstrap.repl> (defrecord Baz [b] IFoo (foo [this] (prn "some baz:" b)))
Error: Can't set! local var or non-mutable field
    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 cljs$core$ex_info (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33205:26)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:699:26)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:685:28)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$2 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:695:28)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:681:28)
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2311:27
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2315:3
    at cljs.core.MultiFn.call.G__11387__6 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:31419:149)

The same as above but with debug added to the analyzer set! method to print the form:

cljs-bootstrap.repl> (defprotocol IFoo (foo [this]))
DEBUG set! p__9852: (set! *unchecked-if* true)
DEBUG set! p__9852: (set! *unchecked-if* false)
nil
cljs-bootstrap.repl> (defrecord Baz [b] IFoo (foo [this] (prn "some baz:" b)))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ILookup$-lookup$arity$2) (cljs.core$macros/fn ([this__7850__auto__ k__7851__auto__] (cljs.core$macros/this-as this__7850__auto__ (cljs.core/-lookup this__7850__auto__ k__7851__auto__ nil)))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ICollection$-conj$arity$2) (cljs.core$macros/fn ([this__7855__auto__ entry__7856__auto__] (cljs.core$macros/this-as this__7855__auto__ (if (cljs.core/vector? entry__7856__auto__) (cljs.core/-assoc this__7855__auto__ (cljs.core/-nth entry__7856__auto__ 0) (cljs.core/-nth entry__7856__auto__ 1)) (cljs.core/reduce cljs.core/-conj this__7855__auto__ entry__7856__auto__))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ILookup$-lookup$arity$3) (cljs.core$macros/fn ([this__7852__auto__ k25 else__7853__auto__] (cljs.core$macros/this-as this__7852__auto__ (cljs.core$macros/case k25 :b b (cljs.core/get __extmap k25 else__7853__auto__))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$IPrintWithWriter$-pr-writer$arity$3) (cljs.core$macros/fn ([this__7864__auto__ writer__7865__auto__ opts__7866__auto__] (cljs.core$macros/this-as this__7864__auto__ (cljs.core$macros/let [pr-pair__7867__auto__ (cljs.core$macros/fn [keyval__7868__auto__] (cljs.core/pr-sequential-writer writer__7865__auto__ cljs.core/pr-writer "" " " "" opts__7866__auto__ keyval__7868__auto__))] (cljs.core/pr-sequential-writer writer__7865__auto__ pr-pair__7867__auto__ "#cljs-bootstrap.repl.Baz{" ", " "}" opts__7866__auto__ (cljs.core/concat [(cljs.core/vector :b b)] __extmap)))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$IMeta$-meta$arity$1) (cljs.core$macros/fn ([this__7848__auto__] (cljs.core$macros/this-as this__7848__auto__ __meta))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ICloneable$-clone$arity$1) (cljs.core$macros/fn ([this__7844__auto__] (cljs.core$macros/this-as this__7844__auto__ (new Baz b __meta __extmap __hash)))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$ICounted$-count$arity$1) (cljs.core$macros/fn ([this__7854__auto__] (cljs.core$macros/this-as this__7854__auto__ (cljs.core$macros/+ 1 (cljs.core/count __extmap))))))
DEBUG set! p__9852: (set! (.. Baz -prototype -cljs$core$IHash$-hash$arity$1) (cljs.core$macros/fn ([this__7845__auto__] (cljs.core$macros/this-as this__7845__auto__ (cljs.core$macros/caching-hash this__7845__auto__ hash-imap __hash)))))
DEBUG set! p__9852: (set! __hash h__7674__auto__)
Error: Can't set! local var or non-mutable field
    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 cljs$core$ex_info (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:33205:26)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$3 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:699:26)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:685:28)
    at Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$2 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:695:28)
    at cljs$analyzer$error (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:681:28)
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2312:27
    at /home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/analyzer.js:2316:3
    at cljs.core.MultiFn.call.G__11387__6 (/home/joelm/scratch/cljs-bootstrap/.cljs_bootstrap/cljs/core.js:31419:149)


 Comments   
Comment by Joel Martin [ 03/Jul/15 9:31 AM ]

FYI, to reproduce, run this in https://github.com/kanaka/cljs-bootstrap

lein run -m clojure.main script/build.clj
node repl.js
cljs-bootstrap.repl> (defprotocol IFoo (foo [this]))
cljs-bootstrap.repl> (defrecord Baz [b] IFoo (foo [this] (prn "some baz:" b)))
Error: Can't set! local var or non-mutable field
...




[CLJS-1324] Compiler fails to raise warning/error when invoking a keyword without arguments Created: 02/Jul/15  Updated: 02/Jul/15

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

Type: Defect Priority: Minor
Reporter: Sean Grove Assignee: Sean Grove
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Invoking a keyword with no arguments doesn't raise a warning/error in the compiler, but it likely should, e.g `(:any-key)`

It raises an error in the browser: "Uncaught TypeError: (intermediate value).cljs$core$IFn$_invoke$arity$0 is not a function".






[CLJS-1323] possible to reload cljs.core in browser REPL Created: 01/Jul/15  Updated: 02/Jul/15  Resolved: 02/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: Next

Type: Defect Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Not Reproducible Votes: 0
Labels: None


 Description   

Accidentally doing so will wreck havoc on the browser REPL as all the core types will get redefined. For some reason cljs.core is the only namespace that is not on the goog.dependencies_.written list, once as the relative path and once again as the absolute path. Uncovered while attempting to test the bootstrap support in browser environments.



 Comments   
Comment by David Nolen [ 02/Jul/15 6:02 PM ]

Misinterpreted the issue. Was loading the macros ns which shares the same name. Needed to rewrite in to a macro ns instead.





[CLJS-1322] Investigate why Babel cannot load into JDK 8 Nashorn Created: 01/Jul/15  Updated: 01/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: GSoC
Fix Version/s: None

Type: Task Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It appears neither the developer browser.js file nor the browser.min.js file can be loaded into Nashorn due to a method size limit exception. The code appears to originate around the lodash include. This may be a red herring but this is a good starting point for investigation.






[CLJS-1321] defrecord broken in bootstrapped cljs Created: 01/Jul/15  Updated: 02/Jul/15  Resolved: 02/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: Next
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Joel Martin Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: bootstrap
Environment:

cljs-bootstrap REPL (https://github.com/swannodette/cljs-bootstrap)



 Description   

First problem that I run into is that emit-defrecord makes use of .getNamespace and .getName on rname. That should probably be (namespace rname) and (name rname). After that change is made the next error is "Can't set! local var or non-mutable field" somewhere in defrecord. Not sure what the cause of that one is.



 Comments   
Comment by David Nolen [ 02/Jul/15 6:03 PM ]

fixed https://github.com/clojure/clojurescript/commit/8a5023b849cfc509931b3ff509a9f7ee48dd03ec

Comment by David Nolen [ 02/Jul/15 6:04 PM ]

I did not look into the set! issue. Separate ticket should be opened for that if it persists.

Comment by Mike Fikes [ 02/Jul/15 6:46 PM ]

Confirmed fixed downstream (https://github.com/mfikes/replete/issues/25), apart from other Can't set! local var or non-mutable field error, which needs a separate ticket.





Generated at Mon Jul 06 02:24:58 CDT 2015 using JIRA 4.4#649-r158309.