I'll have the duck!

I promised myself I’d shut-up for awhile, maybe I still should, but I
just couldn’t help myself with this one…

Today I wrote

data = data.transform

but I meant to write

data = transform(data)

While I knew data would be hash, I certainly didn’t want to write a new
Hash method just for this --you reserve extensions for really general
reusable stuff, right? Besides I wanted to remain open to duck typing
and hence any hash-like object.

That’s when it hit me. We haven’t yet taken the full duck type plunge.
We’ve just strapped a quasi-duck onto an old oop type dog. We’re still
defining our methods base on types, not duck types. But what would
defining on duck type mean intead? As it turns out it measn defining on
method dependencies.

Take #transform. Forget what “class” it belongs to. What does it do?
For the sake of this dialog lets say it does this:

def transform
data.to_a
end

Simple. Now, if I want to call #transform on data, all it needs to do
is repond_to #to_a. It need not matter at all what class it is. So
imagine if you will, that instead of “classes” and “methods”, we could
define “ducks” and “quacks”.

duck to_a
quack transform
self.to_a
end
end

Now anything that responded to #to_a could use #transform. I’m not sure
how far this can be taken. Can classes be undone altogegther? But in
anycase, it seems very cool, and I wonder what kind of overall effect
it could have on coding?

T.

duck == mixin

Consider the Enumerable mixin.

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : [email protected]
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong
later.”

From this principle, all of life and physics may be deduced.

On Mon, 24 Jul 2006 08:09:58 +0900, [email protected] wrote:

Now anything that responded to #to_a could use #transform. I’m not sure
how far this can be taken. Can classes be undone altogegther? But in
anycase, it seems very cool, and I wonder what kind of overall effect
it could have on coding?

there’s a language called “self” that has no classes, only prototypes.
if you
can find some material on that, i think you’ll find it interesting.

regards,

I much prefer its (less mature) derivative, Io. Everything is a
message to something else, and everything is a prototype. Very
simple, very powerful (even, dare I say, more powerful than Ruby,
albeit a bit less pretty).

  • Jake McArthur

Jake McArthur wrote:

I much prefer its (less mature) derivative, Io. Everything is a
message to something else, and everything is a prototype. Very simple,
very powerful (even, dare I say, more powerful than Ruby, albeit a bit
less pretty).

  • Jake McArthur
    Actual, real programming languages with compilers or interpreters, a
    code base, applications and vibrant communities are for wimps! Give me
    an academic abstract language like the Pi-Calculus any day!

:slight_smile:

Now that I think of it, Lisp was once an academic abstract language …
some bozo had to spoil it by writing an interpreter for the IBM 704.

Speaking of languages, isn’t FORTRAN 50 years old this year?

On Monday 24 July 2006 11:40, John C. wrote:

duck == mixin

Consider the Enumerable mixin.

Well… i don’t think mixins are exactly that :slight_smile:
what trans proposes is more like excessive duck-typing

imagine a duck
you can make it quack
and you know - what the duck quacks can be processes in many ways…

Duck.quack.record.to_tape.copy.to_cd.send_to producer

might be a bit excessive, but in essential that’s it…
i’ve learned that kind of ‘method’ in Dylan, where you define that stuff
a bit
different - you have a kind of reversed dispatcher that adds classes to
methods and decides which method to use given what object you operate
on.

little syntax help - the stuff in <> are classes, and are
subclasses of

########################################

define method to-s (animal :: )
color(animal)
end

define method color (duck :: )
“brown”
end

define method color (fish :: )
“grey”
end

########################################

