Hi, I just came across some nice pattern, while working on GLUtils. I don’t know if it’s already commonly known as its pretty simple, but I’m pretty excited, as it is the first step in the direction of writing fast code for unknown types. (Which is quite huge, for re-usability of code) Problem it solves: You have a calculation on some type, whereas the type can be anything, but needs to satisfy certain properties. So you can write some specialized functions without checks, for types, where you already know that they satisfy the properties, and you write a function which takes Any as a type, and does the calculation after it did some checks, which sacrifices performance. You can leave out the checks, to let the runtime check if the type satisfies the properties, but that doesn’t always work (for example, if you interface with C, where you just get segfaults, if something is wrong) and you sacrifice meaningful error messages. So why not use multiple dispatch and eval, to make specialized functions for new types, that satisfy the properties? Example from my GLUtil package, which extracts eltypes from any immutable vector, or color type (could be extended to matrixes):
function eltype(x::Any) T = typeof(x) # type checks if !isbits(T) error(T, " is not a bitstype, so it doesn't have the right memory layout") end types = T.types if isempty(types) error(T, " does not have any fields") end ftype = first(types) if any(t -> t!= ftype, types) error("field types are not homogenious for: ", T) end # We can return the field type, # this means we can make a more specific function for this type eval(( :(fieldtype(x::$T) = $ftype) )) return ftype end Another one, which probably would need some more work : function plus(a, b) T = typeof(a) @assert T == typeof(b) # don't neccessarily need to be of the same type, but which type to return if not the same? types = T.types # type checks if isempty(types) error(T, " does not have any fields") end if !all(t -> t <: Number, types) error("Not all field types are a number for: ", T) end fields = names(T) # create args for creating the resulting addition args = ntuple(i -> begin :(a.$(fields[i]) + b.$(fields[i])) end, length(fields)) body = quote # creating the new type $T($(args...)) end println("I needed to do all the tests :(") # create new specialized function f = eval( :(plus(a::$T, b::$T) = $body) ) return f(a,b) end immutable TEST x::Float32 y::Float32 end t1 = TEST1(3,2) @show plus(t1, t1) --> I needed to do all the tests :( \n TEST(6f0,4f0) @show plus(t1, t1) --> TEST(6f0,4f0)