Stream: helpdesk (published)

Topic: Macro expansion broken, but macro works??


view this post on Zulip Philipp Gabler (Aug 23 2021 at 08:37):

I tried changing some of the code of Turing.jl's @model macro, with the curios effect that macro expansion doesn't work -- with a malformed expression syntax error -- but the macro actually works... any idea what could cause something like that?

julia> @model function demo4(n, ::Type{TV}=Vector{Float64}) where {TV}
           m ~ Normal()
           x = TV(undef, n)
           @show __varinfo__
           for i in eachindex(x)
               x[i] ~ Normal(m, 1.0)
           end
       end
ERROR: syntax: malformed expression
Stacktrace:
 [1] top-level scope
   @ REPL[9]:1

julia> @macroexpand @model function demo4(n, ::Type{TV}=Vector{Float64}) where {TV}
           m ~ Normal()
           x = TV(undef, n)
           @show __varinfo__
           for i in eachindex(x)
               x[i] ~ Normal(m, 1.0)
           end
       end
:($(Expr(:error, "malformed expression")))

julia> var"@model"(LineNumberNode(1), Main, :(function demo4(n, ::Type{TV}=Vector{Float64}) where {TV}
           m ~ Normal()
           x = TV(undef, n)
           @show __varinfo__
           for i in eachindex(x)
               x[i] ~ Normal(m, 1.0)
           end
       end))
