Skip to content

Instantly share code, notes, and snippets.

@mudasobwa
Created March 13, 2015 06:03
Show Gist options
  • Save mudasobwa/c3a47b6620fbab9b6ed7 to your computer and use it in GitHub Desktop.
Save mudasobwa/c3a47b6620fbab9b6ed7 to your computer and use it in GitHub Desktop.
Functional approach to function calls :: Proof of concept
#!/usr/bin/env ruby
require 'awesome_print'
# one case handler, like when in case statement
def whether condition, &cb
$conditions[condition] = cb
$conditions
end
# “others” case handler, like else in case statement
def otherwise &cb
$conditions[:_] = cb
$conditions
end
# shortcut to recursive call
def _ name, param
$functions[name.to_sym].call param
end
# method executor :)
def execute func, *args, &cb
$functions[func.to_sym].call *args, &cb
end
# main switch-case
def poly name, &cb
$functions[name.to_sym] = Proc.new { |arg|
yield arg
known = $conditions.detect { |c,_| c === arg }
(known.nil? ? $conditions[:_] : known.last).call
}
# syntax sugar to provide an ability to call methods in native manner
define_method name do |arg|
execute name.to_sym, arg
end
end
$conditions = { :_ => lambda { raise ArgumentError.new "Please call me properly" } }
$functions = { }
####################################################################
######### main declaration of fibonacci function in DSL ############
####################################################################
poly(:fib) do |n|
whether String do 'I’m not supposed to be called with strings' end
whether 0 do 1 end
whether 1 do 1 end
otherwise do _(:fib, n-2) + _(:fib, n-1) end
end
####################################################################
ap execute :fib, 'STRING'
0.upto(10) do |i|
ap execute :fib, i
end
####################################################################
######### main declaration of factorial function in DSL ############
####################################################################
poly(:fact) do |n|
whether String do 'I would update myself to upport script in strings!' end
whether 0 do 1 end
whether Integer do _(:fact, n-1) * n end
end
####################################################################
0.upto(10) do |i|
ap fact(i) ################## NOTE NATIVE CALL HERE !!!!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment