<< Back to previous view

[CLJS-882] cljs.reader/read-string throws errors when reading keywords that begin with integers Created: 05/Nov/14  Updated: 02/Dec/14  Resolved: 02/Dec/14

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

Type: Defect Priority: Minor
Reporter: Joseph Fahey Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: keywords, reader
Environment:

Using clojurescript 0.0-2371. Error seen with both phantomjs and Chrome



 Description   

(cljs.reader/read-string ":1") throws an error: TypeError: 'null' is not an object (evaluating 'a[(0)]')
at read_keyword (:474)



 Comments   
Comment by Joseph Fahey [ 05/Nov/14 4:10 PM ]

read-keyword, in reader.cljs, matches against symbol-pattern, which disallows symbol names that begin with numbers. Symbols can't begin with numeric characters, but keywords actually begin with ":", so in a keyword like :1 , "1" is actually the second character.

Comment by Francis Avila [ 05/Nov/14 8:01 PM ]

Your reasoning that in a keyword the number is the second character is precisely one of the unclear points about keyword and symbol parsing. Some implementations say yes, and some do not, and there is no "spec" unambiguous enough to decide the issue.

This issue is a duplicate of CLJS-677. The comments in there go in to much greater detail.

Comment by Joseph Fahey [ 06/Nov/14 2:52 AM ]

I'll leave it at that then.

I would like to add that the current state of affairs is rather confusing, because keywords like :1 seem to work fine in clojurescript, except when deserializing with cljs.reader/read-string, from localStorage for example, which fails without a clear explanation.

Comment by Francis Avila [ 06/Nov/14 12:19 PM ]

Agreed, the current state of affairs is not good but the proper fix would be:

  1. Produce a rigorous formal specification of the reader syntax for Clojure (and variants/subsets for edn, Clojurescript, ClojureCLR). (Including consideration of unicode chars, etc.)
  2. Unifying all reader implementations around these specifications (across multiple projects).
  3. Dealing with code breakage in upstream libraries.

Understandably the core developers would probably think this is a very large effort with a lot of disruption for very little gain. I advise just avoiding edge cases in the spec, like :1, :supposedly:ok:keyword, non-ascii characters, etc, in both code and edn.

Comment by Joseph Fahey [ 07/Nov/14 4:15 AM ]

One last thing about the confusion this causes. The problem I see is that {:1 "one"} compiles without any problem in Clojurescript, (keyword? :1} returns true, and (keyword "1") returns :1. The only time the problem comes up is when using reader/read-string. It seems to me that this should be coherent at least within Clojurescript, even if there are discrepancies with the other implementations.

And when using :keywordize :true with externally supplied data, it is hard to be sure that some of the JSON keys won't begin with a digit. (This is how I stumbled onto this.)





[CLJS-671] Inconsistencies when calling 'name' on keywords from strings vs literal keywords Created: 08/Nov/13  Updated: 09/Nov/13  Resolved: 08/Nov/13

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

Type: Defect Priority: Major
Reporter: Joseph Smith Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: keywords
Environment:

Clojurescript r2024; Java 1.7.0_25; OSX 10.9



 Description   

Clojurescript:
1. (keyword "some.name.spaced/keyword")
:some.name.spaced/keyword

2. (name (keyword "some.name.spaced/keyword"))
"some.name.spaced/keyword"

3. (name :some.name.space/keyword)
"keyword"

I'd expect 2 and 3 to return the same string, given 1 returns what looks like the keyword I give to 3.

In contrast to Clojure:
(keyword "some.name.spaced/keyword")
:some.name.spaced/keyword

(name (keyword "some.name.spaced/keyword"))
"keyword"

(name :some.name.space/thing)
"thing"



 Comments   
Comment by David Nolen [ 08/Nov/13 4:52 PM ]

CLJS-660





[CLJS-660] keyword fn in single-arg form produces nil namespace kw for str and symbols Created: 04/Nov/13  Updated: 09/Nov/13  Resolved: 09/Nov/13

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

Type: Defect Priority: Minor
Reporter: Francis Avila Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: keywords
Environment:

cljs r1978



 Description   

