Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in: f(x::T)::Int where T = x #21847

Closed
rfourquet opened this issue May 13, 2017 · 10 comments
Closed

Error in: f(x::T)::Int where T = x #21847

rfourquet opened this issue May 13, 2017 · 10 comments
Labels
parser Language parsing and surface syntax

Comments

@rfourquet
Copy link
Member

In other words, ::ReturnType is incompatible with where clauses in the short function form declarations.
I thought an exemple was more clear than my words in the title.

@JeffBezanson JeffBezanson added the parser Language parsing and surface syntax label May 13, 2017
@JeffBezanson
Copy link
Member

Yes, this is tricky, since a where b denotes a type, and x::t means x has type t, so x::a where b is most naturally parsed as x::(a where b).

@TotalVerb
Copy link
Contributor

It's easy to just parenthesize the function and return type.

@StefanKarpinski
Copy link
Member

StefanKarpinski commented Aug 7, 2017

Quoting from #23163:

What about disallowing type annotations on short-form functions entirely? They're not super useful anyway. Throwing an error would be better here than giving a surprising interpretation.

Or at least throwing an error when the short form is used with a type annotation and a where clause – you can't recover once you've reached the = but at least it can throw a helpful error.

@tkelman
Copy link
Contributor

tkelman commented Aug 7, 2017

What would the error suggest, those features can only be used together in long form functions? Should probably only disallow the ambiguous / confusing cases, if things are parenthesized such that the intent is clear, I don't see a reason to error.

@StefanKarpinski
Copy link
Member

StefanKarpinski commented Aug 7, 2017

Yes, it would only the be necessary to raise an error when there are no disambiguating parens.

@bramtayl: what do you suggest as an alternative? I see only four plausible options:

  1. Do nothing and continue to parse this as we currently do.
  2. Raise a clear error when the parser encounters this specific situation.
  3. Disallow return type annotations on short-form methods altogether.
  4. Change the parser to support infinite backtracking.

Option 1 seems clearly bad and 4 is not going to happen, which leaves only the middle two.

@bramtayl
Copy link
Contributor

bramtayl commented Aug 7, 2017

Hmm. I wasn't reading closely, I was just immediately off-put because I almost exclusively use short form functions (with begin blocks where necessary), and in the long term it would be nice to maintain the same functionality for short form and long form.

@ForceBru
Copy link

Maybe the parser could detect this specific situation and provide a descriptive error message that points to this issue? Something like: Hey, this is a known bug that's tracked in this issue: https://something. The current solution is to enclose the part before "where" in parentheses.

Currently (Julia 1.7.1) I'm getting this confusing error:

julia> is_almost_zero(x::T)::Bool where T<:Real = x  zero(T)
ERROR: UndefVarError: T not defined
Stacktrace:
 [1] top-level scope
   @ REPL[27]:1

It doesn't even tell me which particular T is causing the problem: is it the T in x::T? Or the one in zero(T)? Looks like it's the x::T part, but I only learned this from GitHub comments: #31560 (comment)

@Teo-ShaoWei
Copy link

I came here from this discourse thread (thanks @fredrikekre).

After reading through, seems like the problem can technically be solved with :: taking precedence over where. The issue is that we shouldn't deviate from intuitive meanings, and seems like we had agreed on the following:

Since a where b denotes a type, and x::t means x has type t, so x::a where b is most naturally parsed as x::(a where b).

While I agree that it is more natural to have the denotation of a type go first, I would however disagree that this is the role of where.

Let me reframe using this analogy to bring out the intuition further: In mathematics when we talk about "x^2 + 2x > -1 for x in real", we mean "(x^2 + 2x > -1) for (x in real)". The denotation of the set of x is "x is real". The "for" is used to scope the whole expression and not to x.

This analogy is consistent with our existing definition, e.g.:

f(x::T) where T<:Integer = x

The type denotation is actually just T<:Integer. Then where has no chance to take precedence over ::T, and rightfully shouldn't. Then where applies to the whole expression, which is f(x::T), which is intuitive too since that is the full scope to inflict T<:Integer.

So I think it is still natural to have:

S::A where B<:C

to get the precedence of:

((S::A) where (B<:C))

@ARCJ137442
Copy link

After reading through, seems like the problem can technically be solved with :: taking precedence over where. The issue is that we shouldn't deviate from intuitive meanings,

Personal thought: Visually, at least, the expression that must be separated by Spaces likes X{T} where T often has a lower priority than the expression x::T, which does not require Spaces.

@vtjnash
Copy link
Member

vtjnash commented Oct 31, 2023

This would be breaking to change at this point

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
parser Language parsing and surface syntax
Projects
None yet
Development

No branches or pull requests

10 participants