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
Just a thought: clojure.core// :)
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?
just to be clear, I am talking about a literal simbol, not one made with (symbol ns name)
😉
> '/' 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
That code in ocr-lib is nonsense
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 // worksOh 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 resolvesI 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
Hmm, annoyingly it seems that Clojure actually behaves differently in the reader and clojure.lang.Symbol.
different behavior
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:
So this should really be Base64$Decoder/getDecoder I guess?
Oh, no. I see what you mean
Is the Decoder just ignored then?
Lol, yes:
user=> (Base64/flibbetygibbit/getDecoder)
#object[java.util.Base64$Decoder 0x1d25c1c "java.util.Base64$Decoder@1d25c1c"]
user=>
oh I didnt try that 😆
OK, figured it out I think:
user=> (Base64/flibbetygibbit/getDecoder)
sym: flibbetygibbit/getDecoder (flibbetygibbit / getDecoder)
From (flibbetygibbit/getDecoder)
Form: (. Base64 flibbetygibbit/getDecoder)
methodName: getDecoder
It's ignored by Clojure because clojure gets the name of the symbol, because it basically just wants a string
So by coincidence, it ignores the namespace in this form
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.
helpful information from alex the other day about this
@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.
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.
Doh. the getDecoder method is a method of class java.util.Base64. I think it makes more sense to me now.