On Sun, Dec 31, 2006 at 03:02:08AM -0800, Darren Duncan wrote:
: At 9:34 AM +0000 12/29/06, Luke Palmer wrote:
: >When do we do integer/rational math and when do we do floating point math?
: >
: >That is, is 1 different from 1.0?  Should 10**500 be infinity or a 1
: >with 500 zeroes after it?  Should 10**10**6 run out of memory?  Should
: >"say (1/3)**500" print a bunch of digits to the screen or print 0?
: >
: >These are just examples.  Exponentials are the easiest to think about
: >limit cases with, but the whole general issue needs precise semantics.
: 
: Related to that question, I'd like to draw the list's attention to a 
: #perl6 discussion that several of us had today:
: 
: http://colabti.de/irclogger/irclogger_log/perl6?date=2006-12-31
: 
: Following from this, I propose that we have distinct-looking 
: operators (not just multis) that users can explicitly choose when 
: they want to do integer division/modulus or non-integer 
: division/modulus.
: 
: For example, we could have:
: 
:   div - integer division
:   mod - integer modulus
:   /   - number division
:   %   - number modulus
: 
: Or alternately:
: 
:   idiv - integer division
:   imod - integer modulus
:   ndiv - number division
:   nmod - number modulus
: 
: And in that case, "/" and "%" would be aliases for an alphanumeric 
: pair that can be changed using a lexical pragma; they would default 
: to ndiv/nmod.
: 
: In that case, the explicit "/" and "%" use would be subject to change 
: behaviour depending on the influence of a pragma, while explicit 
: idiv/imod/ndiv/nmod use would stay the same no matter what pragma is 
: in effect.

Something's been bugging me about this for days, and I think I finally
have a feeling about what it is.  It's a reinventing-the-wheel kind
of feeling: most of these operators already *have* names, if you
count long names that include the return type.

    infix:</>:($x, $y --> Int)
    infix:</>:(Int $x, Int $y --> Int)
    infix:</>:($x, $y --> Num)
    infix:</>:(Num $x, Num $y --> Num)
    infix:</>:($x, $y --> Rat)
    infix:</>:(Rat $x, Rat $y --> Rat)

assuming suitable implementation of general forms.  But see below.

: Note that the i/n variants would cast all their arguments as Int/Num 
: before performing the operation as appropriate; they do *not* simply 
: do non-integer work and then cast the result.

We don't have a way to name those two options for implementation:

    multi infix:</> ($x, $y --> Int) { Int($x) / Int($y) }
    multi infix:</> ($x, $y --> Int) { Int($x / $y) }

So perhaps we need a way to name those two differently.  And maybe there's
a third:

    multi infix:</> ($x, $y --> Int) { Int(CALLER::infix:</>($x,$y)) }

or maybe one uses a macro to get those semantics, since that latter
is an infinite recursion if CALLER::infix:</> already happens to pick
the Int returning variant.  Oops...

: Change spelling to taste (eg, they could be spelled 
: Int::Div/Int::Mod/Num::Div/Num::Mod instead), but I hope you get the 
: point of what I was saying.

Assuming everything can be named with some kind of long name, the question
is whether our current aliasing facilities are sufficient for remapping
generic / and % operators, and creating convenience operators like idiv.
I would guess so.  The main question then is whether Standard Perl should
provide such convenience operators, or pragmatic support for them.

The other issue is how this relates to return-type multiple dispatch,
and whether we support type inferencing, or require a pragma to say
that / assumes Rat for its return type.  Or another wacky approach
would be to defer the choice until we know the actual use context
and then do the division.  Run-time type inferencing, as it were...

I don't think that approach would necessarily imply full laziness--one
could presumably evaluate the arguments up to the point of making the
choice of which variant to call.  Of course, if those arguments are
waiting with bated breath to find out *their* type context, then we
really are looking at type inferencing at run time, which transitively
implies a great deal of implied laziness (and associated potential
grief if done poorly).  There's much to be said for a pragma that
forces the issue: "Just gimme my Rats, darn it!"

But I'm also still wondering whether a simpler approach is to declare
that Num is a role that can encapsulate objects of class Int, Num,
Rat, or Dec as necessary.  There also a lot to be said for simple...

Larry

Reply via email to