the methods are not added to the object - they look like that
afterwards:
(using ruby for that, so it looks a bit nicer :wink:

def color (x)
if x === Animal
if x === Fish
“grey”
elsif x === Duck
“brown”
end
end
end

don’t want to hang around in dylan for too long, but this was a new way
(at
least for me) to express methods…
now, this could be driven further

you could attach methods to objects that respond to specific methods

########################################

methods to_a
def compact
delete_if{|e| e.nil? }
end

def sum
inject{|s,v| s+v}
end
end

class Foo
def to_a
[1,2,3,nil]
end
end

Foo.new.compact.sum

6

########################################

something like that…
i find that is true ducktyping :slight_smile:
however… the beauty is in the eye of the beholder, so it might look
butt-ugly to someone else :expressionless:

i just kinda like the idea itself - the implementation in ruby would be
enormous work (as i imagine it at least) - and would slow down ruby
further…

these assumptions are just in my honest opinion :slight_smile: might as well be
pretty
neat to integrate and work with… but i have my doubts…

On 7/24/06, [email protected] [email protected] wrote:

I promised myself I’d shut-up for awhile, maybe I still should, but I
just couldn’t help myself with this one…

So did I :wink:

Today I wrote

data = data.transform

but I meant to write

data = transform(data)

While I knew data would be hash, I certainly didn’t want to write a new
Hash method just for this --you reserve extensions for really general
reusable stuff, right?

I fail to see this point at 100%, I think this is what subclassing is
for,
but I am really oppused to ducktyping, one needs to be, I am afraid of
things all agree on.
Well I love ducktyping but I call it protcolling and I want early
checking,
and I seem to be alone.
Sorry if I go offtopic.

Besides I wanted to remain open to duck typing

and hence any hash-like object.

Yeah great, you see that is what troubles me, it is completely cool to
talk
about hash-like object, but what is a hash-like object? Which messages
must
a hash-like object respond to? All of Hash, I suppose, thus a subclass,
or
only some, then we can talk about protocols again, but the failure to be
able to define the protocol just worries me.
Again very important: The failure to be able, not to have to, I am 100%
for
the enabeling approach, but who enables constraints and protocol
checking?

That’s when it hit me. We haven’t yet taken the full duck type plunge.

Good!

We’ve just strapped a quasi-duck onto an old oop type dog.

Poor animal.

We’re still

defining our methods base on types, not duck types.

This duck risks to get bitten into it’s tail, by itself. I have the
feeling that method delegation (was this the english name (patrimoine
de
méthode)?) is all you are doing.
But pleas get me straight if I read you wrong.

But what would

defining on duck type mean intead? As it turns out it measn defining on
method dependencies.

Take #transform. Forget what “class” it belongs to. What does it do?
For the sake of this dialog lets say it does this:

I am losing you there :frowning:

def transform
data.to_a
end

Simple.

Well if you say so :wink:

Now, if I want to call #transform on data, all it needs to do

Now anything that responded to #to_a could use #transform. I’m not sure
how far this can be taken. Can classes be undone altogegther? But in
anycase, it seems very cool, and I wonder what kind of overall effect
it could have on coding?

Is this a protocol you try to define, sorry if I am too stupid to get
it,
could you explain to an old dog, as a friendly duck?

T.

Cheers
Robert


Deux choses sont infinies : l’univers et la bêtise humaine (j’y suis,
j’y
reste); en ce qui concerne l’univers, je n’en ai pas acquis la certitude
absolue.

  • Albert Einstein

Robert D. wrote:

On 7/24/06, [email protected] [email protected] wrote:

and hence any hash-like object.

Yeah great, you see that is what troubles me, it is completely cool to talk
about hash-like object, but what is a hash-like object? Which messages
must
a hash-like object respond to? All of Hash, I suppose, thus a subclass, or
only some, then we can talk about protocols again, but the failure to be
able to define the protocol just worries me.
That’s the whole point. Duck-typing means that your class only needs to
define the methods (of Hash, in this case) that the called method
(transform here) needs, not the whole Hash class, without having to
specify a protocol. If you want to specify a protocol, there’s one
example of how to do it here:

http://www.erikveen.dds.nl/monitorfunctions/index.html#6.0.0

Again very important: The failure to be able, not to have to, I am 100% for
the enabeling approach, but who enables constraints and protocol checking?
See above. Second time I’ve used that link in this thread :slight_smile:

T.
Like this evil grin ? (Ok, there are still classes…)



class Object
def method_missing sym, *args
@@ducks.select{|d| d.first == sym}.each do |duck|
return send(duck[1], *args) if duck.last.all?{|i|
respond_to? i}
end
super
end

def self.duck sym, real , *interface
    (@@ducks ||= []) << [sym, real, interface]
end

end

def i_next_to_s
succ.to_s
end

def f_next_to_s
ceil.to_s
end

Object.duck :next_to_s, :i_next_to_s, :succ, :to_s
Object.duck :next_to_s, :f_next_to_s, :ceil, :to_s

p(41.next_to_s) #=> “42”
p(‘A’.next_to_s) #=> “B”
p(5.5.next_to_s) #=> “6”


cheers

Simon

Now anything that responded to #to_a could use #transform. I’m not
sure
how far this can be taken. Can classes be undone altogegther? But in
anycase, it seems very cool, and I wonder what kind of overall effect
it could have on coding?

:slight_smile: I was thinking things like this a while ago, and a clever friend
pointed me to predicate classes (see google). The idea with them is that
you define a predicate such as “supports the method ‘each’”. You could
call this predicate Enumerable. The predicate is a declaration of your
interface requirements. You can then add methods to this Enumerable
predicate class, such as min, max, inject, etc. From then, anything that
is Enumerable will also support the things you put in to Enumerable.
Pretty cool.

I liked the idea, anyway. I like it because I think it would make it
easier to take things that you’ve already got, things that someone has
given to you perhaps, and say new things about them based on the fact
that they’ve pretty much got the interface you’re looking for (if they
don’t quite have the right interface, you can use predicate classes to
give them the additional “glue” that they need).

I also like it because I don’t think that there’s anything especially
fundamental about classes. With predicate classes, all you’re really
saying is that “if I’ve got something that can do x and y, then I know
that I can equally validly think of it as something that can do z”.

[I should point out here that I don’t imagine Predicate Classes are “the answer”; I’m just pointing to them as being interesting.]

Class hierarchies almost always seem arbitrary and task oriented to me.
That works well when you’ve a particular task in mind, but I think it
falls over when the task changes, or when you’re more interested in the
information in some objects, rather than what they are currently being
used for.

I also think they’re an impediment to being agile because you’re
building up a hierarchy that may not exist. Sure, you can refactor, and
perhaps you’ve got automated tools that do that, but you shouldn’t need
to. You, and any part of your program or someone else’s, ought to be
able to look at some existing objects in any way they choose. You should
be able to say anything you like about your particular way of looking at
those things.

While I like Ruby a great deal (and I really mean that: it’s made
programming fun again, for me), I don’t think contemporary OO is all
that. Something that’s wonderful about Ruby though, is that I think it’s
got every chance of being the platform in which people find that out,
and find a better way.

On the other hand, I could be wrong, in which case Ruby’s already there
:slight_smile:

Cheers,
Benjohn

On 7/24/06, Alex Y. [email protected] wrote:

a hash-like object respond to? All of Hash, I suppose, thus a subclass,
or
only some, then we can talk about protocols again, but the failure to be
able to define the protocol just worries me.
That’s the whole point. Duck-typing means that your class only needs to
define the methods (of Hash, in this case) that the called method
(transform here) needs, not the whole Hash class, without having to
specify a protocol. If you want to specify a protocol, there’s one
example of how to do it here:

Ruby Monitor-Functions - Or Meta-Meta-Programming in Ruby

Well I have read that, kind of, it is a little bit heavy, too heavy I am
afraid.
I still do not get the point, are you saying I am right (let dogs life)
or
are you saying I am wrong (let only ducks life).
Mixins are another nice way to think about it

class Dog
include Duck
… # no this is not the Perl6 Thingy Jabbawalky operator :wink:
end

d = Puppet
d.implements? Duck ==> true

but maybe this is here already, gotta check.
Thx for your considerations
I repeat nevertheless
Ducks are great, unless they kill Dogs :wink:

Cheers
Robert

Again very important: The failure to be able, not to have to, I am 100%
for

the enabeling approach, but who enables constraints and protocol
checking?
See above. Second time I’ve used that link in this thread :slight_smile:

I will not blame you, yet :wink:

Robert D. wrote:

about hash-like object, but what is a hash-like object? Which messages
example of how to do it here:

http://www.erikveen.dds.nl/monitorfunctions/index.html#6.0.0

Well I have read that, kind of, it is a little bit heavy, too heavy I am
afraid.
I still do not get the point, are you saying I am right (let dogs life) or
are you saying I am wrong (let only ducks life).
It’s my opinion that opposition to duck-typing is a bad idea (especially
when dealing with Ruby, given how pervasive it is), but that doesn’t
make it wrong. It is perfectly possible for both dogs and ducks to
co-exist.

Mixins are another nice way to think about it

class Dog
include Duck
… # no this is not the Perl6 Thingy Jabbawalky operator :wink:
end

d = Puppet
d.implements? Duck ==> true
If you’re always supplying Duck’s functionality as a mixin, you can do:

Duck === d
=> true

The beauty of duck-typing is that you don’t have to, though.

If you wanted an Object#implements? method which doesn’t rely on
implementation via mixin, you could do it like this:

class Object
def implements?(module)
my_methods = Set.new(self.public_methods)
module_methods = Set.new(module.instance_methods)
return my_methods.superset?(module_methods)
end
end

Again, that misses the point somewhat, though - duck-typing lets you not
have to think about the concept of a defined interface (in the Module
sense, at least). If your method only calls #foobar on a passed object,
then that object only need respond to the #foobar method.

but maybe this is here already, gotta check.
Thx for your considerations
I repeat nevertheless
Ducks are great, unless they kill Dogs :wink:
You can always check the class of an object, and there are ways to make
the syntax less cumbersome than it might otherwise be.

On 7/24/06, Alex Y. [email protected] wrote:

Yeah great, you see that is what troubles me, it is completely cool
able to define the protocol just worries me.

Mixins are another nice way to think about it
Duck === d
=> true

No that is not what I want (I do that an awful lot but that is very
doggish)
As a matter of fact I want to be ducky, but on the save side.
I’ll explain

module A
def a; “a”; end
def b; “b”, end
end
class DogOne
include A
end
class DogTwo
def a; :a; end
def b; :b; end
end

[DogOne.new, DogTwo.new].map{ |doggy| doggy.implement? A} ==>
[true, true]
====

As a matter of fact I am completely in love with ruby and even with
ducktyping, but
I am terribly in need of early failure.
I want to fail my programs as early as possible

e.g.

def eat ( someAniamal)

someAnimal.a ===> error

is bad (for me, but early failure is a well accpted principle)
while

def eat( somaAniaml)
assure someAnimal.implements? A
is better

In other words, yes I love to use Dogs but when I use Ducks (and there
are
very good reasons to use Ducks, e.g. agile development) I want to get to
know my duck fast.

The beauty of duck-typing is that you don’t have to, though.

Yes I agree 100% but the not-so-beauty is that I cannot (veryeasily)

If you wanted an Object#implements? method which doesn’t rely on

implementation via mixin, you could do it like this:

class Object
def implements?(module)
my_methods = Set.new(self.public_methods)
module_methods = Set.new(module.instance_methods)
return my_methods.superset?(module_methods)
end
end

yes I could, why not, nice idea

Again, that misses the point somewhat, though - duck-typing lets you not

have to think about the concept of a defined interface (in the Module
sense, at least). If your method only calls #foobar on a passed object,
then that object only need respond to the #foobar method.

Is this really a feature, all the times, I do not think so.

Thx again for your thaughts
Robert

Hi –

On Mon, 24 Jul 2006, Alex Y. wrote:

If you’re always supplying Duck’s functionality as a mixin, you can do:

Duck === d
=> true

The beauty of duck-typing is that you don’t have to, though.

I’d go further: the definition of duck typing is that you don’t :slight_smile:

I think Dave T. was always pretty explicit about saying that duck
typing, in practice as well as theory, is something one does instead
of checking class/module ancestry. I think the use of Duck, duck,
quack, etc. as class and method names is kind of misleading. It moves
the class-checking approach into the “duck” namespace – which means
that “duck typing” gets redefined, and it also means that the thing
originally called “duck typing” is left without a name.

What it always comes down to for me is this: in Ruby, at the moment
that you send a message to an object, you send a message to an object.
No amount of checking of class membership – not even, technically,
the prior checking of respond_to? – has any bearing on what happens
when that message is sent.

Duck typing is Dave’s name for an approach to Ruby programming that
attempts to live in harmony with this underlying state of things in
Ruby, rather than covering it up or pretending it isn’t there.

There are two major ramifications of duck typing:

  1. it leads you to understand what’s actually happening every
    time you call a method in Ruby;
  2. it points the way to interesting and productive things you
    can do to harness the way Ruby works, rather than fighting it.

I’ve always agreed with Jim W. that Ruby is “a duck-typed
language”. In other words, as far as Ruby is concerned, everyone is
duck typing: everyone is sending messages to objects, and those
message-sending events are never connected directly to an object’s
ancestry. Hence #1 in the list above.

As for #2 – it’s not that it’s a mark of shame to use #is_a? and
#respond_to?, but rather that Ruby does provide a programming
environment in which it’s possible, thanks to a design that eschews
certain constraints, to do otherwise, with good results.

Final note to Alex: much of what’s here is in response to the whole
thread, even though it’s in a response to your post :slight_smile:

David

On Jul 23, 2006, at 10:59 PM, Jake McArthur wrote:

I much prefer its (less mature) derivative, Io. Everything is a
message to something else, and everything is a prototype. Very
simple, very powerful (even, dare I say, more powerful than Ruby,
albeit a bit less pretty).

  • Jake McArthur

You piqued my curiosity with that. But “lo” is really hard to google
for. Do you have any reference links?
-Mat

Robert D. wrote:

On 7/24/06, Alex Y. [email protected] wrote:

def implements?(module)
my_methods = Set.new(self.public_methods)
module_methods = Set.new(module.instance_methods)
return my_methods.superset?(module_methods)
end
end

yes I could, why not, nice idea
I think it does everything you’re after.

Again, that misses the point somewhat, though - duck-typing lets you not

have to think about the concept of a defined interface (in the Module
sense, at least). If your method only calls #foobar on a passed object,
then that object only need respond to the #foobar method.

Is this really a feature, all the times, I do not think so.
Absolutely. It’s what makes the entire Enumerable module so useful.
Every single Enumerable method works that way - the object only has to
support the #each method for all of Enumerable’s methods to be
applicable. The #to_s method is similar - anything that supports #to_s
has a whole raft of functionality available to it because methods know
that they’ve got a way of treating it as a string.

Robert D. wrote:

Maybe we can fly. Maybe. But I do not believe so.
It just strikes me as if the community is throwing away so much by being,
forgive me to be blunt, intolerant about philosophies that are well known,
like early failing.
Although I said intolerant I want to add immediately that they are nicely
so, but quite firmely.
Duck typing doesn’t stop you from failing early. If you combine the
#implements? method with the monitor-functions example from earlier in
the thread, you’ve got quite a nice interface checker.

You can have your duck and eat it too.

On 7/24/06, [email protected] [email protected] wrote:

The beauty of duck-typing is that you don’t have to, though.

I’d go further: the definition of duck typing is that you don’t :slight_smile:

Maybe we can fly. Maybe. But I do not believe so.
It just strikes me as if the community is throwing away so much by
being,
forgive me to be blunt, intolerant about philosophies that are well
known,
like early failing.
Although I said intolerant I want to add immediately that they are
nicely
so, but quite firmely.

I think Dave T. was always pretty explicit about saying that duck

typing, in practice as well as theory, is something one does instead
of checking class/module ancestry. I think the use of Duck, duck,
quack, etc. as class and method names is kind of misleading. It moves
the class-checking approach into the “duck” namespace – which means
that “duck typing” gets redefined, and it also means that the thing
originally called “duck typing” is left without a name.

I have to say sorry though about this one, I completely lost the
original
topic in my holy war, good you pointed it out!
[Snip ]

                                 Slashdot, 7/12/2006!)

http://dablog.rubypal.com => D[avid ]A[. ]B[lack’s][ Web]log
[email protected] => me

Cheers Robert


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

You piqued my curiosity with that. But “lo” is really hard to google
for. Do you have any reference links?

Actually it is pretty easy to google: Io programming language :wink:

http://www.iolanguage.com/about/

Regards,
Rimantas

On Jul 24, 2006, at 8:52 AM, Rimantas L. wrote:

You piqued my curiosity with that. But “lo” is really hard to google
for. Do you have any reference links?

Actually it is pretty easy to google: Io programming language :wink:

http://www.iolanguage.com/about/

Right. io, not LO… silly sans-serif fonts.
Thanks!
-Mat