Synopsis 02: Range objects

2009-08-24 Thread Michael Zedeler

Hi Perl 6 people.

I've been looking closely at the definition of the Range class in S02 
and the current Rakudo implementation, and I have some comments...


It seems that there are two intended uses for this class:

Range   A pair of Ordered endpoints

Lets call the above the interval definition.
The |..| operator now constructs a |Range| object rather than merely 
functioning as an operator. Both sides are in item context. 
Semantically, the |Range| acts like a list of its values to the extent 
possible, but does so lazily, unlike Perl 5's eager range operator.

And this one the list definition.


It seems fair enough to demand that a class supports both the concept of 
being able to tell whether some value is between two endpoints (even 
supporting open ranges) as well as being a lazy list in disguise, but 
this concept only works on countable domains.


The most common example is 1 .. 100, which represents both an object 
that can tell whether some other Integer is between 1 and 100 
(inclusive) as well as the list of numbers from 1 to 100.


But there are problems if you try extending it to other data types that 
model over-countable things, such as real numbers.


The Range 1.0001 .. 2.15 makes sense as an interval definition, but 
there can hardly be a useful list definition without defining a step 
size, at least, making it possible to use step sizes less than one.


This issue also surfaces when working with strings. As far as I can see, 
Rakudo has some other comparison operation, which means that Ranges 
using String endpoints are not dwimmy in the sense I'd expect:


say @(a .. ax).perl; # expands to a .. z, aa .. ax
say @(aa .. b).perl; # expands to the empty list

As far as I can see, the ordering is like so:

sub { $^a.chars cmp $^b.chars || $^a cmp $^b }

The code below shows that Rakudo does not currently use lexicographical 
comparison, which may be surprising.


say 'aaa' cmp 'aa';
say 'aaa' cmp 'ba';
say 'aaa' ~~ 'aa' .. 'ba';

The output is:
1
-1
0

The last 0 should be 1 if using normal lexicographical ordering, just 
like cmp does.


It is necessary to consider the data types that we want to use as 
interval endpoints and carry out some sort of analysis of their domains. 
The basic requirements are:


For the interval definition: there must be an obvious ordering relation, 
so we can do $a cmp $b on any $a and $b of the given data type.


For the list definition: for any value $a of the given datatype, it must 
be possible to come up with some $b, where no $c exists so $a  $c  $b.


Now for a short analysis of the different data types used as end points:

Integers - both interval and list definitions are ok.

Str - using lexicographical comparison permits only the interval 
definition. Using the different comparison operator above permits both, 
but results in counter-intuitive interval definition.


Num - using numerical comparison permits only the interval definition. 
It should be easy to come up with a way to specify step sizes to support 
list definition.


Complex - neither definitions are possible.

I am unsure about how this can be solved, apart from extracting the 
interval definition to a super class to Range (we could call it an 
Interval). The backside is that the class returned by the .. operator 
depends on the operands:


Int .. Int - Range
Str .. Str - Interval
Complex .. Complex - undef, exception or some other bad thing.
DataTypeA .. DataTypeB - undef, exception or some other bad thing.

The most elegant solution would be if the data types themselves 
indicated their capabilities. So if the given class has a cmp method 
working on the same data type, the .. can construct an Interval. If the 
given class has a next method (my name for a method returning the next 
value), the .. can even construct a Range. If you want to construct an 
Interval using non-countable things, you should then be able to provide 
your own next replacement. Maybe like so:


my $range = 1.14 .. 1.82 :by {* + 0.01};

Another option is to provide a completely different operator for 
constructing Intervals.


Darren Duncan brought this up before. See 
http://osdir.com/ml/perl6-language/2009-02/msg00422.html


Regards,

Michael Zedeler.





Re: Synopsis 02: Range objects

2009-08-25 Thread Michael Zedeler

James Cloos wrote:

Michael == Michael Zedeler mich...@zedeler.dk writes:



Michael The Range 1.0001 .. 2.15 makes sense as an interval definition, but
Michael there can hardly be a useful list definition without defining a step
Michael size, at least, making it possible to use step sizes less than one.

The obvious (default) choice for a step size would be the precision of
the more precise of the two values.  So 0.0001 in your example above.
  
Well... maybe. How do you specify the intended precision, then? If I 
want the values from 1 to 2 with step size 0.01, I guess that writing


1.00 .. 2.00

won't be sufficient. Trying to work out the step size by looking at the 
precision of things that are double or floats doesn't really sound so 
feasible, since there are a lot of holes in the actual representation, 
so 1.0001 may become 1.0, yielding very different results.


It could be really nice to come up with something dwimmy, but I can't 
really se any really good candidates, when it comes to floating point 
numbers and strings.

If they were specified in hex float syntax, such as 0x1.01P0 .. 0x3.123P0,
then the (default) step should be 0x0.001P0 (which is the same as saying
1.00390625 .. 3.071044921875 with a step size of 0.000244140625).
  
Fair enough, but again - I guess they are translated straight to some 
internal representation where the information in this notation would be 
lost. Just like it would be in decimal notation.

Michael Complex .. Complex - undef, exception or some other bad thing.

Complex .. Complex should have a defined meaning in p6.

A definition which is easy to compute would be the set of points
contained by the square which has opposite corners at the two
specified points.
  
But is that useful? Complex numbers are mostly for mathematics, so I 
guess we have to look in that domain for a good use case. In that domain 
there is no natural ordering of complex numbers, and without some 
ordering, you may be able to decide what should be in the list to 
return, but not which order to use.


I believe that anything we put into Perl 6 should have obvious use cases 
and fall natural into place in the domain that the construct in question 
belongs to. This means we have to come up with a design (there currently 
is no specification of Complex .. Complex), some kind of use case to as 
justification and finally a validation that ensures that the design is 
consistent with other things in the language.


An example of an obvious inconsistency is ranges on strings compared to 
how cmp works.

A better definition would be the set of points contained by the
circle which has a diameter running between the two points.
  
In that case, you'd really need a step size, since circles tend bend :-) 
Also, I'd like to see an obvious and intuitive ordering.

In both cases, of course, including the points actually on the
1-manifold.

Either choice has the same meaning on the real axis as .. generates
when given real args, and is useful for interval arithmetic.
Something for which p6 is well suited.
I'll go and get my old topology book and see what I can find there, but 
I must admit that I'd prefer if Complex .. Complex was left undefined in 
the Perl 6 core, leaving it up to anyone to specify it later.


Regards,

Michael.



Re: Synopsis 02: Range objects [recap]

2009-08-26 Thread Michael Zedeler

