From 26ef66241c4f8748a95dc990922046ad812a4bea Mon Sep 17 00:00:00 2001 From: Xianda Sun <5433119+sunxd3@users.noreply.github.com> Date: Sat, 16 Nov 2024 12:16:36 +0000 Subject: [PATCH] Permit dot call (like `Distributions.Normal`) to be used in model definition (#237) The motivation for the PR is initially to allow the use [`product_distribution`](https://juliastats.org/Distributions.jl/stable/multivariate/#Distributions.product_distribution) in JuliaBUGS model. By writing ```julia @bugs begin x[1:2] ~ Distributions.product_distribution(fill(Normal(), 2)) end ``` It also enables ```julia julia> foo(x) = x + 1 foo (generic function with 1 method) julia> model_def = @bugs begin a = Main.foo(b) end quote a = Main.foo(b) end julia> compile(model_def, (;b=2)) BUGSModel (parameters are in transformed (unconstrained) space, with dimension 0): Model parameters: Variable sizes and types: a: type = Int64 b: type = Int64 ``` i.e., an easier way to introduce external functions into JuliaBUGS. This can't fully replace `@register_primitive` yet, because using `Main` module is relying on Julia runtime behavior and not very intuitive. Examples: ```julia julia> module TestModule bar(x) = x + 1 end Main.TestModule julia> model_def = @bugs begin a = TestModule.bar(b) end quote a = TestModule.bar(b) end julia> compile(model_def, (; b = 1)) ERROR: UndefVarError: `TestModule` not defined in `JuliaBUGS` ... ``` one would need to do ```julia julia> model_def = @bugs begin a = Main.TestModule.bar(b) end quote a = Main.TestModule.bar(b) end ``` also ```julia julia> @testset "t" begin foo1(x) = x + 1 model_def = @bugs begin a = Main.foo1(b) end compile(model_def, (; b= 1)) end t: Error During Test at REPL[18]:1 Got exception outside of a @test UndefVarError: `foo1` not defined in `Main` ... ``` --- Project.toml | 2 +- src/parser/bugs_macro.jl | 2 ++ test/compile.jl | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 982689e6c..f9783e7da 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "JuliaBUGS" uuid = "ba9fb4c0-828e-4473-b6a1-cd2560fee5bf" -version = "0.6.5" +version = "0.7.0" [deps] AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001" diff --git a/src/parser/bugs_macro.jl b/src/parser/bugs_macro.jl index b54287d00..d50982df5 100644 --- a/src/parser/bugs_macro.jl +++ b/src/parser/bugs_macro.jl @@ -151,6 +151,8 @@ function bugs_expression(expr, line_num) error( "Keyword argument syntax is not supported in BUGS, error at $line_num: $(expr)" ) + elseif Meta.isexpr(expr, :.) + return expr else error("Invalid expression at $line_num: `$expr`") end diff --git a/test/compile.jl b/test/compile.jl index 067df5f70..a2af7942a 100644 --- a/test/compile.jl +++ b/test/compile.jl @@ -87,3 +87,11 @@ end @test AbstractPPL.get(model_init_1.evaluation_env, @varname(beta)) == 1 end end + +@testset "dot call" begin + model_def = @bugs begin + x[1:2] ~ Distributions.product_distribution(fill(Distributions.Normal(0, 1), 2)) + end + model = compile(model_def, (;)) + @test model.evaluation_env.x isa Vector{Float64} +end