:(#= /home/philipp/git/DynamicPPL.jl/src/compiler.jl:517 =# (Base).@__doc__ function demo4(n, ::Type{TV} = Vector{Float64}; ) where TV
          #= line 1 =#
          evaluator = ((__model__::Model, __varinfo__::AbstractVarInfo, __context__::DynamicPPL.AbstractContext, n, ::Type{TV}) where TV->begin
                      begin
                          #= REPL[7]:1 =#
                          #= REPL[7]:2 =#
                          begin
                              vn = (VarName){:m}()
                              inds = ()
                              isassumption = begin
                                      let vn = (VarName){:m}()
                                          if (DynamicPPL.contextual_isassumption)(__context__, vn)
                                              if !((DynamicPPL.inargnames)(vn, __model__)) || (DynamicPPL.inmissings)(vn, __model__)
                                                  true
                                              else
                                                  m === missing
                                              end
                                          else
                                              false
                                          end
                                      end
                                  end
                              if isassumption
                                  m = (DynamicPPL.tilde_assume!)(__context__, (DynamicPPL.unwrap_right_vn)((DynamicPPL.check_tilde_rhs)(Normal()), vn)..., inds, __varinfo__)
                              else
                                  if !((DynamicPPL.inargnames)(vn, __model__))
                                      m = (DynamicPPL.getvalue_nested)(__context__, vn)
                                  end
                                  (DynamicPPL.tilde_observe!)(__context__, (DynamicPPL.check_tilde_rhs)(Normal()), m, vn, inds, __varinfo__)
                              end
                          end
                          #= REPL[7]:3 =#
                          x = TV(undef, n)
                          #= REPL[7]:4 =#
                          begin
                              Base.println("__varinfo__ = ", Base.repr(begin
                                          #= show.jl:955 =#
                                          local var"#37#value" = __varinfo__
                                      end))
                              var"#37#value"
                          end
                          #= REPL[7]:5 =#
                          for i = eachindex(x)
                              vn = (VarName){:x}(((i,),))
                              inds = ((i,),)
                              isassumption = begin
                                      let vn = (VarName){:x}(((i,),))
                                          if (DynamicPPL.contextual_isassumption)(__context__, vn)
                                              if !((DynamicPPL.inargnames)(vn, __model__)) || (DynamicPPL.inmissings)(vn, __model__)
                                                  true
                                              else
                                                  #= /home/philipp/git/DynamicPPL.jl/src/compiler.jl:90 =# @views(x[i]) === missing
                                              end
                                          else
                                              false
                                          end
                                      end
                                  end
                              if isassumption
                                  x[i] = (DynamicPPL.tilde_assume!)(__context__, (DynamicPPL.unwrap_right_vn)((DynamicPPL.check_tilde_rhs)(Normal(m, 1.0)), vn)..., inds, __varinfo__)
                              else
                                  if !((DynamicPPL.inargnames)(vn, __model__))
                                      x[i] = (DynamicPPL.getvalue_nested)(__context__, vn)
                                  end
                                  (DynamicPPL.tilde_observe!)(__context__, (DynamicPPL.check_tilde_rhs)(Normal(m, 1.0)), #= /home/philipp/git/DynamicPPL.jl/src/compiler.jl:90 =# @views(x[i]), vn, inds, __varinfo__)
                              end
                          end
                      end
                  end)
          return (Model)(:demo4, evaluator, NamedTuple{(:n, :TV)}((n, TV)), NamedTuple{(:TV,)}((Vector{Float64},)))
      end)

julia> var"@model"(LineNumberNode(1), Main, :(function demo4(n, ::Type{TV}=Vector{Float64}) where {TV}
           m ~ Normal()
           x = TV(undef, n)
           @show __varinfo__
           for i in eachindex(x)
               x[i] ~ Normal(m, 1.0)
           end
       end)) |> eval
demo4 (generic function with 2 methods)

julia> demo4
demo4 (generic function with 2 methods)

julia> demo4(10)
Model{var"#1#2", (:n, :TV), (:TV,), (), Tuple{Int64, DataType}, Tuple{DataType}, DefaultContext}(:demo4, var"#1#2"(), (n = 10, TV = Vector{Float64}), (TV = Vector{Float64},), DefaultContext())

view this post on Zulip Takafumi Arakaki (tkf) (Aug 23 2021 at 20:12):

I don't know what is going on but I'd try

macro f(ex)
    global INPUT = deepcopy(ex)
    ans = ... implementation of f ...
    global OUTPUT = deepcopy(ans)
    return ans
end

to see the real input and output when expanding the macro.

view this post on Zulip Jameson Nash (Aug 26 2021 at 19:49):


view this post on Zulip Jameson Nash (Aug 26 2021 at 19:49):

index fb3e732d41..6f8aff9874 100644
--- a/src/jlfrontend.scm
+++ b/src/jlfrontend.scm
@@ -22,10 +22,10 @@
                `(incomplete ,msg)
                (cons 'error (cdr e))))
          (begin
-           ;;(newline)
-           ;;(display "unexpected error: ")
-           ;;(prn e)
-           ;;(print-stack-trace (stacktrace))
+           (newline)
+           (display "unexpected error: ")
+           (prn e)
+           (print-stack-trace (stacktrace))
            '(error "malformed expression"))))
    thk))

view this post on Zulip Jameson Nash (Aug 26 2021 at 19:50):

If you have access to a source build, you could also have it spit out the full lispy error

view this post on Zulip Philipp Gabler (Aug 31 2021 at 15:27):

Thanks for the tip @Jameson Nash, here's the output. Top of the stack trace:

(type-error car cons ())
unexpected error: #0 (caddr (:: (curly Type TV)))
#1 (resolve-expansion-vars-
 (kw (:: (curly Type TV)) (curly Vector Float64))
 ((n . |#118#n|) (|#unused#| . |#119##unused#|) (TV . |#120#TV|))
 #<julia: DynamicPPL> () #t)

So it's not happy with the Type in there, or what?

view this post on Zulip Jameson Nash (Aug 31 2021 at 16:00):

Apparently the hygiene pass does not know about the ::Type{TV}=Vector{Float64} syntax

view this post on Zulip Philipp Gabler (Sep 12 2021 at 08:27):

Appearently so... I raised an issue.


Last updated: Oct 02 2023 at 04:34 UTC