Arc Forumnew | comments | leaders | submitlogin
Number - Real
5 points by jsgrahamus 4307 days ago | 15 comments
In Scheme when I want to change 3/2 to 1.5, I use something like:

   (exact->inexact (/ 3 2))
I know there is a coerce function in arc

   (coerce (/ 3 2) 'num)
but that still results in 3/2.

How would you cause it to result in 1.5?

Thanks, Steve



1 point by zck 4307 days ago | link

What did you want the type of the result to be?

If you want a string, for output, you can use `num` (http://files.arcfn.com/doc/string.html#num):

    arc> (num (/ 3 2))
    "1.5"
If you want some sort of floating-point, I suppose you could use `nearest`, which was renamed from `to-nearest` a while ago (http://files.arcfn.com/doc/math.html#to-nearest):

    arc> (nearest (/ 3 2) .1)
    1.5
That still returns a number:

    arc> (type (nearest (/ 3 2) .1))
    num
It's kind of ugly, but I don't know of any better way.

-----

1 point by jsgrahamus 4307 days ago | link

Thanks, zck.

So I can use this:

  (coerce (num (/ 3 2)) 'num) --> 1.5

-----

2 points by Pauan 4306 days ago | link

Fun fact: in Racket, you can use this:

  (+ (/ 3 2) 0.0)
The same thing works in Arc and it'll be much faster than calling `num`

-----

1 point by jsgrahamus 4306 days ago | link

Good catch, Pauan. Thanks.

-----

1 point by akkartik 4306 days ago | link

Anarki lets you escape down to scheme, so I've been doing just:

  ($.inexact->exact (/ 3 2))
Perhaps it's worth fixing this in coerce? Should exact or inexact be the default subtype for num?

-----

2 points by Pauan 4305 days ago | link

"Should exact or inexact be the default subtype for num?"

I see at least a few good solutions:

1) Use floating point everywhere. This is what JavaScript (and Nulan) do. Simpler, but it means you give up exact math on rationals.

2) Use floating point by default but support coercing to exact. This may or may not lose information, I don't know. Alternatively, support exact by default and coerce to floating point.

3) Do things the way Racket does it, but when printing the number, coerce it to floating point. This is what Arc/Nu does:

  > 3/2
  1.5
This has the benefit that math calculations are exact, but the result is printed in a more readable fashion (more readable to me anyways).

-----

1 point by akkartik 4305 days ago | link

Thanks, I ended up going with the third option, but with a twist: display prints inexact but write prints exact. So at the prompt you still see exact numbers:

  arc> (/ 3 2)
  3/2
  arc> (prn "aa: " (/ 3 2))
  aa: 1.5
https://github.com/nex3/arc/commit/a9dc15d701

-----

1 point by Pauan 4305 days ago | link

Well, the whole reason I did it in Arc/Nu was because I liked to use the REPL as a calculator, and I hated having it print rationals. So, having the REPL print rationals kinda defeats the point in my eyes, but I don't care since I don't use Anarki.

-----

2 points by akkartik 4305 days ago | link

Yeah, I don't actually want to see rationals at the prompt. It's just that lisp has this nice distinction between 'write and 'print, with the guarantee that 'read can handle anything 'write emits. I'm loath to have write+read change a value in subtle ways.

In this case, that the repl uses 'write is an unfortunate constraint. Still thinking..

-----

2 points by akkartik 4304 days ago | link

Update: I just realized my print solution sucks:

  arc> (prn (/ 3 2))
  1.5
  arc> (prn (list (/ 3 2)))
  (3/2)
Rolling it back. Let's just explicitly use real for now.

-----

3 points by jsgrahamus 4306 days ago | link

I vote for inexact.

-----

2 points by akkartik 4306 days ago | link

Hmm, I thought about it some more, and it seems worth preserving exact because you lose information in going to inexact.

The solution I ended up with was to use your name and Pauan's trick: https://github.com/nex3/arc/commit/4227a4a9b9.

Now instead of

  (coerce (/ 3 2) 'num)
You'd say:

  (real (/ 3 2))
What do you think? Easy to change if you prefer.

-----

1 point by Pauan 4305 days ago | link

Since that's being done in Anarki, I'd rather use $.exact->inexact, rather than relying upon Racket's auto-coercion. My trick is best used in Arc 3.1 which doesn't have (easy) access to Racket.

-----

2 points by akkartik 4305 days ago | link

Ok, done. For some reason I thought your trick was more permissive..

-----

2 points by jsgrahamus 4305 days ago | link

I like the (real (/ 3 2)) format. You easily get both.

-----