Thanks to everyone who has posted their thoughts on Ranges.

Here are the conclusions I have drawn:

Ranges are for checking whether something is within a given interval.
RangeIterators are for iterating over elements in a Range with a given 
step size using :by.


We discussed using Series or Sequence in place of RangeIterator, but 
Series seems too general and Sequence has already been taken.


Up to this point, there are no changes to the spec afaik.


Proposed changes:

It shouldn't be possible to construct RangeIterators over Str (apart 
from single length strings) or Complex using the Range operator (..).



Next open question:

What about Ranges using different types in each endpoint?

1.5 .. 10 :by(0.5)
(Rat .. Int)

0 .. 7

Should they be coerced - and in that case to what? If we don't coerce 
them, what should be returned?


Regards,

Michael Zedeler.



Re: Synopsis 02: Range objects [recap]

2009-08-27 Thread Michael Zedeler

Jon Lang wrote:

Michael Zedeler wrote:
  

Proposed changes:

It shouldn't be possible to construct RangeIterators over Str (apart from
single length strings) or Complex using the Range operator (..).


I'd go one step further with Complex, to say that Range isn't a useful
concept at all so long as before and after are undefined.
  

Agreed. I should have written that as part of the proposal as well.

As for Str, I'm not sure that we should go so far as to say that you
_can't_ create RangeIterators over them, so much as to say that the
default step algorithm is defined only for single-character strings,
and fails if you give it anything else.  In particular, the programmer
should be allowed to enable Str-based RangeIterators by explicitly
supplying his own step algorithm.  That is:

'aa' .. 'zz' # Error in list context: default stepper rejects
multi-character endpoints
'aa' .. 'zz' :by(stepper) # custom stepper overrides default concerns
  

The difference between this and the triple dot-operator is that we
provide an upper bound (and are forced to use the :by-adverb). Is it
worth the while?

Next open question:

What about Ranges using different types in each endpoint?

1.5 .. 10 :by(0.5)
(Rat .. Int)

0 .. 7

Should they be coerced - and in that case to what? If we don't coerce them,
what should be returned?


This is only a half-formed thought at the moment, so please bear with
me: maybe Ranges should extend the triptych that exists with
comparison operators.  That is, you have before and after, lt
and gt, and  and ; you also have cmp, leg, and =.
Perhaps .. should be treated as the numeric operator, and equivalent
Str and generic operators should be supplied separately.  I'd be
inclined to spell the generic Range operator - the one corresponding
to before/after/cmp - as to.  I'm not sure how the Str-based
one ought to be spelled.

With .., there should be automatic coercion of both endpoints to
numbers, just as there is with  and .  With to, there should
be no coercion at all, just like before after, and cmp.

And just like .. should nummify, the to operator should stringify?

Sounds nice.

Regards,

Michael.




Re: Synopsis 02: Range objects

2009-08-27 Thread Michael Zedeler

Karl Brodowsky wrote:

Michael Zedeler schrieb:
Well... maybe. How do you specify the intended precision, then? If I 
want the values from 1 to 2 with step size 0.01, I guess that writing


1.00 .. 2.00

won't be sufficient. Trying to work out the step size by looking at 
the precision of things that are double or floats doesn't really 
sound so feasible, since there are a lot of holes in the actual 
representation, so 1.0001 may become 1.0, yielding very different 
results.
That is a general problem of floats.  We tend to write them in decimal 
notation, but internally they use a representation which is binary.  
And it is absolutely not obvious what the precision of 1.0001 might be.
There could be a data type like LongDecimal in Ruby or BigDecimal 
in Java, that actually has a knowlegde of its precision and whose 
numbers are fractions with a power of 10 as the denominator.  But for
floats I would only see the interval as reasonably clear.  Even a step 
of 1 is coming with some problems, because an increment of 1 does not 
have any effect on floating point numbers like 1.03e300 or so.

Yes. Exactly my point. By the way, do we want to warn if someone writes

1e300 .. 1e301 :by(1)

given that the number implementation yields 1e300 + 1 == 1e300?

Regards,

Michael.






Re: generality of Range

2009-10-04 Thread Michael Zedeler

Hi Darren.

Darren Duncan wrote:
In a project of mine I'm looking to use Perl 6 Range values to 
represent continuous interval values in the most generic manner 
possible, meaning that the endpoint values could literally be of any 
type at all. [...] for a realistic example:


  my $a = ['Foo', 17] ^.. ['Foo', 23];

... I would expect $a to be a Range and to be able to get those 
arrayrefs out of  it. [...]


Bottom line, is my example line with the ['Foo',17] valid Perl 6 or 
not, and if not then what could be done about it?
The short version is that your example shouldn't be valid Perl 6, 
because  both ordering and successor functions are missing.


Look in synopsis 02 and 03 for documentation, but note that this 
particular corner of Perl 6 IMHO still is in flux.


My opinion is that for any domain (integers, real numbers, strings, 
complex numbers, two-element arrays consisting of a string and a number 
(your example) and anything else you can come up with), you have two 
requirements that must be met in order to be able to create a well 
defined Range:


  1. There must be a compare operator that can decide which of  two
 objects from the given domain is the greatest (for strings, ge and
 for numbers ). Lets call it .
  2. There must be a successor function, so that given an object from
 the given domain, say a, successor(a) returns one and only one
 value from the same domain.
  3. Given b = successor(a), there is no c so that b  c  a (using the
 same operator as above).

And finally, if there are multiple, competing variations for the same 
domain, I say that they should be left out of Perl 6.
Also, in what Synopsis is it documented what the methods are to 
extract the endpoints et al from a Range object.  Or what are they called?
Here is some meta-help: if you ever have a Perl 6 object and need to 
know its methods and attributes, use the introspection API. There is a 
description here:


http://rakudo.org/node/51

Regards,

Michael.



Re: r28597 - docs/Perl6/Spec/S32-setting-library

2009-10-04 Thread Michael Zedeler

Moritz Lenz wrote:

Jon Lang wrote:
  

How do pred and succ work when given Complex values?


By adding/substracting 1 from the real part, I'd say. Don't know if that
actually makes sense.
  

It doesn't, because succ should always give the next, smallest possible
element given some ordering relation. Neither does it make sense for
real numbers. Same thing applies to pred.

It may be necessary to move methods in the Numeric class that require
ordering and countability to somewhere else.

You do have a pugs commit bit, don't you?
If you find errors, feel free to correct them in the synopsis.

I do. If anyone doesn't object, I'd be happy to move the methods down to
a subclass (or -role) - at least in the spec (not sure what to do with
the code as of now).

