[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Duck Typing and automated Conversions

Robert Klemme

1/14/2005 10:12:00 AM


Hi all,

conversion of method parameters seems to be a quite common scenario,
example:

def silly_example(str, count)
str = str.to_str
count = count.to_int

s = ""
count.times { s << str }
s
end

Usually these conversions are documented as requirements for method
parameters. We could make them a bit more explicit without changing much
especially not the power of Duck Typing. Here's an idea:

def silly_example(str.to_str, count.to_int)
# str and count are converted like in the example above
s = ""
count.times { s << str }
s
end

Basically this is just a way to save typing. Error reporting will be the
same. RDoc could evaluate this info and generate comments for this
automagically.

Of course, any method could be invoked like this, maybe even with
parameters. I haven't thouroughly thought about implications of that fact
yet.

Thoughs?

robert

40 Answers

Pit Capitain

1/14/2005 11:45:00 AM

0

Robert Klemme schrieb:
>
> def silly_example(str.to_str, count.to_int)
> # str and count are converted like in the example above
> s = ""
> count.times { s << str }
> s
> end
>
> Basically this is just a way to save typing. Error reporting will be the
> same. RDoc could evaluate this info and generate comments for this
> automagically.
>
> Of course, any method could be invoked like this, maybe even with
> parameters. I haven't thouroughly thought about implications of that fact
> yet.
>
> Thoughs?

Interesting idea. I think it's very readable.

Regards,
Pit


dblack

1/14/2005 11:49:00 AM

0

Robert Klemme

1/14/2005 12:06:00 PM

0


"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.61.0501140338360.14852@wobblini...
> Hi --
>
> On Fri, 14 Jan 2005, Robert Klemme wrote:
>
> >
> > Hi all,
> >
> > conversion of method parameters seems to be a quite common scenario,
> > example:
> >
> > def silly_example(str, count)
> > str = str.to_str
> > count = count.to_int
> >
> > s = ""
> > count.times { s << str }
> > s
> > end
> >
> > Usually these conversions are documented as requirements for method
> > parameters. We could make them a bit more explicit without changing
much
> > especially not the power of Duck Typing. Here's an idea:
> >
> > def silly_example(str.to_str, count.to_int)
> > # str and count are converted like in the example above
> > s = ""
> > count.times { s << str }
> > s
> > end
> >
> > Basically this is just a way to save typing. Error reporting will be
the
> > same. RDoc could evaluate this info and generate comments for this
> > automagically.
> >
> > Of course, any method could be invoked like this, maybe even with
> > parameters. I haven't thouroughly thought about implications of that
fact
> > yet.
> >
> > Thoughs?
>
> I personally don't like the '.' notation used for anything other than
> method calls (and floats :-) I just think it's too important and
> central a notation to be borrowed for something else, even something
> that is somewhat kindred to a method call (but isn't one).

In fact the first character that came to mind was '#'. The char to use
here is not important to me. Here are some alternatives:

def silly_example(str.to_str, count.to_int)
def silly_example(str#to_str, count#to_int)
def silly_example(str:to_str, count:to_int)
def silly_example(str::to_str, count::to_int)

> There's also the question of the interaction of this with duck typing.
> Of course that's always a programmer's choice, but I could imagine
> cases where the caller would expect a duck-typing treatment and not
> get it. For example:
>
> obj = Object.new
> def obj.times; 10; end
> str = silly_example("hello", obj)
>
> Here you have an object that responds to 'times', so it's capable of
> being treated in a duck-typing way by simply being sent the message
> 'times' -- but if you intercept the object and do a to_int on it,
> there's trouble.

Well, of course. But in those cases you would not use that notation. You
would simply declare the parameter as you do now and write a comment that
this parameter must respond to #times.

Btw, did you purposely just return an int from your definition of times?
I mean, no block is invoked from that method.

> (Of course you could document your method by saying that it requires
> an object that responds to to_int, but that seems a bit roundabout
> compared to just saying you want an object that responds to times.)

It's just another (supposedly shorter) form to write a common idiom. If
the writer of silly_example decides to do more complex treatment, he can
still do that. We don't loose anything. Note, that the creator of your
obj.times() would be similarly surprised if the implementor of
silly_example had choosen to do it exactly like I presented in the first
example.

I'm not sure whether I missed your point altogether. Could you please
elaborate? Thanks!

Kind regards

robert



Ilmari Heikkinen

1/14/2005 12:46:00 PM

0

Hi,

On 14.1.2005, at 12:16, Robert Klemme wrote:
> def silly_example(str.to_str, count.to_int)
> # str and count are converted like in the example above
> s = ""
> count.times { s << str }
> s
> end

Not to argue against possible syntatic sugar, but you can already do
this in the method signature:

def silly_example(ostr, ocount, str=ostr.to_str, count=ocount.to_int)




Robert Klemme

1/14/2005 1:20:00 PM

0


"Ilmari Heikkinen" <kig@misfiring.net> schrieb im Newsbeitrag
news:39518454-662A-11D9-AB45-000A95CD3934@misfiring.net...
> Hi,
>
> On 14.1.2005, at 12:16, Robert Klemme wrote:
> > def silly_example(str.to_str, count.to_int)
> > # str and count are converted like in the example above
> > s = ""
> > count.times { s << str }
> > s
> > end
>
> Not to argue against possible syntatic sugar, but you can already do
> this in the method signature:
>
> def silly_example(ostr, ocount, str=ostr.to_str, count=ocount.to_int)

Yeah, I know, but that's quite inconvenient IMHO. Also you need to
duplicate the number of your parameters plus it won't work with varying
lenght argument lists.

Regards

robert

dblack

1/14/2005 1:30:00 PM

0

dblack

1/14/2005 1:31:00 PM

0

Ilmari Heikkinen

1/14/2005 1:42:00 PM

0

Hi,

On 14.1.2005, at 15:31, David A. Black wrote:
>> def silly_example(ostr, ocount, str=ostr.to_str, count=ocount.to_int)
>
> Yes except that then someone could call it like this:
>
> silly_example("hi", 1, "hello", 2)
>
> and clobber the conversions you were doing.

Could argue that it's wanted behavior.. "if you want to hack this
without hacking to_str and to_int, replace the defaulted args"

Since this IMHO is pretty much an auto-documented wish for the caller
to supply objects that act like ducks.



gabriele renzi

1/14/2005 1:45:00 PM

0

Robert Klemme ha scritto:

> Basically this is just a way to save typing. Error reporting will be the
> same. RDoc could evaluate this info and generate comments for this
> automagically.
>
> Of course, any method could be invoked like this, maybe even with
> parameters. I haven't thouroughly thought about implications of that fact
> yet.
>
> Thoughs?
>

Yes, one. See RCR 280, add this, and you get quite far in replicating
what mr van rossum is advocating as optional typing for python :) [1]
With pre/post method hook as supposed to be in Ruby2, you get even further.

[1]only the last post, the "stop flames" one would recall this, ignore
the other two.

Robert Klemme

1/14/2005 1:54:00 PM

0


"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.61.0501140520470.15307@wobblini...
> Hi --
>
> On Fri, 14 Jan 2005, Robert Klemme wrote:
>
> >> [I wrote:]
> >>
> >> There's also the question of the interaction of this with duck
typing.
> >> Of course that's always a programmer's choice, but I could imagine
> >> cases where the caller would expect a duck-typing treatment and not
> >> get it. For example:
> >>
> >> obj = Object.new
> >> def obj.times; 10; end
> >> str = silly_example("hello", obj)
> >>
> [...]
> > Btw, did you purposely just return an int from your definition of
times?
> > I mean, no block is invoked from that method.
>
> I did it wrong. It should be:
>
> def obj.times(&block)
> 10.times &block
> end
>
> >> (Of course you could document your method by saying that it requires
> >> an object that responds to to_int, but that seems a bit roundabout
> >> compared to just saying you want an object that responds to times.)
> >
> > It's just another (supposedly shorter) form to write a common idiom.
If
> > the writer of silly_example decides to do more complex treatment, he
can
> > still do that. We don't loose anything. Note, that the creator of
your
> > obj.times() would be similarly surprised if the implementor of
> > silly_example had choosen to do it exactly like I presented in the
first
> > example.
> >
> > I'm not sure whether I missed your point altogether. Could you please
> > elaborate? Thanks!
>
> Partly I'm just very conservative about special-case syntax and
> shortcuts. I can't define exactly why, or exactly where I draw the
> line, or whether there's even a line.... I think I'm also not
> convinced that this (to_int etc.) is common enough or special enough
> to warrant a change in method definitions semantics. I don't think I
> can get much more concrete than that, so it may be that at some level
> I don't have a point, rather than that you've missed it :-)

Ah, ok, I see... :-) Then let's see with what others come up. Maybe I've
orverlooked a complete showstopper and we can forget about this
immediately.

About usage of to_int et al: as these methods are fairly recent (compared
to to_i and others) I'd guess that usage is increasing and they might not
yet be as prolific as I assumed. Don't have exact numbers though.

Thanks for sharing your thoughts!

Kind regards

robert