Robert McIntyre <r...@mit.edu> writes: > So there's some sort of "boxing" going on here where the nil produced > as the values of s-expressions are actually Objects which are nulls, > while literal nils are actually nulls?
No, there's no boxing going on. They're both just regular Java nulls (and null is not an Object). The only difference is in the byte code generation: which constructor gets picked (if any). It seems as if the runtime reflection code when encountering a null will just pick the first constructor it sees, while the compile-time code notices the ambiguity and throws an error. It's kind of annoying that you can't type-hint the nil too. (Thread. ^Runnable nil) ; error, nil can't hold metadata and have to resort to binding it and hinting the binding. (let [^Runnable s nil] (Thread. s)) ; ok > Such as in java where: > > Object t = null; > Thread r = new Thread((String) t); > > is valid but > > Thread r = new Thread(null); > is not ? In this case you've explicitly told Java the type with a string cast so it can generate bytecode that refers the String constructor. You can do that directly too: Thread r = new Thread((String) null); Being statically typed Java never does runtime reflection (unless you explicitly code it) so this issue cannot actually arise in it. > Isn't this breaking referential transparency that (Thread. ((fn []))) > and (Thread. nil) are not the same (you can't replace a function call > with it's value in this case)? This is not the behaviour I would > expect at all, as it would make any clojure function with a nil in > it's range no longer pure. Ambiguous code is arguably "invalid" in some sense anyway when running on a deterministic machine model, so I'm not sure it makes sense to talk about the purity of it. Suppose I do this and never actually call the resulting fn, just throw it away: #(Thread. nil) ; throws an error at compile time #(Thread. (identity nil)) ; doesn't and can't How could they be made consistent? I guess either: 1) Resolve the ambiguity by consistently picking one of the constructors (perhaps the first alphabetically). 2) Delay the exception throwing in the direct nil case to runtime, so the compiler would replace the form with: #(throw (java.lang.IllegalArgumentException.)) And have the reflection code in the second detect ambiguity and throw at runtime as well. -- 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