Regards,

Michael.




Re: r28597 - docs/Perl6/Spec/S32-setting-library

2009-10-12 Thread Michael Zedeler

David Green wrote:

On 2009-Oct-4, at 2:07 pm, Moritz Lenz wrote:

Michael Zedeler wrote:

It doesn't, because succ should always give the next, smallest possible
element given some ordering relation.

Where's that definition from?
The dictionary.  =)  It would be confusing to have a successor 
method for something that isn't orderable and discrete.  An ordered 
continuous type like Real could have .inc and .dec; it just happens 
that in the common case of Ints, .succ and .inc mean the same thing.


Complex could have an .inc method, but I don't think there's any 
especially obvious choice (because .inc probably wants an ordered 
type).  Would it add 1? or 1+i?  Better to spell it out explicitly.

Well, Real implies ordering (at least to me ;-), I don't think we have a
class or role for countability.
A Discrete role would be useful, but is Set good enough for that? 
Sets could be acting as domains for things such as Integers, so we are 
on two different abstraction levels there (having Integer implement Set 
would probably never make much sense, but an Integer object can be part 
of a Set).


Integers, strings and other types have a succ and pred method, but you 
could say that they draw upon a set (acting as their domain) when they 
decide the successor and predecessor of any given element. In 
mathematical terms it makes sense, but I am aware that from an 
implementation perspective, it sounds somewhat odd. It does, however 
solve some of the current problems that we have with iterating on Ranges 
and various other things.


Also, the domain should define how to compare objects and could provide 
details about whether the set is finite, countable or uncountable.


Does anyone know if there has been any prior discussions of such an 
approach?


I started changing the spec, but decided against it since I have some 10 
years of design discussion to catch up on first. Links to prior 
discussions will be greatly appreciated.


Regards,

Michael.



Domains? [Re: r28597 - docs/Perl6/Spec/S32-setting-library]

2009-10-13 Thread Michael Zedeler

yary wrote:

...
  

Also, the domain should define how to compare objects and could provide
details about whether the set is finite, countable or uncountable.


...

Sounds like a role Domain that provides methods (off the top of my head)-

ordering - returns Nil if the domain is unordered, or a method
implementing cmp if it is ordered

succ, pred- returns Nil if the domain is uncountable, or method
implementing next item, prior item if countable.
  

Exactly.

count - returns Inf if it's an infinite domain, or count of objects if
finite. What if counting is an expensive operation?
In most cases, the developer will know whether the domain is infinite 
and just hardwire the result to Inf.

Then the .. operator can accept anything that does Domain where
ordering is non-Nil, and the ... operator can add the condition that
succ/pred are non-Nil.
  

Yes.

Moreover, I have realized that Domains can solve a lot of other 
problems, such as collations. In English, it makes sense to write 
something like


'a' .. 'z'

but the Danish and Swedish counterparts are

'a' .. 'z' followed by 'æ', 'ø', 'å' (Danish)

and

'a' .. 'z' followed by 'ä', 'ö', 'å' (Swedish)

since there is only one 'z' in unicode (for obvious reasons), collation 
is something separate from the charset, which can be provided in a 
domain. Also, encoding magical month names becomes easy (the double 
parens here are casting to a domain):


my $month = ((DateDomain['en_US', '%b']))'Jan';
$month++;
say $month; # Feb

...and even...

my $date = ((DateDomain['en_US', '%D']))'01/14/2001';
$date++;
say $date; # 01/15/2001

Also, this is an extension of the notion of subtypes, augmenting it with 
ordering and some other relations. Next question is whether the domain 
shouldn't also provide arithmetic.


There is a lot of plumbing to do to fully use this concept, but I 
believe it could be really useful.


Regards,

Michael.

where



Re: Suggested magic for a .. b

2010-07-16 Thread Michael Zedeler

On 2010-07-16 18:40, Aaron Sherman wrote:

Oh bother, I wrote this up last night, but forgot to send it. Here y'all go:

I've been testing .. recently, and it seems, in Rakudo, to behave like
Perl 5. That is, the magic auto-increment for a .. z works very wonkily,
given any range that isn't within some very strict definitions (identical
Unicode general category, increasing, etc.) So the following:

A .. z

produces very odd results.

I'd like to suggest that we re-define this operator on strings as follows:

[cut]

Ab .. Be

defines the ranges:

A B  andb c d e

This results in a counting sequence (with the most significant character on
the left) as follows:

Ab Ac Ad Ae Bb Bc Bd Be

Currently, Rakudo produces this:

Ab, Ac, Ad, Ae, Af, Ag, Ah, Ai, Aj, Ak, Al, Am,
An, Ao, Ap, Aq, Ar, As, At, Au, Av, Aw, Ax, Ay,
Az, Ba, Bb, Bc, Bd, Be

which I don't think is terribly useful.
   
I have been discussing the Range operator before on this list, and since 
it often becomes the topic of discussion, something must be wrong with it.


What started it all, was the intention to extend the operator, making it 
possible to evaluate it in list context. Doing so has opened pandoras 
box, because many (most? all?) solutions are inconsistent with the rule 
of least surprise.


For instance, when considering strings, writing up an expression like

'goat' ~~ 'cow' .. 'zebra'

This makes sense in most cases, because goat is lexicographically 
between cow and zebra. So we have a nice ordering of strings that even 
extends to strings of any length (note that the three words used in my 
example are 3, 4 and 5 letters). As you can see, we even have a Range 
operator in there, so everything should be fine. What breaks everything 
is that we expect the Range operator to be able to generate all values 
between the two provided endpoints. Everything goes downhill from there.


With regard to strings, lexicographical ordering is the only prevailing 
ordering we provide the developer with (apart from length which doesn't 
provide a strict ordering that is needed). So anyone using the Range 
operator would assume that when lexicographical ordering is used for 
Range membership test, it is also used for generation of its members, 
naturally leading to the infinite sequence


cow
cowa
cowaa
cowaaa
...
cowb
cowba
cowbaa

For some reason (even though Perl6 supports infinite lists) we are 
currently using a completely new construct: the domain of strings 
limited to the lenght of the longest operand. This is counter intuitive 
since


'cowbell' ~~ 'cow' .. 'zebra'

but

'cow' .. 'zebra'

does not produce 'cowbell' in list context.

Same story applies to other types that come with a natural ordering, but 
have an over countable domain. Although the solutions differ, the main 
problem is the same - they all behave counter intuitive.


5.0001 ~~ 1.1 .. 10.1

but