In Clojurescript, keyword called with a single non-keyword argument always produces a nil-namespace keyword. This is inconsistent with Clojure (although the clojure docs don't mention anything about parsing strings for namespaces).

(-> 'a.b keyword ((juxt namespace name)))
;=> [nil "a.b"]
(-> 'a.b/c keyword ((juxt namespace name)))
;=> ["a.b" "c"]
(-> "a.b" keyword ((juxt namespace name)))
;=> [nil "a.b"]
(-> "a.b/c" keyword ((juxt namespace name)))
;=> ["a.b" "c"]
(-> "/c" keyword ((juxt namespace name)))
;=> ["" "c"]
(-> (symbol "/c") keyword ((juxt namespace name)))
;=> ["" "c"]

Compare with cljs:

(-> 'a.b keyword ((juxt namespace name)))
;=> [nil "a.b"]
(-> 'a.b/c keyword ((juxt namespace name)))
;=> [nil "c"]
(-> "a.b" keyword ((juxt namespace name)))
;=> [nil "a.b"]
(-> "a.b/c" keyword ((juxt namespace name)))
;=> [nil "a.b/c"]
(-> "/c" keyword ((juxt namespace name)))
;=> [nil "/c"]
(-> (symbol "/c") keyword ((juxt namespace name)))
;=> [nil "/c"]

Suggested (untested) patch:

cljs/cljs/core.cljs
(defn keyword
  "Returns a Keyword with the given namespace and name.  Do not use :
  in the keyword strings, it will be added automatically."
  ([name] (cond
            (keyword? name) name
            (symbol? name) (Keyword. (namespace name) (cljs.core/name name)
                                     (str name) nil)
            (string? name) (let [idx (.indexOf name "/")
                                 [ns n] (if (= -1 idx)
                                          [nil name]
                                          [(subs name 0 idx) (subs name idx)])]
                             (Keyword. ns n name nil))
            :else (Keyword. nil name name nil)))
  ([ns name] (Keyword. ns name (str (when ns (str ns "/")) name) nil)))


 Comments   
Comment by Francis Avila [ 04/Nov/13 5:48 PM ]

[(subs name 0 idx) (subs name idx)] above should be [(subs name 0 idx) (subs name (inc idx))]

Comment by David Nolen [ 06/Nov/13 12:46 PM ]

Real patch welcome with tests included, thanks!

Comment by David Nolen [ 08/Nov/13 5:01 PM ]

I don't consider the /foo cases to be valid.

Comment by David Nolen [ 09/Nov/13 3:37 PM ]

fixed, https://github.com/clojure/clojurescript/commit/dc2bb860560a88ad2807faee16f8ba948e488c73





[CLJS-623] Keyword dosen't work as a function of map Created: 16/Oct/13  Updated: 20/Oct/13  Resolved: 20/Oct/13

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

Type: Defect Priority: Minor
Reporter: Andrzej Fricze Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: keywords, lookup, maps
Environment:

Compiling with [org.clojure/clojurescript "0.0-1934"]. Using Light Table to develop.



 Description   

String version access to map

("a" {"a" "ala" :b "bala"}) ;; returns "ala"

unfortunately, the keyword version

(:b {"a" "ala" :b "bala"}) ;; returns nil

I've tried using keyword as function of map, and map as a function with keyword arg. Even using vector as a key in a map works properly, only if map is called with key arg, but still, it works

({[1 2] "ala" :c "bala"} [1 2]) ;; returns "ala"

({"a" "ala" :b "bala"} :b) ;; still nil



 Comments   
Comment by Travis Thieman [ 17/Oct/13 10:39 AM ]

Using the latest version of ClojureScript and script/repl and script/repljs, I observe the following:

1. Your first string example doesn't work in either Clojure or ClojureScript. This is expected behavior as far as I know; you can't access maps using a string the same way you can with a keyword.

2. Your second example, (:b {"a" "ala" :b "bala"}) works fine for me in both Clojure and ClojureScript REPLs.

3. Third example works fine.

4. Fourth example returns "bala" for me in both REPLs.

If you are actually seeing this behavior, my guess would be that the issue is with Light Table. Can you reproduce this in a REPL outside of Light Table?

Comment by Andrzej Fricze [ 18/Oct/13 4:08 PM ]

I've checked in ClojureScript REPL and it works, indeed. You're right, it must be Light Table case. Very sorry for interrupting then.





[CLJS-576] Implement Reified Keywords Created: 26/Aug/13  Updated: 08/Sep/13  Resolved: 08/Sep/13

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

Type: Enhancement Priority: Major
Reporter: Sean Grove Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: cljs, keywords

Attachments: Text File real_keywords.patch    

 Description   

Implement real/reified keywords in ClojureScript so we can stop modifying the String.prototype for strings-as-keywords. Attached patch does that.

One potential notice for the community is that `("a" {"a" 10})` previously worked in ClojureScript before this patch (though not on the jvm).



 Comments   
Comment by David Nolen [ 08/Sep/13 6:26 PM ]

fixed, http://github.com/clojure/clojurescript/commit/2cef52840fcd9d88f077d374cc81e50c7e645b9f
http://github.com/clojure/clojurescript/commit/2e8b32aa28399c69500e511377b1841a6679c9f2





Generated at Thu Dec 18 05:40:14 CST 2014 using JIRA 4.4#649-r158309.