Julia: Parameter names can override existing type names

Created on 20 Apr 2018  路  4Comments  路  Source: JuliaLang/julia

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.

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, 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.

All 4 comments

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!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

arshpreetsingh picture arshpreetsingh  路  3Comments

Keno picture Keno  路  3Comments

tkoolen picture tkoolen  路  3Comments

yurivish picture yurivish  路  3Comments

i-apellaniz picture i-apellaniz  路  3Comments