Re: Can foo(123) dispatch to foo(Int) (was: Mutil Method Questions)
HaloO, Paul Hodges wrote: so back to foo(bar). What's the default behavior? String doesn't Num, does it? though is does convert if the value is good I think that Str and Num are disjoint mutually exclusive types. If you want to get coercive behaviour you need an overloaded foo:(Str|Num) that handles conversions and redispatches. Does that mean foo(123) should or should not dispatch to foo(Int)? Or even foo(Num), for that matter Oy, I could see some headaches around setting these rules in mind, lol What's the DWIMmiest behavior hear? I strongly believe that foo(123) should never *dispatch* to foo:(Int). The best in dwimmery would be an auto-generated foo:(Item) that handles coercions. Would that be switchable by a 'use autocoercions' or so? I assume foo(1) would dispatch to foo(Int) rather than foo(Num), as the most restrictive fit, and I could see how that could blow up in my face. Is there some basic compile time warning (and a way to tell it shut up, I know what I'm doing) that says hey, these are suspiciously close signatures, are you sure this is what you wanted? Last time I checked the subtyping of Perl6 was set-theoretic. That means to me that Int is a strict subset of Num along the lines of subset Int of Num where { .frac == 0 } Note that Num might be implemented as a subclass of Int that adds the fractional part! But subclassing is not subtyping. --
RE: Mutil Method Questions
From: Steffen Schwigon [mailto:[EMAIL PROTECTED] Thomas Wittek [EMAIL PROTECTED] writes: Maybe we should steal the ruby principle of least surprise here, which I find a very good principle. I'm quite confident that Larry already stole all good principles he could find. Me too. However many ongoing discussions on #perl6 and in perl.perl6.language involve how to better reconcile such principles. (Thanks especially to Pubs, which has stimulated a great many refinements and improvements in the Perl 6 language, and continues to do so.) So I think the previously expressed sorts of general concerns are valid, even if there turns out to be {other overriding technical issues, or some sort of misunderstanding} in this particular case. If there would be a Full Metal Perl movie, the imdb quote collection would contain: These are great days we're living, bros. We are jolly green giants, walking the Earth with Perl6. Good start These principles we stole here today are the finest principles we will ever know. After we rotate back However Finest principles known now is extremely likely a subset of finest principles we will ever know (especially considering how relatively recently most were discovered, and especially if you live at least another 10+ years). One *huge* advantage of Perl 6 is to make it *much* easier to copy *new* great ideas as they come along. I think that one of Perl 6's greatest design principles is to anticipate discovering new great design principles. to the world, we're gonna miss not having any principle around that's worth stealing. Oh yea? What about Perl 7!? :-) I expect that Perl 7 will have at least 1 or 2 new finest principles that will be back-ported to Perl 6. My wild guess is that an early perl7 production prototype will be available around 2020. But I think it's a big mistake to get too stuck on specific Perl version numbers, versus featuring the evolutionary role and trajectory of Perl: Perl++, the most natural language of software progress; featuring CPAN++, the executable Wikipedia of software expertise. (This generic designation also has the virtue of reminding people that the other branch of Perl is also evolving, with Perl 5.10 well along in the works, and Perl 5.12 seems a very likely follow-on prospect.) Best regards, Conrad Schneiker http://perl.net.au/wiki/Perl_6_Users_FAQ (Moved from AthenaLab to Perl 6 Wiki.) www.AthenaLab.com (Nano-electron-beam and micro-neutron-beam technology.)
Re: Mutil Method Questions
Thomas Wittek [EMAIL PROTECTED] writes: Steffen Schwigon schrieb: At least the many keywords seem to be necessary to map the complexity of different paradigms possible in Perl6. Multimethods are not just overloading as in C++. Second, the different keywords declare different behaviour you can choose. Just read S06, it's explained quite understandable. Hm, but wouldn't whose be equivalent? sub foo ($bar) { $bar.say; } multi sub foo ($bar) { $bar.say; } Aren't subs a subset of multi subs, meaning that every sub can be expressed as a multi sub? Is there anything a sub has in advantage of a multi sub? So might not just every sub be a multi sub? If the only difference is, that you _must not_ declare a sub twice with different argument lists, I think that this one is relatively unimportant and letting every sub be a multi sub seems to be more consistent to me in opposite to this arbitrary looking distinction. Maybe I just phenomenally misunderstood multi subs, but unless I did, I can't see why we want to have subs when we can have multi subs that can do the same and even more. I understand your point and I confess I'm not sure. At least there seems to be a visibility difference. In S12 I found those two sentences: 1. [sub (or method) without a multi] [...] Only one such sub (or method) can inhabit a given namespace, and it hides any outer subs (or less-derived methods) of the same short name. 2. [subs or methods declared multi] [...] It does not hide any routines with the same short name but a different long name. In other words, multis with the same short name can come from several different namespaces provided their long names differ and their short names aren't hidden by a non-multi declaration in some intermediate scope. GreetinX Steffen -- Steffen Schwigon [EMAIL PROTECTED] Dresden Perl Mongers http://dresden-pm.org/
Re: Mutil Method Questions
Steffen Schwigon: Thomas Wittek [EMAIL PROTECTED]: Maybe I just phenomenally misunderstood multi subs, but unless I did, I can't see why we want to have subs when we can have multi subs that can do the same and even more. I understand your point and I confess I'm not sure. At least there seems to be a visibility difference. In S12 I found those two sentences: 1. [sub (or method) without a multi] [...] Only one such sub (or method) can inhabit a given namespace, and it hides any outer subs (or less-derived methods) of the same short name. 2. [subs or methods declared multi] [...] It does not hide any routines with the same short name but a different long name. In other words, multis with the same short name can come from several different namespaces provided their long names differ and their short names aren't hidden by a non-multi declaration in some intermediate scope. So it looks like we can hide several multis with one sub: class Foo { multi method somesub (Int $arg) { foo - Int: $arg.say } multi method somesub ($arg) { foo - Scalar: $arg.say } } class Bar is Foo { multi method somesub ($arg) { bar - Scalar: $arg.say } } class Baz is Foo { method somesub ($arg) { baz - Scalar: $arg.say } } my $foo = Foo.new; my $bar = Bar.new; my $baz = Baz.new; $foo.somesub(scalar); # foo - Scalar: scalar $foo.somesub(42); # foo - Int: 42 $bar.somesub(scalar); # Bar - Scalar: scalar $bar.somesub(42); #I'd expect (but it doesn't do that, see text below): #using more specialized method from Foo # Foo - Int: 42 $baz.somesub(scalar); # Baz - Scalar: scalar $baz.somesub(42); #_not_ using method from Foo as a non-multi sub overwrites it # Baz - Scalar: 42 Interestingly $bar.somesub(42) doesn't use the multi method somesub (Int $arg) of the class Foo (whose signature would provide a better match) but it also uses multi method somesub ($arg) of the class Bar. So actually every method that somehow matches in a less derived class will be used. The more specialized methods of the more derived classes are hidden, which I didn't expect (but what probably will be better performance wise). So I have no Idea why I would like to use a non-multi as even multis hide the methods of more derived classes. So even if there are cases where I want the non-multi-behavior (what ever it really is), I think they are rare. So I'd suggest that this behavior shouldn't be the default for all subs. Instead I'd find it more intuitive if every sub is a multi sub by default and that you could opt in the non-multi-behavior with a keyword like overriding, dominant or preferred. I think that the multi-behavior will be more common and thus should be the default (as it is in most other languages). The probably less common non-multi-behavior should require an additional keyword. Not vice versa. Again, that's all written from my fairly small knowledge of the Perl6 language. But supposed that one, who starts learning Perl6, will also have a small knowledge at the beginning, this concepts might confuse the beginner, if he/she has to define extra keywords for a behaviour that's probably more common and omitting the keywords will lead to a less common behavior. Maybe we should steal the ruby principle of least surprise here, which I find a very good principle. Maybe someone can enlighten me ;) Best regards, -Thomas
Re: Mutil Method Questions
Thomas Wittek [EMAIL PROTECTED] writes: So it looks like we can hide several multis with one sub: [ example ] Maybe the type system in Pugs is not yet in such a final state to experiment with it in all that details. I can construct other examples or reverse engineer the neighbor discussion about foo(123) where it also doesn't behave as I would expect. Maybe we should steal the ruby principle of least surprise here, which I find a very good principle. I'm quite confident that Larry already stole all good principles he could find. If there would be a Full Metal Perl movie, the imdb quote collection would contain: These are great days we're living, bros. We are jolly green giants, walking the Earth with Perl6. These principles we stole here today are the finest principles we will ever know. After we rotate back to the world, we're gonna miss not having any principle around that's worth stealing. GreetinX Steffen -- Steffen Schwigon [EMAIL PROTECTED] Dresden Perl Mongers http://dresden-pm.org/
Re: Mutil Method Questions
Chris Yocum [EMAIL PROTECTED] writes: Hi All, At the risk of sounding a bit thick, I have a couple of questions about Perl6's multi keyword and mutilmethod in general. This seems like overloaded functions from C++ so why do we need a key word to declare them rather than using something like C++'s name mangling? Is there something that I am just missing here? Because of your question I had a look at Synopsis 6 (http://dev.perl.org/perl6/doc/design/syn/S06.html). I should do this more often. Maybe you should also have a look. It's always refreshing. At least the many keywords seem to be necessary to map the complexity of different paradigms possible in Perl6. Multimethods are not just overloading as in C++. Second, the different keywords declare different behaviour you can choose. Just read S06, it's explained quite understandable. can we now write generic/overloaded functions in Perl6 without OO or have I conflated OO with overloading incorrectly? However it's currently called, with multimethods you can elegantly divide and conquer your code into different subs instead of ugly parameter checking if-cascades. multi sub talk () { say 'Loose Talk Is Noose Talk.'; } multi sub talk (String $msg) { say $msg; } multi sub talk (String $msg, Int $times) { say $msg x $times; } talk(Hi, 10); talk(Hello); talk; GreetinX Steffen -- Steffen Schwigon [EMAIL PROTECTED] Dresden Perl Mongers http://dresden-pm.org/
Re: Mutil Method Questions
Steffen Schwigon [EMAIL PROTECTED] writes: multi sub talk () { say 'Loose Talk Is Noose Talk.'; } multi sub talk (String $msg) { say $msg; } multi sub talk (String $msg, Int $times) { say $msg x $times; } BTW, because we are just on-topic, can someone explain, when these types above are used. They seem pretty useless in my example but it looked that nice. :-) How do I extend the example to really check the parameter types. Some kind of use strict anywhere? GreetinX Steffen -- Steffen Schwigon [EMAIL PROTECTED] Dresden Perl Mongers http://dresden-pm.org/
Re: Mutil Method Questions
Multimethods are not just overloading as in C++. To expand upon this point a little, you can use multimethods to do pattern-matching in the style of ML and similar languages. So, to pinch an example from the pugs tree (examples/functional/fp.p6) multi sub length () returns Int { 0 } multi sub length (*$x, [EMAIL PROTECTED]) returns Int { 1 + length(@xs) } Now you can call length on a list, and the call will be dispatched to the first multi if the list is empty, the second otherwise. In both cases you're passing a list. Really, this use is caused by having slurpy argument lists as much as by the multis. The quicksort example in examples/algorithms/quicksort.p6 is the clearest and most concise description of quicksort I have yet seen. (The version I usually use when teaching ML is not as nice as this one.) Multis also let you define things that look like methods (in the OO sense) outside the class. This is useful because you might want to have common operations on certain objects be as convenient as method calls, but without needing to give them the privileged access to the object data that methods and submethods get, and without modifying the class itself. -- I went to the CO guess what he told me guess what he told me | apologies He said boy u better learn to like Win no matter what u do | to Prince But he's a fool, 'cos nothing compares, nothing compares 2 GNU ^^ http://surreal.istic.org/songs/?file=Nothing%20Compares%202%20GNU.txt signature.asc Description: Digital signature
Re: Mutil Method Questions
On 6/23/06, Steffen Schwigon [EMAIL PROTECTED] wrote: Steffen Schwigon [EMAIL PROTECTED] writes: multi sub talk () { say 'Loose Talk Is Noose Talk.'; } multi sub talk (String $msg) { say $msg; } multi sub talk (String $msg, Int $times) { say $msg x $times; } BTW, because we are just on-topic, can someone explain, when these types above are used. They seem pretty useless in my example but it looked that nice. :-) IMHO they are already used in that example automatically. You just don't see it because every multi sub had different amount of parameters. This example might make it a bit clearer: multi sub talk (String $msg1, String $msg2) { say $msg1 $msg2 } multi sub talk (String $msg, Int $times) { say $msg x $times; } multi sub talk (String $msg, Num $times) { say Please use an integer; } multi sub talk (String $msg, Range $r) { say $_: $msg for $r } talk(Hello, World); # String and String talk(Hi, 2); # String and Int talk(Test, 1.23); # String and Num talk(Hello, 3..5); # String and Range talk(123, 3); # Int and Int I think that would print Hello World HiHi Please use an integer 3: Hello 4: Hello 5: Hello 123123123 In last example, there is no exact match for parameters (Int, Int), so IMHO perl6 would select the closest match, which in this case is (String, Int) because Int can be converted to String. The Range-example is my quess of how Range could be used with for. I'm not 100% sure if that syntax is OK. How do I extend the example to really check the parameter types. Some kind of use strict anywhere? I think that parameter types are automatically checked. Also use strict; is default in perl6, but that's a bit different thing IMHO. -- Markus Laire
Re: Mutil Method Questions
On Fri, Jun 23, 2006 at 06:18:51PM +0300, Markus Laire wrote: multi sub talk (String $msg1, String $msg2) { say $msg1 $msg2 } multi sub talk (String $msg, Int $times) { say $msg x $times; } multi sub talk (String $msg, Num $times) { say Please use an integer; } multi sub talk (String $msg, Range $r) { say $_: $msg for $r } talk(Hello, World); # String and String talk(Hi, 2); # String and Int talk(Test, 1.23); # String and Num talk(Hello, 3..5); # String and Range talk(123, 3); # Int and Int I think that would print Hello World HiHi Please use an integer 3: Hello 4: Hello 5: Hello 123123123 In last example, there is no exact match for parameters (Int, Int), so IMHO perl6 would select the closest match, which in this case is (String, Int) because Int can be converted to String. An alternate interpretation would be that the last one is actually a compile- time error because none of the sigs match (Int,Int) and for a call to work with 2 Int parameters, you'd need to be explicit: talk(~123,3); But I'm not sure which way perl6 actually leans. Though it seems to me that automatic type conversion by the compiler is a way to get yourself in trouble. Not that perl shouldn't let the programmer get himself in trouble, but this seems like one of those things that should require asking to turn on rather than asking to turn off. my two cents, -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Mutil Method Questions
On 6/23/06, Jonathan Scott Duff [EMAIL PROTECTED] wrote: An alternate interpretation would be that the last one is actually a compile- time error because none of the sigs match (Int,Int) and for a call to work with 2 Int parameters, you'd need to be explicit: talk(~123,3); But I'm not sure which way perl6 actually leans. Though it seems to me that automatic type conversion by the compiler is a way to get yourself in trouble. Not that perl shouldn't let the programmer get himself in trouble, but this seems like one of those things that should require asking to turn on rather than asking to turn off. Synopsis 12 at http://dev.perl.org/perl6/doc/design/syn/S12.html says quote When you call a subroutine with a particular short name, if there are multiple visible long names, they are all considered candidates. They are sorted into an order according to how close the actual types of the arguments match up with the declared types of the parameters of each candidate. The best candidate is called, unless there's a tie, in which case the tied candidates are redispatched using any additional tiebreaker long names (see below). /quote IMHO that seems to mean that in my example the (String, Int) version would be called because it's the best candidate. And that would also mean that first Int is automatically converted to String. -- Markus Laire
Re: Mutil Method Questions
Hi All, I would like to thank everyone for their illuminating examples and prose. This has cleared up understanding for me. Thanks again, Chris On 6/23/06, Markus Laire [EMAIL PROTECTED] wrote: On 6/23/06, Jonathan Scott Duff [EMAIL PROTECTED] wrote: An alternate interpretation would be that the last one is actually a compile- time error because none of the sigs match (Int,Int) and for a call to work with 2 Int parameters, you'd need to be explicit: talk(~123,3); But I'm not sure which way perl6 actually leans. Though it seems to me that automatic type conversion by the compiler is a way to get yourself in trouble. Not that perl shouldn't let the programmer get himself in trouble, but this seems like one of those things that should require asking to turn on rather than asking to turn off. Synopsis 12 at http://dev.perl.org/perl6/doc/design/syn/S12.html says quote When you call a subroutine with a particular short name, if there are multiple visible long names, they are all considered candidates. They are sorted into an order according to how close the actual types of the arguments match up with the declared types of the parameters of each candidate. The best candidate is called, unless there's a tie, in which case the tied candidates are redispatched using any additional tiebreaker long names (see below). /quote IMHO that seems to mean that in my example the (String, Int) version would be called because it's the best candidate. And that would also mean that first Int is automatically converted to String. -- Markus Laire
Re: Mutil Method Questions
On Fri, Jun 23, 2006 at 06:55:28PM +0300, Markus Laire wrote: On 6/23/06, Jonathan Scott Duff [EMAIL PROTECTED] wrote: An alternate interpretation would be that the last one is actually a compile- time error because none of the sigs match (Int,Int) and for a call to work with 2 Int parameters, you'd need to be explicit: talk(~123,3); But I'm not sure which way perl6 actually leans. Though it seems to me that automatic type conversion by the compiler is a way to get yourself in trouble. Not that perl shouldn't let the programmer get himself in trouble, but this seems like one of those things that should require asking to turn on rather than asking to turn off. Synopsis 12 at http://dev.perl.org/perl6/doc/design/syn/S12.html says quote When you call a subroutine with a particular short name, if there are multiple visible long names, they are all considered candidates. They are sorted into an order according to how close the actual types of the arguments match up with the declared types of the parameters of each candidate. The best candidate is called, unless there's a tie, in which case the tied candidates are redispatched using any additional tiebreaker long names (see below). /quote IMHO that seems to mean that in my example the (String, Int) version would be called because it's the best candidate. And that would also mean that first Int is automatically converted to String. I don't think so. I think the best candidate prose is about choosing from types that have been specified, not autoconverting between types such that one of them will match the long name. In other words, when you have multi sub foo (Num) { ... } multi sub foo (Int) { ... } foo(1); foo(123); foo(bar); foo(Int) is the best candidate for the first one because 1 is an Int. But in the second and third calls, there is no best candidate because strings were passed. Would you expect the third call to succeed because bar can be converted into the number 0? The programmer put type information in the sig for a reason. I think that reason is that they wanted to be careful about what was allowed to be passed to the subroutine. Autoconversion seems to defeat that. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Mutil Method Questions
Steffen Schwigon schrieb: At least the many keywords seem to be necessary to map the complexity of different paradigms possible in Perl6. Multimethods are not just overloading as in C++. Second, the different keywords declare different behaviour you can choose. Just read S06, it's explained quite understandable. Hm, but wouldn't whose be equivalent? sub foo ($bar) { $bar.say; } multi sub foo ($bar) { $bar.say; } Aren't subs a subset of multi subs, meaning that every sub can be expressed as a multi sub? Is there anything a sub has in advantage of a multi sub? So might not just every sub be a multi sub? If the only difference is, that you _must not_ declare a sub twice with different argument lists, I think that this one is relatively unimportant and letting every sub be a multi sub seems to be more consistent to me in opposite to this arbitrary looking distinction. Maybe I just phenomenally misunderstood multi subs, but unless I did, I can't see why we want to have subs when we can have multi subs that can do the same and even more. -Thomas
Can foo(123) dispatch to foo(Int) (was: Mutil Method Questions)
I'm sending this also to perl6-language, in case someone there knows an answer to this. On 6/23/06, Jonathan Scott Duff [EMAIL PROTECTED] wrote: I don't think so. I think the best candidate prose is about choosing from types that have been specified, not autoconverting between types such that one of them will match the long name. In other words, when you have multi sub foo (Num) { ... } multi sub foo (Int) { ... } foo(1); foo(123); foo(bar); foo(Int) is the best candidate for the first one because 1 is an Int. But in the second and third calls, there is no best candidate because strings were passed. Would you expect the third call to succeed because bar can be converted into the number 0? I think you are right, but I don't see that mentioned anywhere in Synopses. S12 clearly says that for a particular short name (foo here) *all* visible long names (foo(Num) and foo(Int) here) are candidates and best candidate *is* called (no matter how bad it is) -- unless there's a tie. So that would seem to say that for foo(123) above foo(Int) would be called because it's the best candidate. Which one is better for foo(bar)? foo(Int) or foo(Num)? Or is that a tie? And what about other types? e.g. if String can't ever be best candidate for Int, then does that mean that neither can Int ever be best candidate for Num, because they are different types? The programmer put type information in the sig for a reason. I think that reason is that they wanted to be careful about what was allowed to be passed to the subroutine. Autoconversion seems to defeat that. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED] -- Markus Laire
Re: Can foo(123) dispatch to foo(Int) (was: Mutil Method Questions)
On Fri, Jun 23, 2006 at 09:11:44PM +0300, Markus Laire wrote: And what about other types? e.g. if String can't ever be best candidate for Int, then does that mean that neither can Int ever be best candidate for Num, because they are different types? Well, I think Num and Int *aren't* different types because as far as duck typing goes, Num does Int. I wouldn't expect that String does Int though (at least not without some help :). The way I see it, the types specified in the signature are like constraints. When you say sub foo (Num) { ... } the signature says that only an item that can perform the Num role may fit in this slot. When perl tries to match Capture to Signature, it checks the type of each argument in the Capture against the does list for each parameter in the Signature. If the argument type appears in the does list of the Signature, then it's a match and all is well. Otherwise it's an error. Since Num does Int, a call such as Cfoo(10); succeeds. At least that's my vague interpretation of this aspect of perl6 at this moment. :-) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Mutil Method Questions
Hi All, At the risk of sounding a bit thick, I have a couple of questions about Perl6's multi keyword and mutilmethod in general. This seems like overloaded functions from C++ so why do we need a key word to declare them rather than using something like C++'s name mangling? Is there something that I am just missing here? From the wikipedia article (http://en.wikipedia.org/wiki/Multimethods), it seems that this is a way to write generic (or lambda (I think, please correct me if I am wrong)) functions. If that is the case, can we now write generic/overloaded functions in Perl6 without OO or have I conflated OO with overloading incorrectly? Thanks, Chris