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