
Ask HN: Which programming language has the best `number' implementation? - igravious
Might sound like a vague question but I&#x27;m thinking here in terms of a complete type hierarchy that&#x27;s faithful to mathematics, going from Natural numbers to Integers to Rationals to Reals to Complex numbers (and others?). That caters for native primitive machine number types be they floating or fixed point or whole numbers, signed or unsigned.<p>That knows that <i>i</i> is the square root of -1, that knows that √2 is irrational but <i>π</i> and <i>e</i> are transcendental. And so on. Also looking for a language that has a complete efficient implementation of surreal numbers (prompted by Conway&#x27;s recent passing), or at least allows you to plug one in seamlessly&#x2F;transparently if you so desired.
======
s1t5
Julia has the type hierarchy that you're describing and it's very easily
extendable.

~~~
elcritch
Not my area, but it oooks like there’s a surreal numbers package:

[https://github.com/mroughan/SurrealNumbers.jl](https://github.com/mroughan/SurrealNumbers.jl)

And a nice paper:
[https://arxiv.org/pdf/1810.10373](https://arxiv.org/pdf/1810.10373)

~~~
igravious
Spotted that package, and paper – but I don't know Julia so I haven't dug into
it yet. Must get in touch with the author. I've made a Ruby implementation and
the naive recursive addition/subtraction has pathological code paths.

~~~
elcritch
Yah, Julia follows the lisp-y tradition of defining numerical in the language.
All the built-in types are defined in Julia. Check out
[https://github.com/JuliaLang/julia/blob/381693d3dfc9b7072707...](https://github.com/JuliaLang/julia/blob/381693d3dfc9b7072707f6d544f82f6637fc5e7c/base/docs/basedocs.jl#L1458-L1462)

Still for interactive things it can be a bit slow still. I’d recommend using
repl/notebooks. Good luck!

------
jolmg
Personally, I like Haskell's treatment of numbers. I wrote a comment about it
here:

[https://news.ycombinator.com/item?id=18565234](https://news.ycombinator.com/item?id=18565234)

Don't really know much about surreal numbers, but I found the following
library that defines Fractional and Num instances for it, so that should
enable Haskell to work with surreal numbers as if they were native to the
language:

[https://github.com/Lacaranian/surreal](https://github.com/Lacaranian/surreal)

There's also this module on transcendental numbers:

[https://hackage.haskell.org/package/numeric-
prelude-0.4.2/do...](https://hackage.haskell.org/package/numeric-
prelude-0.4.2/docs/Algebra-Transcendental.html)

auxym might be right, though, that you might be better served with a language
that is specialized more in mathematics, rather than a general purpose
language.

~~~
igravious
Thank you, I'll look into this but I find Haskell very hard for my C-family
lineage head to wrap its brain around.

------
qppo
It sounds like you're asking for symbolic math utilities, which exist in a
number of languages.

Like for example I've tried to play this game building a toy language from
first principles but you run into problems rather quickly. A computer can't
represent reals (or even all rationals you care about) with a finite number of
bits. You can't guarantee that all integers are representable by all rationals
and all rationals by reals and so on.

And if you want to throw out formalism and accept the consequences, every
language has a way to do it to varying degrees of success. Matlab,
Mathematica, Julia, Python, R, basically anything that might be used by a
working mathematician probably has the facilities and libraries to help.

~~~
igravious
Aha, you're thinking like me.

That's why I thought I might incorporate surreal numbers into a toy language
early on in the compute chain (before even a "normal"/"traditional" numeric
implementation) but I've already run into the problem that the naive recursive
plus op implementation is pathologically slow in regular cases so I had to
hack the surreal integer case to make it faster.

I don't want the entirety of symbolic math, I just want a sufficiently decent
implementation of a useful part of it! The surreal numbers interest me because
they are said to be able to represent infinitesimals and infinities …

“A computer can't represent reals (or even all rationals you care about) with
a finite number of bits.”

This is where my thinking is on this. Because surreal numbers only give you
the dyadic rationals exactly it forces you to think about what it means to
represent not just exotic numbers like _i_ , _√2_ , _π_ , and _e_ but also
non-exotic rationals like the vulgar fraction _⅓_. My thinking is that the
algorithm(s) that produce ever greater precision for non-exact representations
are finite and recursive which means that the more precise you want something
you specify how long you want that algorithm to pump out ever more precise
values or you specify a number of bits constraint. Not fixed point, not
floating point, flexi-point? If you have _π_ to 100 binary places as a dyadic
fraction that's a precision above and beyond what anyone would ever need in
practice. I'm thinking that when manipulating symbols that the _algorithm_ is
manipulated, not the numeric representation!

------
bjourne
I think Factor has the best number implementation. It has builtin support for
bignums and rationals. Eg:

    
    
        IN: scratchpad 2 63 ^ 1 + 2  63 ^ / 2 63 ^ * 2 63 ^ 1 + =
        t
    

The corresponding expression would incorrectly evaluate to false in most
languages:

    
    
        >>> n = 63
        >>> (2**n + 1) / 2**n * 2**n == 2**n + 1
        False
    

Factor also has syntactic support for complex numbers but not for irrational
ones.

~~~
igravious
Thanks you sir, and would you know about surreal numbers?

~~~
bjourne
I don't know anything about them. But since all the binary operators (+, -, *,
/, =, <, >, etc) are overloadable they could be implemented in Factor.

------
afiori
If you want something like surreal numbers (or anything that might use ordinal
induction) you might be better off with a proof assistant.

Lean is being developed specifically for being applicable to math researcher.

~~~
igravious
Proof assistants are too esoteric for me. Coq, Idris, Agda, Lean, way above my
pay-grade. Fair play to people that understand them but I can't. It's tough to
admit such a thing on a forum like this but there you go. The closest I think
I'll need to go along that route is to graft microkanren into a toy language
as part of its type system.

------
igravious
Missed all these great replies :( Took a while for them to filter through so I
thought my question had sunk like a stone into the murky depths of HN. I'll
reply individually now and hope people notice.

------
RobLach
Julia in the long term

~~~
igravious
A second recommendation for Julia. What's the deal with it?

~~~
ChrisRackauckas
Julia allows for "fast" definitions and and multiple dispatch makes it easy to
incorporate into existing code. By "fast" I mean if you make it an immutable
struct, it'll inline the bytes into arrays and stuff like that, so it'll be as
though it was hardcoded bytes at the end of the day. This is crucial because
Julia's floating point numbers are defined in Julia and had to be fast enough
to match C, so now when you define a weird number type you get the same
machinery for free. But then multiple dispatch is really the kicker here,
since if you ask, what is machine learning with surreal numbers like? Well, in
Julia, if you give the Flux ML library surreal numbers, it'll recompile
everything so it uses surreal numbers and it'll do it fast, so there you go:
take the surreal number library, take Flux, slap them together and now you
have a pretty well-optimized implementation of surreal number machine learning
(and then of course you can optimize it more, since it'll not be able to use
CuDNN with surreal numbers so then you write etc. etc. in the language).
(Note: SurrealNumbers.jl won't get some of the optimizations by its design, so
that's an opening for some work)

~~~
igravious
Cool. Does it do tail recursion elimination? My Ruby implementation is so slow
because all the naive surreal number ops are recursive.

------
auxym
Mathematica?

~~~
eigenspace
Mathematica isn’t really well adapted to dealing with non-commutative number
systems like quaternions or Clifford algebras.

~~~
afiori
that might be a bit out of scope, especially since Mathematica handles
matrices and tensors nicely

~~~
eigenspace
> that might be a bit out of scope Out of scope of what? The OP specific asks
> about number systems beyond complex.

~~~
afiori
wops, missed that, I actually reread the question to see what you were
referring to; guess the quarantine is not doing wonders for my sleep
schedule...

------
rurban
Common Lisp, Julia, perl 6.

~~~
igravious
I'm never going to use Raku as long as they have that logo. I'm joking.

(I'm not joking.)

~~~
lizmat
It would seem that Larry's reasoning for Camelia is working:

"I also take it as a given that we want to discourage misogyny in our
community. You of the masculine persuasion should consider it an opportunity
to show off your sensitive side."

from:
[https://github.com/perl6/mu/blob/master/misc/camelia.txt](https://github.com/perl6/mu/blob/master/misc/camelia.txt)

~~~
igravious
Unfair. Equating the feminine with sensitivity is a subtle form of bigotry in
its own right.

I object to the logo because it looks like it's drawn by a five-year-old, it's
garish and ugly, it's on the homepage of the docs _twice_ and one is _very
large_ , and why a butterfly exactly? Ruby has a ruby, Python a snake, Raku a
butterfly, Wikipedia says Raku is a type of Japanese pottery. For some reason
it reminds me of the artwork in Dora the Explorer I used to watch with my kid
(which I'm _okay_ with in that context I feel I have to stress).

Take a look at:

[https://www.ruby-lang.org/en/](https://www.ruby-lang.org/en/) and
[https://ruby-doc.org/](https://ruby-doc.org/)

[https://julialang.org/](https://julialang.org/) and
[https://docs.julialang.org/en/v1/](https://docs.julialang.org/en/v1/)

[https://www.r-project.org/about.html](https://www.r-project.org/about.html)
and [https://www.r-project.org/other-
docs.html](https://www.r-project.org/other-docs.html)

[https://www.python.org/](https://www.python.org/) and
[https://docs.python.org/3/](https://docs.python.org/3/)

Versus:

[https://docs.raku.org/](https://docs.raku.org/)

Even Scratch, which is aimed at kids learning programming, is more subdued and
less childish:

[https://scratch.mit.edu/](https://scratch.mit.edu/)

~~~
lizmat
> I object to the logo because it looks like it's drawn by a five-year-old

And why should that affect your decision to use or not use Raku? Isn't that
ageism in its purest form? :-)

------
sloaken
Oldie but a goodie: FORTRAN It has evolved a lot over the years.

~~~
igravious
Left field suggestion, I'll take a peek.

------
jjgreen
Have a look at Pari/GP

~~~
igravious
Hmm, an interesting suggestion.

