How to annotate a type using the splat operator

How to (possibly) annotate an argument type when using the splat operator?

f(x, y) = x^2 + y^2
vec = [1.0, 2.0, 'a']
f(vec[1:2]...)

How can I annotate the use ...of a function call. Also note that none of the macro to display the code ( @code_llvm, @code_lowered, @code_native, @code_typed, @code_warntype) is not working, so it would be very difficult to optimize the use splat?

+4
source share
2 answers

Because it seems that in the above example of using macroreversions, reflection functions could not achieve the correct types of arguments, using the original function instead of the macro may be useful:

f(x, y) = x^2 + y^2
vec = [1.0, 2.0, 'a']
@code_warntype(f(vec[1:2]...)) # => Nothing
code_warntype(f,map(typeof,vec[1:2])) 
#  Variables:
#  x::Float64
#  y::Float64
#  .....

, (function, collection of types).

:

+1

, - :

julia> foo(args::Float64...) = sum([x^2 for x in args])::Float64
foo (generic function with 1 method)

julia> foo(args::Vector{Float64}) = foo(args...)::Float64
foo (generic function with 2 methods)

julia> foo(args::Tuple{Vararg{Float64}}) = foo(args...)::Float64
foo (generic function with 3 methods)

julia> foo(2.0, 5.5, 7.0)
83.25

julia> v = Float64[2, 5.5, 7.0]
    3-element Array{Float64,1}:
     2.0
     5.5
     7.0

julia> foo(v)
83.25

julia> t = tuple(v...)
(2.0,5.5,7.0)

julia> foo(t)
83.25

, .

julia> @which foo(2.0, 5.5, 7.0)
foo(args::Float64...) at none:1

julia> @which foo(v)
foo(args::Array{Float64,1}) at none:1

julia> @which foo(t)
foo(args::Tuple{Vararg{Float64}}) at none:1

@code_warntype ..

julia> @code_warntype foo(2.0, 5.5, 7.0)
Variables:
  args::Tuple{Float64,Float64,Float64}
  #s33::Int64
  #s32::Int64
  #s31::Int64
  x::Float64
  #s30::Int64

Body:
  begin  # none, line 1:
      GenSym(1) = (Base.nfields)(args::Tuple{Float64,Float64,Float64})::Int64
      0:
      GenSym(3) = (top(ccall))(:jl_alloc_array_1d,(top(apply_type))(Base.Array,Float64,1)::Type{Array{Float64,1}},(top(svec))(Base.Any,Base.Int)::SimpleVector,Array{Flo
at64,1},0,GenSym(1),0)::Array{Float64,1}
      #s33 = 1
      #s32 = 1
      #s31 = 0
      unless (Base.box)(Base.Bool,(Base.not_int)(#s31::Int64 === GenSym(1)::Bool)::Any)::Bool goto 2
      3:
      #s31 = (Base.box)(Base.Int,(Base.add_int)(#s31::Int64,1)::Any)::Int64
      GenSym(10) = (Base.getfield)(args::Tuple{Float64,Float64,Float64},#s32::Int64)::Float64
      GenSym(11) = (Base.box)(Base.Int,(Base.add_int)(#s32::Int64,1)::Any)::Int64
      #s30 = 1
      GenSym(12) = GenSym(10)
      GenSym(13) = (Base.box)(Base.Int,(Base.add_int)(1,1)::Any)::Int64
      x = GenSym(12)
      #s30 = GenSym(13)
      GenSym(14) = GenSym(11)
      GenSym(15) = (Base.box)(Base.Int,(Base.add_int)(2,1)::Any)::Int64
      #s32 = GenSym(14)
      #s30 = GenSym(15)
      GenSym(4) = (Base.box)(Base.Float64,(Base.mul_float)(x::Float64,x::Float64)::Any)::Float64
      $(Expr(:type_goto, 0, GenSym(4)))
      $(Expr(:boundscheck, false))
      (Base.arrayset)(GenSym(3),GenSym(4),#s33::Int64)::Array{Float64,1}
      $(Expr(:boundscheck, :(Main.pop)))
      #s33 = (Base.box)(Base.Int,(Base.add_int)(#s33::Int64,1)::Any)::Int64
      4:
      unless (Base.box)(Base.Bool,(Base.not_int)((Base.box)(Base.Bool,(Base.not_int)(#s31::Int64 === GenSym(1)::Bool)::Any)::Bool)::Any)::Bool goto 3
      2:
      1:
      GenSym(8) = GenSym(3)
      return (Base._mapreduce)($(Expr(:new, :((top(getfield))(Base,:IdFun)::Type{Base.IdFun}))),$(Expr(:new, :((top(getfield))(Base,:AddFun)::Type{Base.AddFun}))),GenSy
m(8))::Float64
  end::Float64

julia> @code_warntype foo(v)
Variables:
  args::Array{Float64,1}

Body:
  begin  # none, line 1:
      return (top(_apply))((top(getfield))(Main,:call)::F,Main.foo,args::Array{Float64,1})::Float64
  end::Float64

julia> @code_warntype foo(t)
Variables:
  args::Tuple{Float64,Float64,Float64}

Body:
  begin  # none, line 1:
      return (Main.foo)((top(getfield))(args::Tuple{Float64,Float64,Float64},1)::Float64,(top(getfield))(args::Tuple{Float64,Float64,Float64},2)::Float64,(top(getfield))(args::Tuple{Float64,Float64,Float64},3)::Float64)::Float64
  end::Float64

: IJulia, juliabox.org, Julia v0.4.1:

:

julia> @which foo(t::Tuple{Vararg{Float64}}...)
foo(args::Tuple{Vararg{Float64}}) at none:1

julia> @which foo(v::Vector{Float64}...)
foo(args::Array{Float64,1}) at none:1
+1

Source: https://habr.com/ru/post/1616909/


All Articles