1.1 .. 10.1

does not (and really shouldn't!) produce 5.0001 in list context.

I'd suggest that if you want to evaluate a Range in list context, you 
may have to provide a hint to the Range generator, telling it how to 
generate subsequent values. Your suggestion that the expansion of 'Ab' 
..  'Be' should yield Ab Ac Ad Ae Bb Bc Bd Be is just an example of a 
different generator (you could call it a different implementation of ++ 
on Str types). It does look useful, but by realizing that it probably 
is, we have two candidates for how Ranges should evaluate in list context.


The same applies to Numeric types.

My suggestion is to eliminate the succ method on Rat, Complex, Real and 
Str and point people in the direction of the series operator if they 
need to generate sequences of things that are over countable.


Regards,

Michael.



Re: Suggested magic for a .. b

2010-07-27 Thread Michael Zedeler

On 2010-07-27 23:50, Aaron Sherman wrote:

PS: On a really abstract note, requiring that ($a .. $b).reverse be lazy
will put new constraints on the right hand side parameter. Previously, it
didn't have to have a value of its own, it just had to be comparable to
other values. for example:

   for $a .. $b -  $c { ... }

In that, we don't include the RHS in the output range explicitly. Instead,
we increment a $a (via .succ) until it's= $b. If $a were 1 and $b were an
object that does Int but just implements the comparison features, and has
no fixed numeric value, then it should still work (e.g. it could be random).
Now that's not possible because we need to use the RHS a the starting point
when .reverse is invoked.

This is exactly why I keep writing posts about Ranges being defunct as 
they have been specified now. If we accept the premise that Ranges are 
supposed to define a kind of linear membership specification between two 
starting points (as in math), it doesn't make sense that the LHS has an 
additional constraint (having to provide a .succ method). All we should 
require is that both endpoints supports comparison (that they share a 
common type with comparison, at least).


To provide expansion to lists, such as for $a .. $b - $c { ... }, we 
should use type coercion semantics, coercing from Range to Sequence and 
throw an error if the LHS doesn't support .succ.


Writing ($a .. $b).reverse doesn't make any sense if the result were a 
new Range, since Ranges should then only be used for inclusion tests (so 
swapping endpoints doesn't have any meaningful interpretation), but 
applying .reverse could result in a coercion to Sequence.


Writing for ($a .. $b).reverse - $c { ...} may then blow up because it 
turns out that $b doesn't have a .succ method when coercing to sequence 
(where the LHS must have an initial value), just like for $a .. $b - $c 
{ ... } should be able to blow up because the LHS of a Range shouldn't 
have to support .succ.


Regards,

Michael.



Re: Suggested magic for a .. b

2010-07-28 Thread Michael Zedeler

On 2010-07-28 06:54, Martin D Kealey wrote:

On Wed, 28 Jul 2010, Michael Zedeler wrote:
   

Writing for ($a .. $b).reverse -  $c { ...} may then blow up because it
turns out that $b doesn't have a .succ method when coercing to sequence
(where the LHS must have an initial value), just like
 for $a .. $b -  $c { ... }
should be able to blow up because the LHS of a Range shouldn't have to
support .succ.
 

Presumably you'd only throw that except if, as well, $b doesn't support .pred ?
   
Yes. It should be .pred. So ($a .. $b).reverse is only possible if 
$b.pred is defined and $a.gt is defined (and taking an object that has 
the type of $b.pred). If the coercion to Sequence is taking place first, 
we'll have to live with two additional constraints ($b.lt and $a.succ), 
but I guess it would be easy to overload .reverse and get rid of those.


Regards,

Michael.





Re: Suggested magic for a .. b

2010-07-28 Thread Michael Zedeler

On 2010-07-29 00:24, Dave Whipp wrote:

Aaron Sherman wrote:
On Wed, Jul 28, 2010 at 11:34 AM, Dave Whipp d...@dave.whipp.name 
wrote:


To squint at this slightly, in the context that we already have 
0...1e10 as
a sequence generator, perhaps the semantics of iterating a range 
should be

unordered -- that is,

 for 0..10 - $x { ... }

is treated as

 for (0...10).pick(*) - $x { ... }



As others have pointed out, this has some problems. You can't 
implement 0..*

that way, just for starters.


I'd say that' a point in may favor: it demonstrates the integers and 
strings have similar problems. If you pick items from an infinite set 
then every item you pick will have an infinite number of 
digits/characters.


In smart-match context, a..b includes aardvark. It follows that, 
unless you're filtering/shaping the sequence of generated items, then 
almost every element (a..b).Seq starts with an infinite number of 
as.


Consistent semantics would make a..b very not-useful when used as 
a sequence: the user needs to say how they want to avoid the 
infinities. Similarly (0..1).Seq should most likely return Real 
numbers -- and thus (0..1).pick(*) can be approximated by 
(0..1).pick(*, :replace), which is much easier to implement.
I agree that /in theory/ coercing from Range to Sequence, the new 
Sequence should produce every possible value in the Range, unless you 
specify an increment. You could argue that 0 and 1 in (0..1).Seq are 
Ints, resulting in the expansion 0, 1, but that would leave a door open 
for very nasty surprises.


In practise, producing every possible value in a Range with 
over-countable items isn't useful and just opens the door for 
inexperienced programmers to make perl run out of memory without ever 
producing a warning, so I'd suggest that the conversion should fail 
unless an increment is specified.


The general principle would be to avoid meaningless conversions, so (1 
.. *).Seq  (1 .. *).pick should also just fail, but with finite 
endpoints, it could succeed. The question here is whether we should open 
for more parallelization at the cost of simplicity. I don't know.


So either you define some arbitrary semantics (what those should be 
is, I think, the original topic of this thread) or else you punt 
(error message). An error message has the advantage that you can 
always do something useful, later.
I second that just doing something arbitrary where no actual definition 
exists is a really bad idea. To be more specific, there should be no 
.succ or .pred methods on Rat, Str, Real, Complex and anything else that 
is over-countable. Trying to implement .succ on something like Str is 
most likely dwimmy to a very narrow set of applications, but will 
confuse everyone else.


Just to illustrate my point, if we have .succ on Str, why not have it on 
Range or Seq?


Let's just play with that idea for a second - what would a reasonable 
implementation of .succ on Range be?


(1 .. 10).succ --?-- (1 .. 11)
(1 .. 10).succ --?-- (2 .. 11)
(1 .. 10).succ --?-- (1 .. 12)
(1 .. 10).succ --?-- (10^ .. *)

Even starting a discussion about which implementation of .succ for Range 
(above), Str, Rat or Real completely misses the point: there is no 
definition of this function for those domains. It is non-existent and 
trying to do something dwimmy is just confusing.


As a sidenote, ++ and .succ should be treated as two different things 
(just like -- and .pred). ++ really means add one everywhere and can 
be kept as such, where .succ means the next, smallest possible item. 
This means that we can keep ++ and -- for all numeric types.


Coercing to Sequence from Range should by default use .succ on the LHS, 
whereas Seq could just use ++ semantics as often as desired. This would 
make Ranges completely consistent and provide a clear distinction 
between the two classes.

Getting back to 10..0


Yes, I agree with Jon that this should be an empty range. I don't care 
what order you pick the elements from an empty range :).

Either empty, the same as 0 .. 10 or throw an error (I like errors :).

Regards,

Michael.



Re: Suggested magic for a .. b

2010-07-28 Thread Michael Zedeler

On 2010-07-29 01:39, Jon Lang wrote:

Aaron Sherman wrote:


In smart-match context, a..b includes aardvark.


No one has yet explained to me why that makes sense. The continued use of
ASCII examples, of course, doesn't help. Does a .. b include æther?
This is where Germans and Swedes, for example, don't agree, but they're all
using the same Latin code blocks.


This is definitely something for the Unicode crowd to look into.  But
whatever solution you come up with, please make it compatible with the
notion that aardvark..apple can be used to match any word in the
dictionary that comes between those two words.


The key issue here is whethere there is a well defined and meaningful 
ordering of the characters in question. We keep discussing the nice 
examples, but how about apple .. ส้ม?


I don't know enough about Unicode to suggest how to solve this. All I 
can say is that my example above should never return a valid Range 
object unless there is a way I can specify my own ordering and I use it.



I've never accepted that the range between two strings of identical length
should include strings of another length. That seems maximally non-intuitive
(well, I suppose you could always return the last 100 words of Hamlet as an
iterable IO object if you really wanted to confuse people), and makes string
and integer ranges far too divergent.


This is why I dislike the notion of the range operator being used to
produce lists: the question of what values you'd get by iterating from
one string value to another is _very_ different from the question of
what string values qualify as being between the two.  The more you use
infix:..  to produce lists, the more likely you are to conflate lists
with ranges.


I second the above. Ranges are all about comparing things. $x ~~ $a .. 
$b means is $x between $a and $b?. The only broadly accepted 
comparison of strings is lexicographical comparison. To illustrate the 
point: wouldn't you find it odd if 2.01 wasn't in between 1.1 and 2.1? 
Really?


Regards,

Michael.



Re: Suggested magic for a .. b

2010-07-28 Thread Michael Zedeler

On 2010-07-29 02:19, Jon Lang wrote:

Michael Zedeler wrote:
   

Jon Lang wrote:
 

This is definitely something for the Unicode crowd to look into.  But
whatever solution you come up with, please make it compatible with the
notion that aardvark..apple can be used to match any word in the
dictionary that comes between those two words.
   

The key issue here is whether there is a well defined and meaningful
ordering of the characters in question. We keep discussing the nice
examples, but how about apple .. ส้ม?
 

All I'm saying is: don't throw out the baby with the bathwater.  Come
up with an interim solution that handles the nice examples intuitively
and the ugly examples poorly (or better, if you can manage that right
out of the gate); then revise the model to improve the handling of the
ugly examples as much as you can; but while you do so, make an effort
to keep the nice examples working.
   
I am sorry if what I write is understood as an argument against ranges 
of strings. I think I know too little about Unicode to be able to do 
anything but point at some issues, I belive we'll have to deal with. The 
solution is not obvious to me.

I don't know enough about Unicode to suggest how to solve this. All I can
say is that my example above should never return a valid Range object unless
there is a way I can specify my own ordering and I use it.
 

That actually says something: it says that we may want to reconsider
the notion that all string values can be sorted.  You're suggesting
the possibility that a cmp ส้ is, by default, undefined.
   

Yes, but I am sure its due to my lack of understanding of Unicode.

Regards,

Michael.



Re: Breaking encapsulation by detaching a private-variable-accessing method from one object and calling it on another

2010-08-03 Thread Michael Zedeler

On 2010-07-31 20:23, Carl Mäsak wrote:

* Today we discovered that it's possible to break encapsulation by
detaching a method from an object of one class, and calling that
method on an object of another class. Which means that breaking the
encapsulation of a foreign class is as easy as creating a custom class
with all of the same private attributes, and with a method to print
(or otherwise reveal) them.

* It is my feeling that such encapsulation-breakage shouldn't be
allowed. Do you agree, p6l?
   
I don't really agree. The way OOP is implemented in perl 5 allows 
breaking encapsulation on many different levels, but I believe this has 
turned out to be a strength, since it allows you to use in those (very 
rare?) cases where it is needed.


When I found that all objects in perl 6 had fields, I was kind of put 
off, since it looked to Java-ish. What saves the spirit of perl is that 
people are still free to hack away (and then there are such roles as 
postcircumflex that reintroduces the very terse syntax, perl 5 is known 
for, avoiding the dot-hell of Java).


I believe we have a much larger task at hand, which is to write 
documentation that educates newcomers to use the right tools for the 
right job. I'd never recommend monkeypatching to a rookie programmer (or 
those silly .* and .+ method invocators) and I believe we owe people 
outside the perl community to explain the /intent/ behind the different 
constructs.


