Re: [racket-dev] Racket Questions?

2012-09-15 Thread David Van Horn

On 9/14/12 3:36 PM, Becca MacKenzie wrote:

Hello!
So a friend of mine just started learning Racket and was wondering if
there's a particular reason why the modulo function in racket only takes
in integers? He wrote his own mod function to take in other things but
he was just wondering what the reasoning is behind this.


Hi Becca,

Excellent question -- I hope you don't mind that I've forwarded it to 
the Racket developers list for a more authoritative answer (and 
potentially a change to Racket).


I don't believe there's any principled reason not to extend `modulo' to 
other kinds of numbers such as rationals and (exact) complex numbers.  I 
worry that the idea of modulo may not be well defined for inexact 
numbers, but I could be wrong (inexact numbers don't obey a lot of the 
usual mathematical properties we're used to).  I see that in 
Mathematica, the arguments of Mod can be any numeric quantities, not 
necessarily integers.  Here are some examples:


   http://reference.wolfram.com/mathematica/ref/Mod.html#6881

Recently, Racket's GCD and LCM were extended to work on non-integer 
arguments, and I believe this is a similar case where the function could 
(and should?) be extended to work for more kinds of numbers.  But I'm 
interested to hear what the dev list has to say on the matter.


David

_
 Racket Developers list:
 http://lists.racket-lang.org/dev


Re: [racket-dev] What are single flonums good for?

2012-09-15 Thread Vincent St-Amour
At Fri, 14 Sep 2012 23:45:43 -0500,
Robby Findler wrote:
 The original message in this thread suggests that there is a type
 Single-Flonum and that it is making Neil wrangle his code to be
 careful about it.

Right, TR supports `Single-Flonum's, but not `f32vector's.

Part of the complexity in Neil's code is due to types, part of it is not.

Assuming he wrote the math library in untyped Racket:

(define (foo x)
   (cond [(double-flonum? x)  (flfoo x)]
 [(single-flonum? x)  (real-single-flonum
   (flfoo (real-double-flonum x)))]
 [else  (flfoo (real-double-flonum x))]))

The code is exactly the same as before. The complexity comes from the
fact that this function, when given single-precision inputs, wants to
produce single-precision outputs, hence the special case.

If Neil wants `foo' to be as flexible as Racket's built-in operations
(which, when given single-precision inputs, produce single-precision
outputs), he needs that special case, types or not.

If he gives up on that flexibility, things become a lot simpler:

(define (foo x)
   (flfoo (real-double-flonum x)))

This version still accepts single-precision inputs, but always produces
doubles.

The types simply mirror that distinction:

(: foo (case- (Single-Flonum - Single-Flonum)
(Flonum - Flonum)
(Real - Real)))

vs

(: foo (Real - Flonum))

This kind of complexity gets worse for functions with multiple arguments,
and types make it worse. When expressing coercion rules, the
implementation can take shortcuts that the type system cannot currently
express, leading to unwieldy types.

These issues only come up when writing libraries that aim to propagate
Racket's numeric flexibility, such as the math library or TR's base
environment. Clients of either don't need to worry about any of that.

Single-precision floats are not the source of this problem (you would
run into the same issues, in both the untyped and typed worlds, with a
function that takes ints to ints and floats to floats), but they do add
one more type to worry about.

Vincent
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Racket Questions?

2012-09-15 Thread Michael Wilber
For the record, I've always just defined my own modulo when I need it
for floats:

; A modulo operator for floats!
(define (float-modulo p q)
  (- p (* q (truncate (/ p q)

It doesn't properly handle negative numbers though.

David Van Horn dvanh...@ccs.neu.edu writes:
 On 9/14/12 3:36 PM, Becca MacKenzie wrote:
 Hello!
 So a friend of mine just started learning Racket and was wondering if
 there's a particular reason why the modulo function in racket only takes
 in integers? He wrote his own mod function to take in other things but
 he was just wondering what the reasoning is behind this.

 Hi Becca,

 Excellent question -- I hope you don't mind that I've forwarded it to 
 the Racket developers list for a more authoritative answer (and 
 potentially a change to Racket).

 I don't believe there's any principled reason not to extend `modulo' to 
 other kinds of numbers such as rationals and (exact) complex numbers.  I 
 worry that the idea of modulo may not be well defined for inexact 
 numbers, but I could be wrong (inexact numbers don't obey a lot of the 
 usual mathematical properties we're used to).  I see that in 
 Mathematica, the arguments of Mod can be any numeric quantities, not 
 necessarily integers.  Here are some examples:

 http://reference.wolfram.com/mathematica/ref/Mod.html#6881

 Recently, Racket's GCD and LCM were extended to work on non-integer 
 arguments, and I believe this is a similar case where the function could 
 (and should?) be extended to work for more kinds of numbers.  But I'm 
 interested to hear what the dev list has to say on the matter.

 David

 _
   Racket Developers list:
   http://lists.racket-lang.org/dev
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] What are single flonums good for?

2012-09-15 Thread Robby Findler
Thanks for the explanation. I see how this is not a typed-specific
problem (indeed, it is probably a Good Thing that TR helps us be
careful about this distinction when it matters).

At this point, I'm still left wondering if Single-Flonums are good for
anything, but I can imagine that they are good for not breaking old
programs, so probably best to leave well enough alone.

Thanks again,
Robby

On Sat, Sep 15, 2012 at 9:31 AM, Vincent St-Amour stamo...@ccs.neu.edu wrote:
 At Fri, 14 Sep 2012 23:45:43 -0500,
 Robby Findler wrote:
 The original message in this thread suggests that there is a type
 Single-Flonum and that it is making Neil wrangle his code to be
 careful about it.

 Right, TR supports `Single-Flonum's, but not `f32vector's.

 Part of the complexity in Neil's code is due to types, part of it is not.

 Assuming he wrote the math library in untyped Racket:

 (define (foo x)
(cond [(double-flonum? x)  (flfoo x)]
  [(single-flonum? x)  (real-single-flonum
(flfoo (real-double-flonum x)))]
  [else  (flfoo (real-double-flonum x))]))

 The code is exactly the same as before. The complexity comes from the
 fact that this function, when given single-precision inputs, wants to
 produce single-precision outputs, hence the special case.

 If Neil wants `foo' to be as flexible as Racket's built-in operations
 (which, when given single-precision inputs, produce single-precision
 outputs), he needs that special case, types or not.

 If he gives up on that flexibility, things become a lot simpler:

 (define (foo x)
(flfoo (real-double-flonum x)))

 This version still accepts single-precision inputs, but always produces
 doubles.

 The types simply mirror that distinction:

 (: foo (case- (Single-Flonum - Single-Flonum)
 (Flonum - Flonum)
 (Real - Real)))

 vs

 (: foo (Real - Flonum))

 This kind of complexity gets worse for functions with multiple arguments,
 and types make it worse. When expressing coercion rules, the
 implementation can take shortcuts that the type system cannot currently
 express, leading to unwieldy types.

 These issues only come up when writing libraries that aim to propagate
 Racket's numeric flexibility, such as the math library or TR's base
 environment. Clients of either don't need to worry about any of that.

 Single-precision floats are not the source of this problem (you would
 run into the same issues, in both the untyped and typed worlds, with a
 function that takes ints to ints and floats to floats), but they do add
 one more type to worry about.

 Vincent
_
  Racket Developers list:
  http://lists.racket-lang.org/dev