I was just thinking about a problem, and I happened to be pseudo coding
partially in Ruby, partially something else. Then I figured the pseudo code
might be useful Ruby.
In Ruby you can use case / when to branch you code based on object type. But
it’s generally not seen as good style to branch on type in Ruby, because it
violates the duck typing principle. (If it quacks its a duck).
But in line with Ruby’s duck typing why not add some duck matching:
My original problem involved getting arguments in that was either a
collection or a single item, for example a generic product method. So I
thought it would be nice to be able to branch the code based on whether an
argument had the “each” method. This lead to the idea of a kind of pattern
matching based on available methods instead of the more strict matching on a
class.
def product (x, y)
p = 0
match_methods(x, y)
when(:each, nil) x.each {|a| p = p + a.multiply(y) }
when(nil, :each) y.each {|b| p = p + x.multiply(b) }
when(nil, nil) p = x.multiply(y)
end
return p
end
(Might also be nice to branch based on whether a method yields or takes a
code block as argument).
It is somewhat similar to type matching in languages like OCaml, except here
you match the duck type, not the class type.
In the above example, more than one argument could be involved. In the
following example a single argument is used, but more methods can be
avaialbe. As with case statements the first match top down is executed.
def classify creature
match_methods (creature)
when(:quacks :wings) puts "duck"
when(:quacks) puts (“hunter”)
when(:wings :feather) puts "bird"
when(:wings :nocturnal) puts "probably bat or batman"
when(:wings) puts "airborne"
when(:legs) if creature.legs.count == 8 then puts “spider” else puts
"walking creature"
end
end
Mikkel
[snip]
So I thought it would be nice to be able to branch the code based on > whether an argument had the “each” method. This lead to the idea of
a kind of pattern matching based on available methods instead of the
more strict matching on a class.
def product (x, y)
p = 0
match_methods(x, y)
when(:each, nil) x.each {|a| p = p + a.multiply(y) }
when(nil, :each) y.each {|b| p = p + x.multiply(b) }
when(nil, nil) p = x.multiply(y)
end
return p
end
(Might also be nice to branch based on whether a method yields or takes a
code block as argument).
It is somewhat similar to type matching in languages like OCaml, except here
you match the duck type, not the class type.
Yes, this is pattern-matching ala Standard ML, this is realy nice ![:wink: :wink:](https://emoji.discourse-cdn.com/twitter/wink.png?v=12)
also know as multimethods, double dispatch, visitor.
[snip]
What are your question ?
do you want multimethods ?
regards
Simon Strandgaard
···
On Mon, 21 Oct 2002 02:41:53 +0200 “MikkelFJ” mikkelfj-anti-spam@bigfoot.com wrote:
Why not define a class whose === operator is true for objects that have
certain methods - or even check arity - possibly even bind the specific
method and toss give it a proc that raises an exception to test to yielding.
Then you can just us the DuckIdentity class in a case block - no need for new
constructs, and DuckIdentity can be enhanced with things like attribute
stuff…
···
On Sunday 20 October 2002 07:52 pm, MikkelFJ wrote:
I was just thinking about a problem, and I happened to be pseudo coding
partially in Ruby, partially something else. Then I figured the pseudo code
might be useful Ruby.
In Ruby you can use case / when to branch you code based on object type.
But it’s generally not seen as good style to branch on type in Ruby,
because it violates the duck typing principle. (If it quacks its a duck).
But in line with Ruby’s duck typing why not add some duck matching:
My original problem involved getting arguments in that was either a
collection or a single item, for example a generic product method. So I
thought it would be nice to be able to branch the code based on whether an
argument had the “each” method. This lead to the idea of a kind of pattern
matching based on available methods instead of the more strict matching on
a class.
def product (x, y)
p = 0
match_methods(x, y)
when(:each, nil) x.each {|a| p = p + a.multiply(y) }
when(nil, :each) y.each {|b| p = p + x.multiply(b) }
when(nil, nil) p = x.multiply(y)
end
return p
end
(Might also be nice to branch based on whether a method yields or takes a
code block as argument).
–
Judson
“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com wrote in message
news:20021021094724.08fbbc13.0bz63fz3m1qt3001@sneakemail.com…
Yes, this is pattern-matching ala Standard ML, this is realy nice ![:wink: :wink:](https://emoji.discourse-cdn.com/twitter/wink.png?v=12)
also know as multimethods, double dispatch, visitor.
[snip]
What are your question ?
do you want multimethods ?
I neither want or do not want multimethods. It was just an idea I wanted to
share. I though it was original because I haven’t seen any kind of pattern
matching working on supported methods before.
I don’t think this is the same as multimethods - one reason being that the
technology is not assocatiated with formal function arguments - although it
could be used there as well.
Mikkel