Regards,

Michael.



Re: Encapsulating the contents of container types

2011-08-20 Thread Michael Zedeler

On 2011-08-20 12:02, Damian Conway wrote:

Carl asked:

* What language components could be provided to put class implementors
on the right path so that their classes end up encapsulated by
default?

Doing nothing should result in the safe behaviour (i.e. full encapsulation).
You ought to have to explicitly request anything else.

One of the *big* selling points of Perl 6 is the prospect of OO done right.
Leaky encapsulation ain't that.
Sorry if I am hijacking the thread, but how does the .* and .+ fit into 
OO done right idea?


As I understand it, having a class hierarchy like so:

class A { method m { say A.m called } }
class B is A { method m { say B.m called } }
class C is A { method m { say C.m called } }
class D is B is C { method m { say D.m called } }

calling

D.new().+m();

Produces

D.m called
B.m called
C.m called
A.m called

Making it an option (and I suspect sometimes even the responsibility) of 
the caller (reading Calling sets of methods in S12) to choose how 
dispatch should be done, can hardly be said to be encapsulation (a 
subset of OO) done right?


In other words, any class using .+, .* or $something.WALK( ... ) is - in 
the best case - violating the responsibilities of its superclasses. The 
.+ and .* operators still look to me as if someone has been mixing up 
the chain of responsibility pattern with normal OO method dispatch. On 
one hand, there is no reason that .* and .+ should use the inheritance 
hierarchy as the dispatch order if we're looking for some generalized 
chain of responsibility. On the other hand, explicitly calling each 
method all the way up the inheritance hierarchy, ignoring the efforts of 
the individual methods to carry out their specialization of their super 
classes, just doesn't seem to make any sense.


