Skip to content

Function definitions are possible in for-loop header #53738

Open
@mauro3

Description

Yesterday I found out that in a loop header values can be assigned to array elements:

julia> a = [77];

julia> for a[1] = 1:5
           println(a)
       end
[1]
[2]
[3]
[4]
[5]

which seems a bit niche but ok.

Naturally, I tried other uses of = in the loop header: setting mutable struct fields works and function definition as well. But the latter produces strange results:

julia> function for_loop_fn()
           function f end
           for f(i) = 1:2
               println(f(1))
           end
           return f
       end;


julia> fn = for_loop_fn()
1
2
(::var"#f#4"{Int64}) (generic function with 1 method)

julia> fn(77)
2

Also actually using i in the "function body" does not work (and probably can't):

julia> for f(i) = 1:2+i
           println(f(1))
       end
ERROR: UndefVarError: `i` not defined
Stacktrace:
 [1] top-level scope
   @ REPL[14]:1

Should the function definition just error? Or is there a purpose to this?

For reference, the lowered code:

julia> @code_lowered for_loop_fn()
CodeInfo(
1 ─       Core.NewvarNode(:(f))
│   %2  = 1:2@_2 = Base.iterate(%2)
│   %4  = @_2 === nothing%5  = Base.not_int(%4)
└──       goto #4 if not %5
2%7  = @_2@_4 = Core.getfield(%7, 1)
│   %9  = Main.:(var"#f#4")
│   %10 = Core.typeof(@_4)
│   %11 = Core.apply_type(%9, %10)
│         f = %new(%11, @_4)
│   %13 = Core.getfield(%7, 2)
│   %14 = (f)(1)
│         Main.println(%14)
│         @_2 = Base.iterate(%2, %13)
│   %17 = @_2 === nothing%18 = Base.not_int(%17)
└──       goto #4 if not %18
3 ─       goto #2
4return f
)

This is in Julia 1.10.2. However, a quick check suggests it's identical down to 1.2. In 1.1 there is slightly different but still wrong behavior (but array element updating also works).

Metadata

Assignees

No one assigned

    Labels

    compiler:loweringSyntax lowering (compiler front end, 2nd stage)parserLanguage parsing and surface syntax

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions