I recently found some code that, due to a misunderstanding, parametrized a function using the name of a built-in type. Example:
c{Float32}(r::Float32) = Float32(2pi)*r
c(1)
This might be pretty weird to debug, especially for a newcomer, and it seems easy to raise an error if you're parametrizing on a name that is already a defined type. This would be consistent with the existing convention to raise an error when trying to redefine a type.
This syntax has been deprecated, in part for this very reason. In v0.7+ this shouldn't be a problem.
This syntax has been deprecated
This still results in the confusing error I think OP talked about:
c(r::Float32) where {Float32} = Float32(2pi)*r
c(1)
I think OP wanted to disallow using already defined types as type parameters, since for this example locally in the funciton Float32 will not mean float but rather whatever type r have.
I see. I still think the new syntax helps a lot, since c{Float32} has a different meaning in other, very-frequently-used contexts, while where X always introduces a local binding for X. It's pretty important to learn which keywords introduce local names.
Disallowing use of a certain name locally because of a global definition sort of flies in the face of everything local variables and lexical scope are about. Imagine writing let x = 0 ... end and getting an error because x is already taken. Or more realistically perhaps let pi = 3 ... end. It also introduces action at a distance where your code can become invalid because somebody added a type with the same name somewhere --- even though there is no real conflict since you were using a local binding construct. So I'm pretty strongly against disallowing this.
You've convinced me, so I'll close this. Thanks for taking the time!
Most helpful comment
I see. I still think the new syntax helps a lot, since
c{Float32}has a different meaning in other, very-frequently-used contexts, whilewhere Xalways introduces a local binding forX. It's pretty important to learn which keywords introduce local names.Disallowing use of a certain name locally because of a global definition sort of flies in the face of everything local variables and lexical scope are about. Imagine writing
let x = 0 ... endand getting an error becausexis already taken. Or more realistically perhapslet pi = 3 ... end. It also introduces action at a distance where your code can become invalid because somebody added a type with the same name somewhere --- even though there is no real conflict since you were using a local binding construct. So I'm pretty strongly against disallowing this.