Regards,

Michael.



Re: [perl #121454] Can't inline complex constraints in multisub signatures

2014-03-31 Thread Michael Zedeler.

On 2014-03-29 21:45, Damian Conway wrote:

Moritz wrote:

To spin the tale further, we need to think about what happens if
somebody writes

multi foo(1|2e0) { ... }

so now we have Int|Num. We could explore the most-derived common
ancestor (Cool), or look into role space (Real, Numeric come to mind),
or simply error out.

Or maybe we need to reconsider the whole idea that it's appropriate to
infer type from a smartmatched constraint?

[...]

In other words specifying a constraint value is a way of applying a
smartmatched acceptance test to a parameter, but the type of the
acceptance test is typically totally unrelated to the type of the
parameter.

Which is why it now seems very odd to me that we are currently inferring
parameter types from constraint values.
I couldn't agree more. This looks like a piece of odd-sized baggage left 
behind by Moose, where declaring type constraints on attributes is too 
easily mistaken as actual type declarations.


Other languages may provide simple restriction rules for parameter value 
domains in the shape of types, but in a dynamically typed language, it 
doesn't make much sense, since there may be conversion paths between the 
types involved.


I'd much more prefer a pure matching language where no assumptions about 
types are done automatically, forcing me to write explicit type 
constraints myself, if I believe they are necessary (they should rarely 
be needed, since having to deal too much with types in a dynamically 
typed language is counterproductive :-) ).


In general - Perl (5) is a great tool because it doesn't force people to 
deal too much with typing (both implicit and explicit). Lets keep it 
that way.

--
Michael Zedeler
70 25 19 99
mich...@zedeler.dk mailto:mich...@zedeler.dk

dk.linkedin.com/in/mzedeler http://dk.linkedin.com/in/mzedeler/ | 
twitter.com/mzedeler https://twitter.com/mzedeler | 
github.com/mzedeler https://github.com/mzedeler/


Re: [perl #121454] Can't inline complex constraints in multisub signatures

2014-03-31 Thread Michael Zedeler.

On 2014-03-31 14:49, Michael Zedeler. wrote:

On 2014-03-29 21:45, Damian Conway wrote:

Moritz wrote:

To spin the tale further, we need to think about what happens if
somebody writes

multi foo(1|2e0) { ... }

so now we have Int|Num. We could explore the most-derived common
ancestor (Cool), or look into role space (Real, Numeric come to mind),
or simply error out.

Or maybe we need to reconsider the whole idea that it's appropriate to
infer type from a smartmatched constraint?

[...]

In other words specifying a constraint value is a way of applying a
smartmatched acceptance test to a parameter, but the type of the
acceptance test is typically totally unrelated to the type of the
parameter.

Which is why it now seems very odd to me that we are currently inferring
parameter types from constraint values.
I couldn't agree more. This looks like a piece of odd-sized baggage 
left behind by Moose, where declaring type constraints on attributes 
is too easily mistaken as actual type declarations.
Sorry - correction: where declaring type constraints should be where 
declaring value constraints.

--
Michael Zedeler
70 25 19 99
mich...@zedeler.dk mailto:mich...@zedeler.dk

dk.linkedin.com/in/mzedeler http://dk.linkedin.com/in/mzedeler/ | 
twitter.com/mzedeler https://twitter.com/mzedeler | 
github.com/mzedeler https://github.com/mzedeler/


Re: New parrot feature: reset coros, or not? how to deal with dead coros

2014-10-15 Thread Michael Zedeler.

Hi Reini.

On 2014-10-15 16:21, Reini Urban wrote:

Current parrot behaviour for exhausted yields is dying with Cannot
resume dead coroutine.

parrot coros are designed after lua, but lua does return nil and as
2nd return value announces also cannot resume dead coroutine. most
lisp's also behave the same way.
As third version the parrot book announced coros to be auto-resetting.

This makes no sense to me at all, as coros are usually needed to fetch
elements from a lazy list, and when the list is exhausted the state
should return to the head of the list automatically? lazy cycling a la
?
No auto-reset, please. Just return nil or throw an exception. In other 
words, make it easy to understand that the coro has been exhausted. It 
should be next to trivial to reset back to the initial state. The need 
to automatically reset to initial state is unusual, so don't make it the 
default.


Written by a seasoned user of a fair amount of programming languages.
--
Michael Zedeler
70 25 19 99
mich...@zedeler.dk mailto:mich...@zedeler.dk

dk.linkedin.com/in/mzedeler http://dk.linkedin.com/in/mzedeler/ | 
twitter.com/mzedeler https://twitter.com/mzedeler | 
github.com/mzedeler https://github.com/mzedeler/


Re: Language design

2015-06-16 Thread Michael Zedeler
This is another of my points: when presented with all the features in Perl 6 - 
what is then essential?

The essential features - besides being presented up front and center to newbies 
- are also good candidates for what should go into the core.

For instance, why have Complex and Rat numbers in the core? If you're not 
working in a very specialized field (which probably *isn't* numerical 
computation), those datatypes are just esoteric constructs that you'll never 
use.

The beauty of Perl 6 is that not only can they be deferred to a module - they 
may still extend the syntax of Perl 6 once they're loaded.

In other words: Perl 6 is perfectly suited to be designed with a tiny core with 
most features in separate modules, and yet it had been provided with the most 
feature rich core (*COUGH* bloated *COUGH*) among most languages I know.

Regards,

Michael.

 Parrot Raiser wrote 

Subsets will be absolutely essential, if it is to be possible to learn
it with a reasonable amount of time and effort.

On 6/16/15, Paweł Murias pawelmur...@gmail.com wrote:
 I think Perl 6 tries to include too much rather than too little.
 It will be possible to just use a subset

 On 16 June 2015 at 10:32, Michael Zedeler mich...@zedeler.dk wrote:

 On 06/12/15 15:54, Parrot Raiser wrote:

 Has somebody been following the discussions on types?
 http://xkcd.org/1537/ :-)*

 Perl6 has something similar to example 9.

 Ranges, hyper-operators as well as the invocation operators .+ and .*
 doesn't make any sense to me. Those constructs made me stop using Perl
 and
 look elsewhere. It was a hard decision since I've used the language for
 at
 least 15 years.

 I hope Perl6 regexes will make it far beyond Perl itself and the notion
 of
 being able to introduce custom dsl parsed on equal terms as the rest of
 Perl 6 is really sweet.

 Regards,

 Michael.

 --
 Michael Zedeler
 70 25 19 99
 mich...@zedeler.dk

 dk.linkedin.com/in/mzedeler | twitter.com/mzedeler | github.com/mzedeler





Re: Language design

2015-06-16 Thread Michael Zedeler
Yes. It looks nice that Perl 6 recognizes zero in this way, but the consequence 
is that each implementation of Perl 6 has to run a gcd algorithm every now and 
then. 

I'd be very surprised if the computational complexity of any useful (even 
approximate) gcd algorithm doesn't scale with the with the size of the 
denominators, which is why I can't see that it is feasible to use for real 
numerical applications.

