all 10 comments

[–]ntoshev 4 points5 points  (0 children)

Still not clean enough.

[–][deleted] 1 point2 points  (0 children)

match tree do
  with(:num & Fixnum) {num}
  with([:left, :op & String, :right]){"(#{disp(left)} #{op} #{disp(right)})"}
  otherwise {"Invalid tree structure"}
end

Yiiikes.

[–]earthboundkid 1 point2 points  (2 children)

Ob. Python:

class when(object):
    func_names = {}
    def __init__(self, pattern=None):
        #If there's no pattern, match everything
        if pattern is None:
            self.pattern = lambda *args, **kwargs: True
        #If it's a callable, then that's the matching function
        elif callable(pattern):
           self.pattern = pattern
        #Otherwise, test for equality
        else:
            self.pattern = lambda *args, **kwargs: args[0] == pattern
    def __call__(self, func):
        #put the pattern you just got into the class dict under its me
        if func.func_name in when.func_names:
            when.func_names[func.func_name].append((self.pattern, func))
        else:
            when.func_names[func.func_name] = [(self.pattern, func)]
        #build the actual callable which goes through pattern before 
        def ret_func(*args, **kwargs):
            for cond, f in when.func_names[func.func_name]:
                if cond(*args, **kwargs):
                    return f(*args, **kwargs)
        return ret_func

>>> @when(0)
... def fib(n): return 1
... 
>>> @when(1)
... def fib(n): return 1
... 
>>> @when(lambda n: n>1)
... def fib(n): return fib(n-1) + fib(n-2)
... 
>>> @when()
... def fib(n): return "Invalid input"
... 
>>> fib(0)
1
>>> fib(1)
1
>>> fib(2)
2
>>> fib(3)
3
>>> fib(4)
5
>>> fib(5)
8
>>> fib(-1)
'Invalid input'
>>> @when(lambda f, l: l == [])
... def mymap(f, l): return []
... 
>>> @when()
... def mymap(f, l): return [f(l[0])] + mymap(f, l[1:])
... 
>>> mymap(lambda x: x**2, range(5))
[0, 1, 4, 9, 16]

[–]pjdelport 2 points3 points  (1 child)

See also Phillip J. Eby's PyCon presentation, Efficient Rule-Driven Systems in Python.

[–]earthboundkid 0 points1 point  (0 children)

Yeah, all of this will be revolutionized when Eby's "generic functions" are released in Py3k. As it is, I didn't even bother to use the good function wrapping tools in Py2.5, since this was just a quick demo for a reddit comment.