clojure-dev

Issues: https://clojure.atlassian.net/browse/CLJ | Guide: https://insideclojure.org/2015/05/01/contributing-clojure/
2020-10-10T18:35:22.039300Z

hello everyone, quick question. As I was working on the grammar definition of Clojure’s symbols and keywords for my project (parcera) I received this report about symbols being allowed to have more than one / character. Although I have seen this for keywords I didnt think it was possible for symbols. Is this a bug? or is it also “tolerated” for backwards compatibility :thinking_face: • here is the example code: https://github.com/VladimirMarkovic86/ocr-lib/blob/master/src/clj/ocr_lib/core.clj#L13 • here is the report and reproduction case: https://github.com/carocad/parcera/pull/94#issuecomment-706546263

dominicm 2020-10-10T18:40:47.040Z

Just a thought: clojure.core// :)

2020-10-10T19:03:39.040100Z

yep I am aware of that one. However in that case the namespace/simple-name still applies. The problem is something like foo/bar/baz . Which part is the namespace and which the name?

2020-10-10T19:04:19.040300Z

just to be clear, I am talking about a literal simbol, not one made with (symbol ns name) 😉

dominicm 2020-10-10T19:05:26.040500Z

> '/' has special meaning, it can be used once in the middle of a symbol to separate the namespace from the name, e.g. my-namespace/foo. '/' by itself names the division function. Troll answer: whichever one is nearest the middle :D

😅 1
2020-10-10T19:07:13.041400Z

That code in ocr-lib is nonsense

dominicm 2020-10-10T19:11:54.042800Z

user=> (re-matches symbolPat "clojure.core//")
["clojure.core//" "clojure.core/" "/"]
user=> (re-matches symbolPat "clojure.core/foo")
["clojure.core/foo" "clojure.core/" "foo"]
user=> (re-matches symbolPat "clojure.core/foo/bar")
["clojure.core/foo/bar" "clojure.core/foo/" "bar"]
user=> 
I'm sure you tried this, but the source regex is quite useful actually. Explains why // works

dominicm 2020-10-10T19:12:53.043Z

Oh wow, I'm surprised that works…

user=> (import '[java.util Base64])
java.util.Base64
user=> (Base64/Decoder/getDecoder)
#object[java.util.Base64$Decoder 0x1237e0be "java.util.Base64$Decoder@1237e0be"]
user=> 
Gonna have to poke at how that resolves

2020-10-10T19:19:26.043400Z

I actually didnt try that 😅 . Good to know. However that regex could be seen as “an implementation detail”. In parcera I dont use them anymore because the LispReader has a lot of other checks for most tokens

dominicm 2020-10-10T19:20:21.043600Z

Hmm, annoyingly it seems that Clojure actually behaves differently in the reader and clojure.lang.Symbol.

dominicm 2020-10-10T19:20:59.044Z

different behavior

2020-10-10T19:28:35.044200Z

I did poke around but didnt understand it. Decoder is a public static class inside Base64 class. However, Decoder doesnt have a getDecoder static method. Only Base64 has :man-shrugging::skin-tone-4:

dominicm 2020-10-10T19:33:57.044400Z

So this should really be Base64$Decoder/getDecoder I guess?

dominicm 2020-10-10T19:34:19.044600Z

Oh, no. I see what you mean

dominicm 2020-10-10T19:34:22.044800Z

Is the Decoder just ignored then?

dominicm 2020-10-10T19:34:44.045Z

Lol, yes:

user=> (Base64/flibbetygibbit/getDecoder)
#object[java.util.Base64$Decoder 0x1d25c1c "java.util.Base64$Decoder@1d25c1c"]
user=> 

2020-10-10T19:35:03.045200Z

oh I didnt try that 😆

dominicm 2020-10-10T19:59:28.045400Z

OK, figured it out I think:

user=> (Base64/flibbetygibbit/getDecoder)
sym: flibbetygibbit/getDecoder (flibbetygibbit / getDecoder)
From (flibbetygibbit/getDecoder)
Form: (. Base64 flibbetygibbit/getDecoder)
methodName: getDecoder

dominicm 2020-10-10T19:59:53.045600Z

It's ignored by Clojure because clojure gets the name of the symbol, because it basically just wants a string

dominicm 2020-10-10T20:00:03.045800Z

So by coincidence, it ignores the namespace in this form

2020-10-10T20:04:08.047900Z

It appears you can use full name java.util.Base64$Decoder to name that Java class, but there doesn't seem to be a shorter way to refer to it, no matter what import statements you use.

dpsutton 2020-10-10T20:06:56.048200Z

helpful information from alex the other day about this

dominicm 2020-10-10T20:07:03.048500Z

@andy.fingerhut fwiw, the Decoder is completely ignored :) (Base64/foobarbaz/getDecoder) works just as well. It should be (Base64/getDecoder). It works because it expands to (. Base64 foobarbaz/getDecoder) and the Compiler uses the name of the symbol at the 3rd position.

2020-10-10T20:07:20.048600Z

But strangely enough, you cannot use the full name to refer to the getDecoder method in that class. Maybe I misunderstand the JVM docs for that class, though.

2020-10-10T20:10:01.048800Z

Doh. the getDecoder method is a method of class java.util.Base64. I think it makes more sense to me now.