I'm not saying that there isn't any alternative to the way other languages 
implements floats, but Rats in particular seems to require a nondeterministic 
algorithm in order to be of practical use. 

Regards, 

Michael. 

 Aristotle Pagaltzis wrote 

* Michael Zedeler mich...@zedeler.dk [2015-06-16 18:55]:
 For instance, why have Complex and Rat numbers in the core? If you're
 not working in a very specialized field (which probably *isn't*
 numerical computation), those datatypes are just esoteric constructs
 that you'll never use.

https://www.youtube.com/watch?v=S0OGsFmPW2M


Re: Language design

2015-06-16 Thread Michael Zedeler
...and unpredictable performance is a cost you're willing to pay? 

M.

 The Sidhekin wrote 

On Tue, Jun 16, 2015 at 10:02 PM, Michael Zedeler mich...@zedeler.dk wrote:

I'm not saying that there isn't any alternative to the way other languages 
implements floats, but Rats in particular seems to require a nondeterministic 
algorithm in order to be of practical use. 

  Rats means never having to worry about inaccurate float representations.

$ perl -E '$i+=0.1 for 0..1000; say for $i, $i cmp 100.1' # oops …
100.0999
-1
$ perl6 -e 'my $i; $i+=0.1 for 0..1000; .say for $i, $i cmp 100.1'
100.1
Same
$

  Float inaccuracy is one of the things I'm really looking forward to 
forgetting. :)



Eirik



Re: Language design

2015-06-16 Thread Michael Zedeler
I really understand your point. If there was several competing OOP modules, 
things *could* get really complicated (in my opinion, it isn't the case for 
perl 5, but it is worth discussing), but it doesn't seem as if anyone has put 
any effort into defining what needs to be common and what doesn't. 

Seriously, do you believe that the hyperoperators address the problem, you're 
referring to?

Regards, 

Michael. 

 Paweł Murias wrote 

The goal is to avoid everyone using a different not fully compatible version 
of everything. Like in perl 5 with the bunch of different ways to do objects, 
signatures etc. 

Pilling good things on top of each others rather than aiming for an elegant 
design is what I consider the core idea of Perl.

Being able to add language features removes most benefits of a simple design 
(easy to create tool support).


On 16 June 2015 at 21:08, Fields, Christopher J cjfie...@illinois.edu wrote:

I like that I can start with a fairly simple subset of Perl 6 but pick up more 
as I go along, if it’s needed.


chris


On Jun 16, 2015, at 9:45 AM, Paweł Murias pawelmur...@gmail.com wrote:


I think Perl 6 tries to include too much rather than too little. 

It will be possible to just use a subset 


On 16 June 2015 at 10:32, Michael Zedeler mich...@zedeler.dk wrote:

On 06/12/15 15:54, Parrot Raiser wrote:

Has somebody been following the discussions on types? http://xkcd.org/1537/ 
:-)*

Perl6 has something similar to example 9.

Ranges, hyper-operators as well as the invocation operators .+ and .* 
doesn't make any sense to me. Those constructs made me stop using Perl and 
look elsewhere. It was a hard decision since I've used the language for at 
least 15 years.

I hope Perl6 regexes will make it far beyond Perl itself and the notion of 
being able to introduce custom dsl parsed on equal terms as the rest of Perl 6 
is really sweet.

Regards,

Michael.

-- 
Michael Zedeler
70 25 19 99
mich...@zedeler.dk

dk.linkedin.com/in/mzedeler | twitter.com/mzedeler | github.com/mzedeler






The invocation operators .* and .+

2015-06-16 Thread Michael Zedeler

Hi.

I know that Perl 6 has a lot of live and let live to it, but is it 
possible somehow to remove features as well?


The latest comment about language design by Parrot Raiser (great name!) 
had me reflect on why I don't use perl any longer, and here is one of 
the reasons:


class Person {
has $.name;
method hello {
say Hi, I'm $.name (Person);
}
}

class Employee is Person {
method hello {
say Hello. My name is $.name (Employee);
}
}

class Surfer is Person {
method hello {
say Whats up, dude? (Surfer);
}
}

class Professor is Surfer is Employee {
method hello {
say Good day to you, my name is $.name (Professor);
}
}

my $p = Professor.new(name = Alice);

$p.*hello;

Which outputs

Good day to you, my name is Alice (Professor)
Whats up, dude? (Surfer)
Hello. My name is Alice (Employee)
Hi, I'm Alice (Person)

This is working exactly as specified in the synopsis, but does Perl 6 
NEED anything like this? Just because something is possible doesn't make 
it an automatic requirement!


I know that if I don't like the construct, then I shouldn't use it, but 
this operator (and .+) is nudging people who really doesn't understand 
OOP to use the inheritance hierarchy as a function chaining mechanism 
way beyond what it is intended for. Working with a language means 
working with code that *other people* has written in that language. I 
don't want to maintain anything using this operator (or its twin, .+), 
because I haven't seen just one reasonable use case for it.


--
Michael Zedeler
70 25 19 99
mich...@zedeler.dk

dk.linkedin.com/in/mzedeler | twitter.com/mzedeler | github.com/mzedeler



Re: The invocation operators .* and .+

2015-06-16 Thread Michael Zedeler

Hi Aristotle.

On 06/16/15 12:24, Aristotle Pagaltzis wrote:

* Michael Zedeler mich...@zedeler.dk [2015-06-16 11:35]:

This is working exactly as specified in the synopsis, but does Perl
6 NEED anything like this? Just because something is possible doesn't
make it an automatic requirement!

