goretkin / FixArgs.jl

Other
19 stars 3 forks source link

Broadcasting considerations #25

Open goretkin opened 3 years ago

goretkin commented 3 years ago
julia> @fix _ .+ _
ERROR: UndefVarError: .+ not defined

because

julia> Meta.@lower(@fix _ .+ _)
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = (FixArgs.fix)(.+, nothing, nothing)
└──      return %1
))))

Note that

julia> Meta.@lower(1 .+ 2)
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = Base.broadcasted(+, 1, 2)
│   %2 = Base.materialize(%1)
└──      return %2
))))

Perhaps Base.Broadcast.Broadcasted{Nothing}(+, ()) can be used to represent .+, or we can define new wrapper type, or better yet just use BroadcastFunction from https://github.com/JuliaLang/julia/pull/37583

goretkin commented 3 years ago

on Julia 1.6

julia> (@fix Base.Broadcast.BroadcastFunction(+)(1, _))(1:3)
3-element Vector{Int64}:
 2
 3
 4
goretkin commented 3 years ago

Already true on v1.5, infix and prefix broadcasted functions parse differently:

julia> dump(:(f.(1,2)))
Expr
  head: Symbol .
  args: Array{Any}((2,))
    1: Symbol f
    2: Expr
      head: Symbol tuple
      args: Array{Any}((2,))
        1: Int64 1
        2: Int64 2

julia> dump(:(1 .+ 2))
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol .+
    2: Int64 1
    3: Int64 2

because .$operator is handled specially by the parser.

julia> :(.+)
:.+

julia> :(f.)
ERROR: syntax: unexpected ")"
Stacktrace:
 [1] top-level scope at none:1

julia> :(.f)
ERROR: syntax: invalid identifier name "."
Stacktrace:
 [1] top-level scope at none:1