-
-
Notifications
You must be signed in to change notification settings - Fork 33
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
Allow typevars in do
expressions
#437
base: main
Are you sure you want to change the base?
Conversation
Allows constructs like f() do (x::T) where T; body end It's already being parsed, but the where clause is put into a tuple, causing a syntax error downstream. This change just avoids putting it in a tuple.
I think it is best for proposed syntax changes to start as or have an associated issue in the JuilaLang/julia repo for viability. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, technically.
@@ -369,7 +369,9 @@ tests = [ | |||
"f() do x, y\n body end" => "(call f (do (tuple x y) (block body)))" | |||
"f(x) do y body end" => "(call f x (do (tuple y) (block body)))" | |||
"@f(x) do y body end" => "(macrocall-p @f x (do (tuple y) (block body)))" | |||
|
|||
"f(x) do (y::T) where T body end" => "(call f x (do (where (parens (::-i y T)) T) (block body)))" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"f(x) do (y::T) where T body end" => "(call f x (do (where (parens (::-i y T)) T) (block body)))" | |
"f(x) do y::T where T body end" => "(call f x (do (tuple (::-i y (where T T))) (block body)))" | |
"f(x) do (y::T) where T body end" => "(call f x (do (where (parens (::-i y T)) T) (block body)))" |
Maybe add a test for the case without parenthesis (IIUC the where clause will bind tighter than the ::).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, as @c42f points out, the relative precedence of ::
and where
is already context dependent:
julia> parsestmt(SyntaxNode, "function f()::T where T 0 end")
line:col│ tree │ file_name
1:1 │[function]
1:10 │ [where]
1:10 │ [::-i]
1:10 │ [call]
1:10 │ f
1:15 │ T
1:23 │ T
1:24 │ [block]
1:25 │ 0
julia> parsestmt(SyntaxNode, "f()::T where T = 0")
line:col│ tree │ file_name
1:1 │[=]
1:1 │ [::-i]
1:1 │ [call]
1:1 │ f
1:6 │ [where]
1:6 │ T
1:14 │ T
1:18 │ 0
So in this case, I think we should make :: bind tighter than where so parentheses are not necessary here.
See also: JuliaLang/julia#55159 And also, as a syntax change this would need to be gated on VERSION. |
(@c42f edit:) Upstream syntax discussion: JuliaLang/julia#54915
There are several ways to create functions in julia. One of them is the
do
syntax. You can't dispatch ondo
functions, but now and then the need comes up to capture the types of variables. Although this is easy withtypeof
inside the function body, it turns out to be quite easy to enable the use ofwhere
clauses in thedo
syntax. This would make ado
function similar to the other function definitions.The reason it's easy is that such expressions are already being parsed, but a minor detail prevents it from being accepted as a valid expression:
The
where
clause becomes encapsulated in atuple
. The reason is that after the parser seesdo
, it looks for a comma separated list. After the list is parsed, i.e. on;
or linefeed, the list is encapsulated in atuple
. This means that thewhere
clause becomes an argument to the function, which fails as a syntax error. By modifying the parsing ofdo
expressions to avoid insertingtuple
if the newly parsed list is awhere
, the parse result becomes:This is a valid
:->
expression, just like an anonymous function definition((x::T) where T) -> T(x)
currently is.The PR is a one-line change to
parser.jl
, isolated to parsing what followsdo
. It does not enable any new or very useful functionality, it merely will make functions defined indo
quite similar to other function definitions.I don't think this change will break anything, as the construction currently results in a
ERROR: syntax: ...
failure.