Well someone thought they needed it in Perl 5 so they wrote NEXT which
provides EVERY:: which does exactly the same thing. C3 dispatch surely
has something similar too, natively, I’m just not aware of it.
Which is a reasonably good argument for letting others write a *module* 
for Perl 6 that provides this feature. I don't see why it should be in 
the core.

I haven't seen just one reasonable use case for it.

Anyplace you would have to say “if you override this method then make
sure to call the overridden method also” (like calling -new up the
inheritance tree). Instead of relying on every subclass writer to not
screw this up (and leave the object instance in an incoherent state),
you use something like these operators to make *sure* a certain method
is called all up the inheritance tree as necessary for your de-/init
needs.

Sorry. Doesn't make sense.

class A {
sub destroy {
...important cleanup
}
}

class B is A {
sub destroy {
...important cleanup...
nextall;
}
}

followed by

$b.destroy

What is it that make this *less* preferable over

class A {
sub destroy {
...important cleanup
}
}

class B is A {
sub destroy {
...important cleanup...
}
}

$b.+destroy.

The latter breaks encapsulation. The subclass B has the *full* 
responsibility to handle the method call. Not the caller.

Every modern Perl 5 OO system invents stuff like BUILD and DEMOLISH for
this purpose. And one of the points of Perl 6 is not to have to handroll
a reasonable OO system as your first step in writing nontrivial systems.
So putting these operators right in the language, properly designed, is
specifically called for.
Show me the precedence for constructs like this in other languages, 
please. I haven't seen any and I belive it is because they're not 
necessary.

Just because you can’t think of the use of a feature doesn’t mean there
isn’t one.

Of course. That's why I've brought up the subject for discussion here.

Or maybe you are aware of the motivation for these designs and disagree
with that desire in the first place? In that case I don’t know what to
say; obviously there are plenty of people who do see it as a necessity.
I am really not so sure, because I've tried to bring up the subject a 
couple of times, and every time I get answers from people like you: 
people who don't need the feature themselves, but refer to it as 
something someone else probably need. Please show me an example that 
makes Perl 6 vastly more useful by the addition of this feature.


Perl 6 could be great because things like this operator could be 
deferred to non-core modules, but right now they're in the core and 
nobody can really explain why. *COUGH* featurecreep *COUGH*


Regards,

Michael.

--
Michael Zedeler
70 25 19 99
mich...@zedeler.dk

dk.linkedin.com/in/mzedeler | twitter.com/mzedeler | github.com/mzedeler



Re: Language design

2015-06-16 Thread Michael Zedeler

On 06/12/15 15:54, Parrot Raiser wrote:

Has somebody been following the discussions on types? http://xkcd.org/1537/ :-)*

Perl6 has something similar to example 9.

Ranges, hyper-operators as well as the invocation operators .+ and .* 
doesn't make any sense to me. Those constructs made me stop using Perl 
and look elsewhere. It was a hard decision since I've used the language 
for at least 15 years.


I hope Perl6 regexes will make it far beyond Perl itself and the notion 
of being able to introduce custom dsl parsed on equal terms as the rest 
of Perl 6 is really sweet.


Regards,

Michael.

--
Michael Zedeler
70 25 19 99
mich...@zedeler.dk

dk.linkedin.com/in/mzedeler | twitter.com/mzedeler | github.com/mzedeler



Re: Language design

2015-07-13 Thread Michael Zedeler
 Darren Duncan wrote 

 On 2015-06-16 2:15 PM, The Sidhekin wrote:
  On Tue, Jun 16, 2015 at 10:52 PM, Michael Zedeler mich...@zedeler.dk 
  wrote:
  ...and unpredictable performance is a cost you're willing to pay?
 
     I don't write performance-critical applications, but even if I did, why 
 would
  I prefer getting the wrong answer faster?
 
 I agree with Sidhekin and similar mentalities.
 
 On the range between safety/correctness and speed, a good programming 
 language / 
 tool should always default to the most safe/correct option when the user 
 doesn't 
 specify where on the range they want, and leave it to the power users to 
 explicitly make the trade-off when they know what they're doing.
 
 In this case, people who explicitly want floats because of performance rather 
 than exact rationals do indeed count as power users.

I'd still pull out the argument that you want the least surprising behavior. Of 
course, I would prefer being able to add two rational numbers with very large 
denominators and have the underlying machinery shorten the result for me, but 
the performance hit is easy to great. Am I missing something here, or wouldn't 
most people expect addition to be a constant time operation?

Imagine a really simple operation: a script that takes a spread sheet, parses 
it and writes out the weighted average of some of the columns. Anyone would 
expect that if 40,000 rows takes 1 second to process, then 80,000 takes 2. With 
Perl 6 not do much. You'd have to switch to power user mode to get that kind 
of predictability.

 Normal people are more interested in not being surprised by the answers they 
 get 
 to what should be common-sense questions, such as when adding 10.3 to 14.2.

So far, almost every other language has behaved this way, and it has worked. I 
can see that Rats do solve a problem, but if you'd claim that it is very severe 
then I'd disagree. This is a minor nuisance that I'd only pay a small price to 
fix.

 I should also point out that finance / anything to do with money is an 
 extremely 
 common use case that cares very much about math being exact, its not just 
 esoteric science applications.

I doubt that Rats is a complete solution to the problems you have to solve when 
it come to represent monetary values. My take is you'd need very specific 
rounding algorithms when you convert to a fixed number of digits.

I believe my example with the spread sheet is much more mundane.

 This all being said, I draw the line where implementing is much more 
 complicated 
 to serve esoteric cases.  So for example while exact precision rationals 
 absolutely should be default / part of core, something like symbolic values 
 eg 
 exact representations of irrational numbers, are perfectly valid to, and 
 probably shouldn't, be part of core.  Exact rationals are not particularly 
 complicated.  Its perfectly reasonable to expect in the core that if someone 
 does math that is known to deal with irrationals in general, that loss of 
 precision then is acceptable.

Just to be sure that we are taking about the same thing:

An ideal Rat implementation should be able to always output the least possible 
denominator, right?

And if I happen to add some rational numbers that involve, say, very very large 
prime numbers (intentionally or not), it's clear that the result probably can't 
be shortened much, but the run time of the underlying algorithm may explode.

..and that is acceptable behavior?

..or did I miss something?

M.
-- 
Michael Zedeler
70 25 19 99
mich...@zedeler.dk

dk.linkedin.com/in/mzedeler |twitter.com/mzedeler | github.com/mzedeler