Skip to content

Instantly share code, notes, and snippets.

@yloiseau
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yloiseau/a85ce83bef2600d4eb86 to your computer and use it in GitHub Desktop.
Save yloiseau/a85ce83bef2600d4eb86 to your computer and use it in GitHub Desktop.
Macro operators

Just played with the idea of allowing user-defined operators via macros...

This is working code.

If we continue this idea, right/left associativity and distributivity priority must be implemented (options of the &operator macro).

module MacroOperators

union Option = {
 Some = { value }
 None
}

# monadic bind
&operator (">>=", |monad, func| -> match {
  when monad is None() then monad
  otherwise func(monad: value())
})

# inverse function application, similar to unix pipe
# (since binary operation are right associative, we must check the types)
&operator (">", |value, func| -> match {
  when isClosure(value) then value: andThen(func)
  otherwise func: invoke(value)
})

# function application operator
&operator ("$", |func, value| -> func: invoke(value))

&operator ("<<", |x| -> 2 * x)

function f = |x| -> x + 1

function g = |x| -> 2 * x

function div = |x| -> match {
  when (x % 2) == 0 then Some(x / 2)
  otherwise None()
}

function main = |args| {
  println(Some(3) &>>= ^div) # None
  println(Some(4) &>>= ^div) # Some(2)
  println(None() &>>= ^div)  # None

  println(3 &> ^f &> ^g)  # g(f(3)) -> 8

  println(^g &$ ^f &$ 3)  # g(f(3)) -> 8

  println($<< 4) # -> 8

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