Skip to content

Instantly share code, notes, and snippets.

@c42f
Last active June 8, 2016 21:53
Show Gist options
  • Save c42f/841ecdfb8af878b34e58 to your computer and use it in GitHub Desktop.
Save c42f/841ecdfb8af878b34e58 to your computer and use it in GitHub Desktop.
Experimenting with generated types
module GeneratedTypes
# First an example of a simple "generic" type
immutable GenericImmutable{FieldNames, FieldTypes<:Tuple}
fieldvalues::FieldTypes
end
@generated function getfield{FieldNames, FieldTypes, Name}(gi::GenericImmutable{FieldNames,FieldTypes},::Type{Val{Name}})
fieldnumber = findfirst(FieldNames, Name)
fieldnumber > 0 || error("Field $name not found")
quote
gi.fieldvalues[$fieldnumber]
end
end
# Here we should define a macro version of getfield. So far it is immutable, so setfield is redundant
# @getfield(x,a) -> getfield(x,Val{:a})
macro getfield(x,a)
:(getfield($x,Val{$(Expr(:quote, a))})) # Is there a better way to insert a quote ":" than this???
end
# An example:
x = GeneratedTypes.GenericImmutable{(:a,:b),Tuple{Int64,Float64}}((1,2.0))
@assert getfield(x,Val{:a}) == 1
@assert getfield(x,Val{:b}) == 2.0
# Next, we need to define a macro that takes modifies a type definition to create a generated type
# It will work like this:
macro generated_type(expr)
println(expr) # For now just show what the parser thinks of the mess below
1
end
@generated_type immutable Foo{N}
if N == 1
quote
A::Int
end
else
quote
B::(Float64,Float64)
C::Bool
end
end
end
# foo{1}(1) == foo{Tuple{:A},Tuple{Int}}(1)
# foo{2}((2.0,3.0),true) == foo{Tuple{:B,:C},Tuple{Tuple{Float64,Float64},Bool}}((2.0,3.0),true)
#
# The macro will also define a @getfield macro and getfield() function
# The inner constructors probably won't work, not sure?
# Outer constructors may or may not work, but they will have to call the "complicated" name of the inner constructor of what is wanted (but can be generated themselves)
end # module
@andyferris
Copy link

Just looking at this again. The line you commented "Yup, it's a hack alright" is the one that is currently forbidden in 0.5 master, since JuliaLang/julia#16040...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment