From: Markus Date: 2004-10-08T02:26:41+09:00 Subject: Re: Range behavior (Re: [RCR] New [] Semantics) On Thu, 2004-10-07 at 09:55, trans. (T. Onoma) wrote: > On Thursday 07 October 2004 11:27 am, Markus wrote: > | On Thu, 2004-10-07 at 07:11, trans. (T. Onoma) wrote: > | > --only Numeric ranges can be Continuous. > | > | Not so. Time ranges, for example, can be Continuous, as could > | Colour or FuzzyTruthValue or... > > True. Although I think one could argue, that the defining characteristic is a > *capability* to functionally map to rational numbers. So in a sense they are > numeric too, even if they don't use Numeric as a base class. Is that > important? Well, there are continuous mathematical constructs that _don't_ map to the rationals (e.g. the reals), so I think it's a bad definition. I may someday want to implement something that can represent sqrt(2) exactly... > So yes, you are right. We need to consider Intervals of variant objects. But > how? By having an Interval class that uses duck typing on its sentinels? Maybe I'm missing the problem (I'm busy trying to get my roll-your-own-operators patch working and haven't been following this thread as closely as I'd like to) but why is this considered a problem? It seems to me that restricting them to a specific base class would be the harder (and less useful) of the options. > | > Consider further how succ determines successive members --a Range is an > | > indeterminate ordered set built by iteration. Oddly one defines a Range > | > with a first and last argument, but iterations are supposed to be defined > | > by a seed (first) and the number of successive iterations. > | > | Supposed by whom? You can just as easily define an iteration with > | a termination test (e.g. iterating over the lines of a File). > > Okay, sure. My point was simply that you get no promises with a termination > test. Start: first Succ: next = (2+sqr(this))*(2+sqr(step)) Test: this < last Here's a simple (albeit contrived) case with a termination test where you can promise that it terminates, even without knowing how many steps it takes. > | > And there is good > | > reason for this: there is no way to be sure that any given _last_ is a > | > member of the set! Look at this: > | > > | > class ShrinkyDink > | > def initialize(x); @x = x.to_i; end > | > def succ; @x - 1; end > | > def <=>(b); @x <=> b; end > | > end > | > > | > rng = ShrinkyDink.new(0)...ShrinkyDink.new(100) > | > > | > Not only is ShrinkyDink.new(100) not a member of the range, but nothing > | > "inbetween" the two is either! > | > | This fails because the implementation of either succ or <=> is > | aberrant; by definition x.succ > x, while that is not the case for > | ShrinkyDinks. If you start going down that path (e.g. "but what if they > | write: > > Not really. I went to an extreme purposefully to demonstrate a point. For > something more realistic try the Collatz conjecture. *laugh* First response: I'll write Collatz#succ if you write Collatz#<=>! Second response: Unless you're talking about the congruence sets (attractors), in which case I'll write <=> and you can write succ. Then if "p Collatz.new(1).succ" returns anything we can split the money. Third response: what exactly would a range (or interval) mean in that context? > Nonetheless, I take it your point is basically "it's the programmers problem" > with regards to whether there's a real end member or termination? Not exactly. But we can't prevent them from writing code that won't _ever_ terminate without severely hobbling the language (e.g. Turring) so we shouldn't make this a major consideration. Better to have the semantics clear (and well named, and well documented) so that they can avoid shooting them selves in the foot, rather than try to control their feet. For that matter (again, with the contrived examples), I might want that sort of behavior; suppose my subtype of Numeric defines a congruence operation that is _not_ monotonic; thus member? on a Range of them might need to iterate through them. -- Markus