I want to use assignment form and where syntax while specifying the return type. I can’t. Why not? (Presumably I’ve misunderstood what some syntax means.)

To be concrete, here are a few function definitions that compile:

function f(::T)::Nothing where {T} nothing end
f(::T) where {T} = nothing
f()::Nothing = nothing

Here’s one that doesn’t:

f(::T)::Nothing where {T} = nothing

The first example above uses where syntax and has a return type. The second uses assignment form and where syntax. The third uses assignment form and has a return type. Any two, I can do. All three, I can’t. What am I missing?

I feel like I should be able to find this by searching, but I haven’t figured out what to search; apologies.

(ETA I’m on 1.9.2 if that’s relevant… but surely not.)

Ah. So… I didn’t just miss an obvious way to do this?

Do you know if this is something which is actually hard to support parsing? Or is it in some sense an omission for which I should post a bug on github?

My question is if the issue is Nothing where {T} appearing like a type of f(::T) to the parser, why isn’t it a problem for function f(::T)? Ignoring the function-end parts, it has almost the same form, just differing by =.

function f(::T)::Nothing where {T} nothing end
f(::T)::Nothing where {T} = nothing

My understanding (bear in mind I know little) is that where serves multiple purposes syntactically, and in the function f(::T) case the where really is part of the function syntax. So precedence (of where vs ::) doesn’t make any difference.

This is a difficult parser corner case. I’ve wrestled with it, but there is no straightforward solution. The problem is that generally the right way to parse f(x) :: A where B is as f(x) :: (A where B) because where makes types and the right side of :: has to be a type. For 1-line function definitions only though, we want (f(x) :: A) where B , but we don’t know it’s a function definition until we see the following = , and by then it’s too late. So you need to write function (which I think is more readable for such elaborate definitions anyway), or parenthesize the f(x) :: A part.

Basically function tips off the parser soon enough to treat the where clause properly, but the = only shows up after the where clause when it’s too late. Now I have a little bit more clarity to this old gripe I had, though I still don’t know the issues with the 2 anonymous forms. I at least would like the anonymous function block to work as well as the named one if it were possible without breaking changes.