Skip to content

Instantly share code, notes, and snippets.

@cscherrer
Created April 20, 2021 22:18
Show Gist options
  • Save cscherrer/656eb13fdefea23f61bf65c6b13c4bd1 to your computer and use it in GitHub Desktop.
Save cscherrer/656eb13fdefea23f61bf65c6b13c4bd1 to your computer and use it in GitHub Desktop.
A convenient way to create a new TupleVector from an existing one
using MacroTools: @q
using GeneralizedGenerated
struct TypelevelExpr{T}
expr::Expr
TypelevelExpr(expr::Expr) = new{to_type(expr)}(expr)
end
@gg function with(nt::NamedTuple{N,T}, ::TypelevelExpr{E}) where {N,T,E}
ex = from_type(E)
q = @q begin end
for x in N
xname = QuoteNode(x)
push!(q.args, :($x = Base.getproperty(nt, $xname)))
end
push!(q.args, ex)
q
end
macro with(nt, ex)
tle = TypelevelExpr(ex)
quote
with($nt, $tle)
end |> esc
end
nt = (x=1,y=3.0)
with(nt, TypelevelExpr(:(x^2 - y)))
@with nt begin
x^2 - y
end
#########################################
using SampleChains
using SampleChains: chainvec
function with(tv::TupleVector{T,X}, ex::TypelevelExpr{E}) where {T,X,E}
n = length(tv)
result = chainvec(with(tv[1], ex), n)
for j in 2:n
result[j] = with(tv[j], ex)
end
return result
end
# Example: Box-Muller sampling algorithm
tv = TupleVector((u=rand(1000), v=rand(1000)))
@with tv begin
r = sqrt(-2 * log(u))
(x = r * cospi(2v), y = r * sinpi(2v))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment