Re: Namespaced symbols, and errors

2013-03-10 Thread Gary Verhaegen
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

2013-03-10 Thread Marko Topolnik


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

2013-03-09 Thread Gary Verhaegen
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

2013-03-09 Thread Bronsa
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

2013-03-09 Thread Gary Verhaegen
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

2013-03-09 Thread nick rothwell
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.