`Where` questions


#1

Where questions

Hi! I spent some time today reading the upcoming 0.6 documentation and had a few questions while trying to understand the upcoming new syntax for parametric types.

  1. What is the difference, if any, between typealias Vector{T} Array{T,1} and const Vector = Array{T, 1} where T?

  2. Of the following two forms, why can you say b). but not a).?

    a). Tuple{X, Y} where X <: Real where Y <: Vector{X}

    b). Tuple{X, Y} where Y <: Vector{X} where X <: Real

  3. What is the difference, if any, between f{T}(x::T) = x and f(x::T) where T = x?


About the `Array{<:Number, 2}` syntax
#2

None.

A where B where C is actually (A where B) where C

In another word B can use typevar in C (or in general any typevar defined later in syntactic order) but not the other way around. If B and C do not reference each other, the order can be reversed but it’s not possible in general when they are referencing each other as in this case.

None. Except that the former might be getting deprecated due to conflict with a better constructor definition syntax.


#3

And this might also be deprecated as some point since there isn’t really a need for it anymore.


#4

So, apparently, reading where as wherein provides the correct sense of oriented inclusion.


#5

You gotta remember the implicit <: Any or else it makes no sense.


#6

Related question to the last.

Is Array{Int, N} where N really exactly the same as Array{Int, N} where N <: Any?

In the latter, N = 1, 2, etc does not satisfy the predicate N <: Any, so it seems that should be forbidden…


#7

It’s an unrelated issue. https://github.com/JuliaLang/julia/issues/9580


#8

i find this syntax mildly confusing, because it looks like the = is part of the type constraint

f(x::T) where T = x
t(x::T) where T = T

wouldn’t it make more sense to put it inside the parens?

t(x::T where T) = T

#9

See the on going discussion at https://github.com/JuliaLang/julia/pull/20308#issuecomment-276229351 for a better syntax. The comment linked also shows why putting it inside the parenthesis is wrong.


#10

anyone cares to explain what is the problem with this?

f(t::T where T)::T = ...

yes T is used after its definition, OK. but the return type is not part of the dispatch mechanism, so how is that different than, say,

f(t::T) where T = T

in which case we use T after its definition? what do we lose here?


#11

Since most of us expect where to introduce a clause (i.e. a nontrivial expression) perhaps a better keyword would be something like for_any. These seem less confusing than the where versions, at least to me:

f(x::T) for_any T = x
t(x::T) for_any T = T
foo{T}(x) for_any T = rhs

And this is about the same (since type assertions are already peculiar):

foo{T}(x) for_any T<:Real = rhs

#12

Because it’s f(t::(T where T))::T = ... which is f(t::Any)::T = .... The type parameter for the method has to be on the method, it is not if you put it into the argument. The thing before where is the thing that’s parametrized. For f(::T where T) it’s T and for f(::T) where T it’s f(::T). You want the latter for parametric method definition.


#13

unfortunately juliabox keeps dying for me now, so can’t try. but if i understand correctly, you can do this in 0.6?

f(x::Pair{T,T} where T, a::Array{T,1} where T) = x, a


#14

Yes, it constrains the first argument to be a pair with the same type, and a vector that has another type.
In that form, the Ts in each argument are independent.
(g(x::Pair{T,T}, a::Array{T,1}) where T) = x, a is what you need to constrain the elements of the Pair and of the Vector to all be the same type.


#15

anyone cares to explain what is the problem with this?

f(t::T where T)::T = ...

The parameter names of UnionAll types do not escape the signature. They do not automatically come into scope; they are inside the type. In your first example T is just a dummy variable used to discuss the type (T where T) which (I think) is converted to Any.

When the where is outside the signature, that indicates that the method is to be parameterized and the names of the type variables are visible both inside the signature and inside the method body (the ...).

The thing which “might” make sense is

(f(t::T) where T)::T = ...

which is quite analogous to the allowed

(f(t::T) where T) = ...

given that (as I understand) the method output restriction ::T piece is transformed to be a part of the ... anyway.


#16

juliabox 0.6.0 seems to be permadead to me. is this also possible now?

isgoodtype(t) = t <: (Pair{T, T} where T)

that is, this expression is just a regular expression that can be used outside of definitions? because afaik it is not possible with 0.5.0 syntax.


#17

Yes. <20 chars limit>


#18

+1. the juliabox 0.6-dev kernel is always crashing those days for me too