Re: RFC 54 (v1) Operators: Polymorphic comparisons
Bart Lateur wrote: On Tue, 08 Aug 2000 23:43:26 -0400, Ken Fox wrote: (assuming min() is polymorphic): min($a, $b) eq $a Ugly, but minimal changes to the language. We could adopt a syntax similar to sort(): $lowest = min($x, $y, $z); # default: numerical (?) $first = min { $a cmp $b } ($x, $y, $z); # alphabetical That's missing the point that min() should be polymorphic and information preserving though. I think min() should attempt to downcast it's arguments until they are either the same type or information would be lost. If information would be lost, then upcast the simpler one to the other. The definition of "information loss" is slippery though. The string "10.0" has more information than 10 or even 10.0 (stored as a fixed precision float). IMHO we could come up with a practical definition that made generic algorithms possible. - Ken
Re: RFC 54 (v1) Operators: Polymorphic comparisons
At 05:12 PM 8/7/00 -0400, Chaim Frenkel wrote: "DC" == Damian Conway [EMAIL PROTECTED] writes: I currently fail to switch to 'eq' many times when I should, but the failure mode is obvious. Her the failure mode will be really strange. DC I would claim that the failure mode is not obvious: "dog"=="cat" is true Sure it is. I pass a large amount of data and _everything_ matches! Voila, I messed up the test. Test looks okay. (If I was a newbie, '==' is broken. Given my experience, I used the wrong test.) Both ways have issues. "dog"=="cat", but "10.0"ne"10". Both are arguably wrong--dogs aren't cats, but 10.0 really is 10... Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: RFC 54 (v1) Operators: Polymorphic comparisons
Dan Sugalski wrote: At 05:12 PM 8/7/00 -0400, Chaim Frenkel wrote: "DC" == Damian Conway [EMAIL PROTECTED] writes: I currently fail to switch to 'eq' many times when I should, but the failure mode is obvious. Her the failure mode will be really strange. DC I would claim that the failure mode is not obvious: "dog"=="cat" is true Sure it is. I pass a large amount of data and _everything_ matches! Voila, I messed up the test. Test looks okay. (If I was a newbie, '==' is broken. Given my experience, I used the wrong test.) Both ways have issues. "dog"=="cat", but "10.0"ne"10". Both are arguably wrong--dogs aren't cats, but 10.0 really is 10... I first thought that "==" and "eq" were cut from the same cloth as "||" and "or" that is the difference was precedence. But I guess I learned. Or did I? -- Clayton Scott
Re: RFC 54 (v1) Operators: Polymorphic comparisons
Clayton Scott wrote: I first thought that "==" and "eq" were cut from the same cloth as "||" and "or" that is the difference was precedence. Then I learned. Mr. Scott's experience is evidence for a strong argument AGAINST operator overloading. If we allow object types, and allow object types to overload, we lose the clarity we have in a language that doesn't have these things. Maintaining code with perl5 package-modules is difficult enough, but at least all the object method calls are explicitly object method calls and there aren't any object method calls masquerading as well-understood builtins! -- David Nicol 816.235.1187 [EMAIL PROTECTED] On hold for tech support since 1995
Re: RFC 54 (v1) Operators: Polymorphic comparisons
I first thought that "==" and "eq" were cut from the same cloth as "||" and "or" that is the difference was precedence. Then I learned. Mr. Scott's experience is evidence for a strong argument AGAINST operator overloading. Huh??? I draw exactly the opposite conclusion: If "==" were overloaded to automatically Do The Right Thing for numbers vs strings as operands, there would have been no confusion in the first place! If we allow object types, and allow object types to overload, we lose the clarity we have in a language that doesn't have these things. Maintaining code with perl5 package-modules is difficult enough, but at least all the object method calls are explicitly object method calls and there aren't any object method calls masquerading as well-understood builtins! So these: $vec4 = $vec1-add($vec2-unit-cross_product( $vec3-unit)-dot_product($vec1-unit); $diff = Math::BigFloat-new((Math::BigFloat-new(( Math::BigFloat-new((Math::BigFloat-new($China{gdp} -fmul($China{gdp_incr})))-fdiv(Math::BigFloat- new($China{pop}-fmul($China{pop_incr})-fsub( Math::BigFloat-new(Math::BigFloat-new($USA{gdp}- fmul($USA{gdp_incr})))-fdiv(Math::BigFloat-new( $USA{pop}-fmul($USA{pop_incr})))-fabs()); are better than these: $vec4 = $vec1 + ~$vec2 x ~$vec3 . ~$vec1; $diff = abs( ($China{gdp}*$China{gdp_incr})/($China{pop}*$China{pop_incr}) - ($USA{gdp}*$USA{gdp_incr})/($USA{pop}*$USA{pop_incr}) ); Surely not? Operator overloading can certainly be abused (hey, I'm building a career on that! ;-), but it can also significantly *improve* the maintainability of code, when used correctly. In other words: it's just like *every* other feature of Perl. Damian
Re: RFC 54 (v1) Operators: Polymorphic comparisons
Michael Fowler wrote: I would argue that you should be manipulating your data, or checking values, so that numbers and strings are sorted how you wish. The proposed isnum(), or way-to-determine-if-a-scalar-is-a-number would help. This should be an explicit check, though, because you have a very definite idea about how you want things sorted. That's not very generic programming is it? People should be able to write code and only say "this must be ordered", and let Perl figure out what ordered means. In C++ you have to write an overloaded comparison operator and then use a template function. Damian is saying Perl should make this hard thing easier. I think Glenn Linderman implied that the string comparison is Perl's generic ordering function. It isn't. Equality is perfect, but ordering isn't. If they were, the results of lt would be the same as for all numbers. "20" lt "3" # true 20 lt 3 # true -- should be false I don't think it's possible to retrofit different behavior into Perl though, mostly because it's weakly typed between strings and numbers. Perhaps the new min() and max() operators should have polymorphic behavior with the type chosen as the simplest type representation that does not lose information? eq is already generic like Glenn said. Here's a proper polymorphic = (assuming min() is polymorphic): min($a, $b) eq $a Ugly, but minimal changes to the language. What might be nicer is to complement min() and max() with ordered(). ordered() will just return true if all it's arguments are "well ordered". The same information preserving downcasting should be used in selecting an ordering function. - Ken
Re: RFC 54 (v1) Operators: Polymorphic comparisons
This seems to be adding a special case. (I.e. only if _both_ are non-numeric will it switch to a cmp operation.) I currently fail to switch to 'eq' many times when I should, but the failure mode is obvious. Her the failure mode will be really strange. (And how does one tell if the string is numeric or not? eg. "35abc" == "n37c" ) Would modifying the waya number is converted to string be more satisfactory? I generally look at the 'cmp' amily as doing a lexical ordering. While the '=' as doing a numerical ordering. So I'm not sure that your generic insertion is generic enough. One still has to decide on the ordering. Enlighten me O' prolific one. chaim "PRL" == Perl6 RFC Librarian [EMAIL PROTECTED] writes: PRL =head1 ABSTRACT PRL This RFC proposes that numeric comparison operators default to stringwise PRL comparison when both arguments are non-numeric strings. PRL =head1 DESCRIPTION PRL Currently the expression: PRL"cat" == "dog" PRL returns true. PRL It is proposed that if Ineither argument of a numeric comparison PRL operator can be converted to a number, rather than both being converted PRL to zero, the two operands should be compared using the equivalent PRL stringwise comparison operator. -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 54 (v1) Operators: Polymorphic comparisons
This RFC proposes that numeric comparison operators default to stringwise comparison when both arguments are non-numeric strings. The problem with this, is that we're removing orthogonality from the language. ROTFL. Do we want to say: $num1 == $num2 works $string1 == $string2 works $string1 eq $string2 works $num1 == non-decimal numeric literal works $num1 eq non-decimal numeric literal breaks? No, this last one still works. Damian
Re: RFC 54 (v1) Operators: Polymorphic comparisons
Damian Conway wrote: This RFC proposes that numeric comparison operators default to stringwise comparison when both arguments are non-numeric strings. The problem with this, is that we're removing orthogonality from the language. ROTFL. But it's true. The semantics of == vs eq is currently very well defined and distinct. The proposal muddies the distinctions. The thing that allows you to LOL is precisely the thing which should motivate us to not reduce Perl's already low orthogonality quotient without very compelling reasons. -- John Porter
Re: RFC 54 (v1) Operators: Polymorphic comparisons
"DC" == Damian Conway [EMAIL PROTECTED] writes: I currently fail to switch to 'eq' many times when I should, but the failure mode is obvious. Her the failure mode will be really strange. DC I would claim that the failure mode is not obvious: "dog"=="cat" is true Sure it is. I pass a large amount of data and _everything_ matches! Voila, I messed up the test. Test looks okay. (If I was a newbie, '==' is broken. Given my experience, I used the wrong test.) DC I often need a generic comparison test (typically for equality of less-than), DC and to get it one has to jump through hoops: DC sub generic_eq { DC my $failed; DC local SIG{__WARN__} = { $failed = 1 }; DC return $_[0] eq $_[1] || $_[0]==$_[1] !$failed; DC } DC I want generic equality to DWIM. I.e. are these the same (for some DC reasonable value of "same"). DC And "dog"=="cat" is not a reasonable value of "same". Agreed. But ... one of the side effects of the '==' comparison is that it coerces the two sides into being numbers. This has effects (not nice ones) on future usages of the value. (Think '' and '|'.) Are you proposing that usage of numeric comparisons _will not_ change the 'type' of the arguments? (This should be an internals issue, but in perl5 it is a user visible effect. RFC anyone?) chaim -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
RFC 54 (v1) Operators: Polymorphic comparisons
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Operators: Polymorphic comparisons =head1 VERSION Maintainer: Damian Conway [EMAIL PROTECTED] Date: 7 August 2000 Version: 1 Mailing List: [EMAIL PROTECTED] Number: 54 =head1 ABSTRACT This RFC proposes that numeric comparison operators default to stringwise comparison when both arguments are non-numeric strings. =head1 DESCRIPTION Currently the expression: "cat" == "dog" returns true. It is proposed that if Ineither argument of a numeric comparison operator can be converted to a number, rather than both being converted to zero, the two operands should be compared using the equivalent stringwise comparison operator. It is further proposed that the current warning: Argument "%s" isn't numeric be changed to: Arguments of "%s" aren't numeric - using string comparison instead =head1 RATIONALE Perl has excellent support for generic programming, because of its dynamic typing, generic data types, and interface polymorphism. Just about the only place where that DWIM genericity breaks down is in comparisons. It is difficult to construct many generic algorithms and data structures in Perl, because there is no generic way to specify an ordering on dynamically typed data. For example, one cannot simply code a generic BST insertion method: sub insert { my ($self, $key, $value) = @_; if (!defined($self-{key})) { $self-{key} = $key; return $self-{value} = $value; } my $compare = $key = $self-{key}; return $self-{value} = $value unless $compare; $self-{$compare} = $self-new() unless $self-{$compare}; return $self-{$compare}-insert($key,$value); } This will work well for numeric keys, but fail miserably on most string-based keys, because = will generally return 0 for most pairs of strings. The above code would work correctly however if = detected the string/string comparison and automagically used cmp instead. =head1 IMPLEMENTATION Dammit, Jim, I'm a doctor, not an engineer! =head1 REFERENCES Chapter 12 of "Object Oriented Perl"