Skip to content

Instantly share code, notes, and snippets.

@SegFaultAX
Created August 16, 2012 00:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save SegFaultAX/3364849 to your computer and use it in GitHub Desktop.
Save SegFaultAX/3364849 to your computer and use it in GitHub Desktop.
Lua Multimethods (Clojure-style)
function defmulti(keyfn)
if not keyfn then
keyfn = function(...) return ... end
end
local multi = {
_keyfn = keyfn,
_methods = {}
}
setmetatable(multi, {
__call = function(self, ...)
local key = self._keyfn(...)
if self._methods[key] then
return self._methods[key](...)
else
if self._methods.default then
return self._methods.default(...)
else
error("no dispatch for key: " .. tostring(key))
end
end
end
})
return multi
end
function defmethod(multi, key, fn)
if not multi._methods then
multi._methods = {}
end
multi._methods[key] = fn
end
fib = defmulti(tonumber)
defmethod(fib, 0, function() return 0 end)
defmethod(fib, 1, function() return 1 end)
defmethod(fib, "default", function(n) return fib(n-1) + fib(n-2) end)
print(fib(10))
greet = defmulti(function(user) return user.name end)
defmethod(greet, "mk", function() return "MK is 1337" end)
defmethod(greet, "mark", function() return "Mark is a lamer" end)
defmethod(greet, "default", function(user) return string.format("%s seems like a nice fellow", user.name) end)
print(greet({name = "mk"}))
print(greet({name = "mark"}))
print(greet({name = "steven"}))
@min4builder
Copy link

This only overloads the first parameter, and only by value (not by type).

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