Re: Namespaced symbols, and errors
Here's another mental model that you can use. (Not sure it is 100% accurate with the actual implementation, but it has served me well so far.) Keywords are not bound, in the same sense that numbers are not bound. 1 is 1, just as 2 is 2, whatever the namespace you are into. 1 from the user namespace is the same a 1 from the clojure.core namespace. Similarly, the keyword :hello is not bound, it just is. :hello in the user namespace is the same value as :hello in the core namespace or in any other namespace. As keywords are very lightweight to create and very fast to compare for equality, they are often used as keys in associative data structures. Sometimes, though, you actually want to have keywords that are local to your namespace, because you want to encapsulate some behaviour. Say you want to create a simple tree-manipulation library, where your nodes are, for some reason, represented as maps with a special key :children. Other than that, you want the user of your library to be able to add any information to the maps representing the nodes of the tree. One way to approach this would be to document that the special key :children is reserved and cannot be used. Another way to handle this would be to create a keyword that is supposedly unique to your library, by prefixing the keyword with some chosen prefix, say :tree-children. That would soon become quite cumbersome to type, and does not really preclude the preceding point, though it would make conflicts rarer. But there is one thing that Clojure can guarantee, which is that in a single application, there will not be two namespaces with the same name. So, assuming your library is contained in a namespace called my.tree-manipulation.core, you could decide to call your special key :my.tree-manipulation.core.children. That, too, would be cumbersome, but conceivably safer. Now, this is originally an implementation detail, but it just so happens that keywords are basically implemented as symbols that evaluate to themselves. That is, if keywords did not exist in Clojure, you could invent them by declaring them as (def :a ':a); after that declaration, :a would work exactly like a keyword works today in Clojure. Which means that we can reuse the namespace resolution feature of symbols : every time the reader reads in a symbols, it first resolves it in the current namespace, and then evaluates the full symbol to find its value. Keywords sort of short-circuit that by default. However, with the :: notation, you are basically telling the reader to first evaluate the given symbol in the current namespace, then evaluate it as a symbol. So ::bla in namespace test is the same as typing the full keyword :test/bla. But the keyword itself is not resolved in the namespace, the keyword just is. It just so happens that its value looks like a namespace-qualified symbol with a colon in front. Getting back to the tree example, you can thus have your special key be ::children, which combines the two following advantages : the actual keyword is pretty specific to your library, as the real keyword seen by the compiler will be :my.tree-manipulation.core/children, but it is also nearly as short to type and to read as plain :children. Now let's look at your questions in light of this mental model. On 9 March 2013 19:37, nick rothwell n...@cassiel.com wrote: I understand that ::foo is a keyword bound into the local namespace. So ::foo is actually a shorthand for the :my.ns/foo keyword, which is a value by itself, independently of any enclosing or existing namespace. (Keywords follow the symbol rule of maximum one / in the name, but there is actually no link with existing namespaces : you can use a keyword :no-namespace/k even if there is no namespace called no-namespace.) I also understand (according to the docs) that :my.namespace/foo is the keyword foo in the namespace my.namespace. As I stated earlier, namespaces are only of interest to symbol resolution; they do not interfere with keywords beyond their optional construction via the :: shorthand. ::nsalias/foo is the keyword foo in the namespace my.namespace if I've aliased my.namespace to nsalias. So Clojure first tries to find the corresponding symbol, then only converts it to a keyword. Thus namespace resolution works with aliases. The resulting keyword is still a value by itself. But also: ::my.namespace/foo is equivalent to :my.namespace/foo (as a convenience, I guess). Resolving an already namespace-qualified symbol yields the same namespace-qualified symbol. :nsalias/foo is not the same as ::nsalias/foo - in fact, I'm not sure what :nsalias/foo is - a call on str yields :nsalias/foo. :nsalias/foo is the value :nsalias/foo - symbols are self-evaluating values, just as 1 is 1. The fact that it looks like a namespaced symbol is irrelevant. ::nsalias/foo is asking the reader to first resolve the symbol nsalias/foo in the current namespace, using known aliases if need be, and only afterwards turning it
Re: Namespaced symbols, and errors
On Friday, March 8, 2013 4:56:03 PM UTC+1, nick rothwell wrote: Typing the following at a REPL: (str ::junk/junk) (where there's no alias for junk) gives me: RuntimeException Invalid token: ::junk/junk clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) A couple of things: (i) Invalid token seems a bit curt: doesn't it mean something like no such namespace alias? This could definitely benefit from an improvement in the reader/compiler. Another aside: why does Clojure require :: for aliases but only : for namespace-qualified keywords? Under what circumstance would I use :junk/junk in any way other than to mean ::junk/junk (or :my.namespace.junk/junk, given the appropriate alias)? ::keyword being a shortcut for ::current-ns/keyword is more consistent (so less surprising) than being a shortcut for :current-ns/keyword. String value of a keyword is often important and dictated by outside constraints (conversion from/to string is common) so there's benefit to allowing a slash in it. I personally appreciate the :: to signal a qualified keyword. They are rare and special so it's nice to have them visually stand out. I bet other people can enumerate other reasons to support/criticise this design choice, but in the end there won't be much to learn from it. -Marko -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Namespaced symbols, and errors
The reader basically transforms :: into :namespace/, which means that the remaining part must be an unqualified symbol (i.e. no / in it). The character / is not allowed in unqualified symbols. As the documentation [1] says : '/' 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. Your notation ::junk/junk, assuming your type in namespace my.namespace.junk, would result in the keyword :my.namespace.junk/junk/junk, which is invalid (two /'s). Hence the implied restriction that ::symbol cannot contain a / character. I'm not really sure what you mean about aliases. Keywords stand by themselves (they are literals that evaluate to themselves), they are not aliases for something else. [1] http://clojure.org/reader On 8 March 2013 16:56, nick rothwell n...@cassiel.com wrote: Typing the following at a REPL: (str ::junk/junk) (where there's no alias for junk) gives me: RuntimeException Invalid token: ::junk/junk clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) A couple of things: (i) Invalid token seems a bit curt: doesn't it mean something like no such namespace alias? (ii) A complete aside, but: the interactive REPL obviously isn't disregarding the rest of the line when it gets a token error. Another aside: why does Clojure require :: for aliases but only : for namespace-qualified keywords? Under what circumstance would I use :junk/junk in any way other than to mean ::junk/junk (or :my.namespace.junk/junk, given the appropriate alias)? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Namespaced symbols, and errors
Gary, ::foo/bar is valid syntax if foo is a valid namespace alias. Try: (alias 'foo 'clojure.core) ::foo/bar Il giorno 09/mar/2013 09.36, Gary Verhaegen gary.verhae...@gmail.com ha scritto: The reader basically transforms :: into :namespace/, which means that the remaining part must be an unqualified symbol (i.e. no / in it). The character / is not allowed in unqualified symbols. As the documentation [1] says : '/' 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. Your notation ::junk/junk, assuming your type in namespace my.namespace.junk, would result in the keyword :my.namespace.junk/junk/junk, which is invalid (two /'s). Hence the implied restriction that ::symbol cannot contain a / character. I'm not really sure what you mean about aliases. Keywords stand by themselves (they are literals that evaluate to themselves), they are not aliases for something else. [1] http://clojure.org/reader On 8 March 2013 16:56, nick rothwell n...@cassiel.com wrote: Typing the following at a REPL: (str ::junk/junk) (where there's no alias for junk) gives me: RuntimeException Invalid token: ::junk/junk clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) A couple of things: (i) Invalid token seems a bit curt: doesn't it mean something like no such namespace alias? (ii) A complete aside, but: the interactive REPL obviously isn't disregarding the rest of the line when it gets a token error. Another aside: why does Clojure require :: for aliases but only : for namespace-qualified keywords? Under what circumstance would I use :junk/junk in any way other than to mean ::junk/junk (or :my.namespace.junk/junk, given the appropriate alias)? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Namespaced symbols, and errors
On 9 March 2013 12:27, Bronsa brobro...@gmail.com wrote: Gary, ::foo/bar is valid syntax if foo is a valid namespace alias. Try: (alias 'foo 'clojure.core) ::foo/bar I did not know that. Is that documented anywhere ? I was under the impression that :: was just intended as a shorthand to create local keywords so as to avoid clashing with other namespaces; that it does namespace resolution looks to me more like a side-effect of symbols and keywords sharing the same underlying implementation. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Namespaced symbols, and errors
I understand that ::foo is a keyword bound into the local namespace. I also understand (according to the docs) that :my.namespace/foo is the keyword foo in the namespace my.namespace. ::nsalias/foo is the keyword foo in the namespace my.namespace if I've aliased my.namespace to nsalias. But also: ::my.namespace/foo is equivalent to :my.namespace/foo (as a convenience, I guess). :nsalias/foo is not the same as ::nsalias/foo - in fact, I'm not sure what :nsalias/foo is - a call on str yields :nsalias/foo. This last point is the one that's confusing me. On Saturday, March 9, 2013 8:36:30 AM UTC, Gary Verhaegen wrote: The reader basically transforms :: into :namespace/, which means that the remaining part must be an unqualified symbol (i.e. no / in it). The character / is not allowed in unqualified symbols. As the documentation [1] says : '/' 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. Your notation ::junk/junk, assuming your type in namespace my.namespace.junk, would result in the keyword :my.namespace.junk/junk/junk, which is invalid (two /'s). Hence the implied restriction that ::symbol cannot contain a / character. I'm not really sure what you mean about aliases. Keywords stand by themselves (they are literals that evaluate to themselves), they are not aliases for something else. [1] http://clojure.org/reader On 8 March 2013 16:56, nick rothwell ni...@cassiel.com javascript: wrote: Typing the following at a REPL: (str ::junk/junk) (where there's no alias for junk) gives me: RuntimeException Invalid token: ::junk/junk clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) A couple of things: (i) Invalid token seems a bit curt: doesn't it mean something like no such namespace alias? (ii) A complete aside, but: the interactive REPL obviously isn't disregarding the rest of the line when it gets a token error. Another aside: why does Clojure require :: for aliases but only : for namespace-qualified keywords? Under what circumstance would I use :junk/junk in any way other than to mean ::junk/junk (or :my.namespace.junk/junk, given the appropriate alias)? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.