Skip to content

Instantly share code, notes, and snippets.

@fcard
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save fcard/f49fbc730e9319f9eb07 to your computer and use it in GitHub Desktop.

Select an option

Save fcard/f49fbc730e9319f9eb07 to your computer and use it in GitHub Desktop.
ExpressionPatterns Examples
ematch(:(a+b = c), :(a+b = c))
ematch(:(a+b = c), :(1+2 = 3), variable=:?)
ematch(:(a+b = c), :(1+2 = 3))
ematch(:(a,b), :(b,a))
ematch(:(a::!,b), :(b,a))
ematch(:(a::!,b), :(a,a))
ematch(:(a::?+b = c::?), :(1+b = 3), variable=:?)
ematch(:(a::?+b = c::?), :(1+d = 3), variable=:?)
ematch(:(x,x), :(1,2))
ematch(:((x::&),x), :(1,2), consistency=true)
ematch(:((x::&),x), :(1,1), consistency=true)
ematch(:(1...), :(1,1,1,1))
ematch(:([1,2]...), :(1,2,1,2,1,2))
ematch(:((1,2)...), :((1,2),(1,2),(1,2)))
ematch(:(a...), :(1,2,3,4,5,6,7))
ematch(:((a::&)...), :(1,2,3,4,5,6,7), consistency=true)
ematch(:((a::&)...), :(1,1,1,1,1,1,1), consistency=true)
#same as @destruct let
@elet (x,y) = :(1,2) begin
x + y
end
@elet (f(x,y)) = :(a+b) begin
(f,x,y)
end
let ex = :(for (x,y) in [[1,2],[3,4]]
println(x)
println(y)
end)
@elet (for el in coll body... end) = ex begin
(el, coll, body)
end
end
let ex = :(x -> 2x + 10)
(@destruct (x -> a*x + b) -> a)(ex)
end
name(x::Symbol) = x
@destruct name(M.m) = name(m)
@destruct function applyall((fs,xss...)...)
map((f,xs)->:($f($(xs...))), fs, xss)
end
@destruct macro reverse_operands(f(x,y))
:($f($y,$x))
end
@destruct macro for_to_map(for x in coll body... end)
:(map($coll) do $x; $(body...) end)
end
@macromethod derivate(x -> a + b) esc(:($x -> ($x -> $a)($x) + ($x -> $b)($x)))
@macromethod derivate(x -> a - b) esc(:($x -> ($x -> $a)($x) - ($x -> $b)($x)))
#...
@macromethod derivate((x::&) -> x) esc(:($x -> 1))
@macromethod derivate((x::&) -> c) esc(:($x -> 0))
@macromethod polynomial_terms(a::$Symbol) [[:constant=>1, :exponent=>1]]
@macromethod polynomial_terms(a::$Number) [[:constant=>a, :exponent=>0]]
@macromethod polynomial_terms(c*(a^e)) [[:constant=>c, :exponent=>e]]
@macromethod polynomial_terms(a^e) [[:constant=>1, :exponent=>e]]
@macromethod polynomial_terms(c*a) [[:constant=>c, :exponent=>1]]
@macromethod polynomial_terms(a + b) :[@polynomial_terms($a)..., @polynomial_terms($b)...]
@macromethod polynomial_terms(+(a,b...)) :[@polynomial_terms($a)..., @polynomial_terms(+($(b...)))...]
@macromethod polynomial_terms(a - b) quote
let polyb = @polynomial_terms($b)
for pb in polyb; pb[:constant] = -(pb[:constant])
[@polynomial_terms($a)..., polyb...]
end
end
@macromethod polynomial_terms(f()) []
# switch statement
function makeifs(value, casevalues, expressions)
map(casevalues,expressions) do casevalue, expression
:(if $value == $casevalue; $expression end)
end
end
function applyifs(default, ifs)
foldr(default, ifs) do ifexpr, elsexpr
push!(ifexpr.args, quote $elsexpr end)
ifexpr
end
end
getdefault(maybe_default) = isempty(maybe_default)?
:(error("no matching case in switch!")) :
(first(maybe_default))
@destruct macro switch(value, begin ((case::!)(casevalues) => expressions)...
((default::!) => default)...; end)
applyifs(getdefault(default), makeifs(value, casevalues, expressions))
end
#= usage
@switch x begin
case(c1) => expr1
case(c2) => expr2
...
default => defaultexpr
end
=#
@macromethod mm(x)[any] 1
@macromethod mm(x+y)[+] 2
@macromethod mm(x-y)[-] 3
@macromethod mm(f(x,y))[f] 4
macromethods(:mm) #=>
4-element Array{MacroMethod,1}:
@mm(x,)[P=0, L=any]
@mm(x + y,)[P=10, L=+]
@mm(x - y,)[P=20, L=-]
@mm(f(x,y),)[P=30, L=f]
=#
@mm x #> 1
@mm x+y #> 1
@mm x-y #> 1
@mm f(x,y) #> 1
@prefer @mm(x+y) over @mm(x)
@mm x+y #> 2
@mm x-y #> 1
@prefer any over @mm(x)
@mm x-y #> 3
@mm f(x,y) #> 4
@prefer f over + in (@mm)
@mm x-y #> 4
@remove_method @mm(x+y)
@mm x+y #> 4
@remove_method f from (@mm)
@mm x+y #> 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment