Hacker News new | past | comments | ask | show | jobs | submit login

The specific type of conversion is one I don't see as a big issue. The programmer deliberately decided to use an imprecise data type for the calculation.

But more importantly, I'm saying that the problematic rounding can occur even if your tower does not have both bigint and float. It can happen even if every layer can completely represent every value of the layer above it. Do you have any complaints that are unique to a tower that has both bigint and float, and don't apply to towers that only have float?

To elaborate on that, an implicit cast directly from a single bigint to a single float won't happen with the rules in the wikipedia article. You'd have to do something like bigint+float, which can have horrible rounding errors, but those horrible rounding errors are also present in float+float.

And you can even have these problems without a tower. So I don't see how the bigint and float scenario is an argument against towers.




From a distance, I kind of like Scheme, so I went and re-read the R5RS section on the topic. To me, the numeric tower (generalized) says:

   N < Z < Q < R < C < H

   ℕ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ ⊂ ℍ
That's a nice statement about idealized sets of numeric values. So `integer?` implies `rational?` implies `real?` implies `complex?` implies `number?` in Scheme predicates and type conversions.

But no programming language can have "Reals" (they aren't computable), so floats are a common/useful approximation. And in actuality `bigint?` doesn't imply `floating?`, and `floating?` doesn't imply `bigint?`. Neither is a strict subset of the other, and because of this you can easily find examples where implicit conversion does something "questionable". You've made it about rounding errors, but I'm trying to criticize something about pretending they are subtypes/subsets. Claiming it's a tower and hand waving about exact/inexact doesn't make it a tower, and so I think implicit conversion for these is a poor choice.

You can have little subset relations for implicit conversions:

    float32?   implies  float64?
    float64?   implies  complex64?
    float32?   implies  complex32?
    complex32? implies  complex64?

    fixint?    implies  bigint?
    fixint?    implies  rational?
    bigint?    implies  rational?
Since this is supposedly in a discussion about JavaScript, maybe even:

    fixint?    implies  float64?
All of those relate true subsets for the collection of values they can represent, but it's not much of a tower. It's more a collection of DAGs.


> But it's not much of a tower, and it's more of a collection DAGs.

> I'm trying to criticize something about pretending they are subtypes/subsets. Claiming it's a tower and hand waving about exact/inexact doesn't make it a tower

I thought we established right away that it's not a single tower. The description in the wikipedia page is two towers with links between them. (Or at least it's two if you don't waste effort on things like having both float64 and complex32.)

But I don't see any hand waving. The relationships and conversions are very clear. That's why I interpreted your complaint as being more about the specific operation. So with your correction, I need you to explain where you see hand-waving.

If you just don't like the name "Tower" for an implementation that has both bignums and floats then okay I agree I guess?


> I thought we established right away that it's not a single tower.

Where did we say that? The first picture on the Wikipedia page shows the tower as a linear stack of items from set theory. The Scheme predicates are named similarly. This is the appealing myth.

> The description in the wikipedia page is two towers with links between them.

Not on the page I'm seeing. Are you reading the English page? At the bottom, I see a tree of abstract types (sets).

This shows that you can traverse (Integer to Rational to Real) and (Float to Real) to find the common abstract type Real. But there isn't actually a Real type you can do operations with. You've got concrete BigInt and Float64, and even if Real is implemented as a C-style tagged-union of the two types, you still need to pick one or the other for doing operations like addition. Then the Scheme standard says stuff like, "try to be exact when you can, but inexact is ok sometimes". So all the set theory justification is out the window, and it's really just an ad hoc rule.

It's just not as elegant as it seems, and it gives an unsound justification to making implicit conversions.

> If you just don't like the name "Tower" then okay I agree I guess?

Please don't do that. I've tried to clarify details in response to your questions, but if you're just going to dismiss it with some snarky crap like that then you can go fuck yourself.

Reply if you want, but I'm guessing we're done here.


> Where did we say that? The first picture on the Wikipedia page shows the tower as a linear stack of items from set theory. The Scheme predicates are named similarly. This is the appealing myth.

In the section where the wikipedia page talks about exact and inexact, the specific thing you were calling out, it says "Another common variation is to support both exact and inexact versions of the tower or parts of it; R7RS Scheme recommends but does not strictly require this of implementations. In this case, similar semantics are used to determine the permissibility of implicit coercion: inexactness is a contagious property of numbers,[6] and any numerical operation involving both exact and inexact values must yield inexact return values of at least the same precision as the most precise inexact number appearing in the expression, unless the precision is practically infinite (e.g. containing a detectable repetend), or unless it can be proven that the precision of the result of the operation is independent of the inexactness of any of its operands (for example, a series of multiplications where at least one multiplicand is 0).".

I want to especially highlight the phrase "exact and inexact versions of the tower or parts of it" Which I then reacted to by saying "The article describes a reasonable-sounding way to extend the tower with a second dimension of precision." Once you have two dimensions it's no longer a single tower. I thought that was the common ground that we were talking on, that if you use that method it's not a true tower anymore.

> Please don't do that. I've tried to clarify details in response to your questions, but if you're just going to dismiss it with some snarky crap like that then you can go fuck yourself.

That wasn't snark. I am really trying to understand your argument, because it looks like we've been talking about different things the entire time.

I had thought we established from the very start that the description on the wiki page wasn't actually a single tower. If you are still trying to convince me it's a more complicated graph, then I agree with you, and I don't understand how we got so far without that being clear. Sorry for sounding reductionist about it.

So please, honest question for clarification, do you object to the graph of number types described by that paragraph, do you object to using the word "tower" to talk about it, or do you object to both? Please don't get mad at me for asking, or think I'm trying to dismiss you.

And if someone builds a pure tower that goes int32, double, complex, quaternion, do you think that's inherently self-defeating because it can't live up to the promises of a tower? It doesn't have the issue of floats versus bignums; it's strict subsets all the way down.


I'm sorry for misreading your comment about the term "tower". :-)

> do you object to using the word "tower" to talk about it

No, I don't really care about the terminology, except when it helps to communicate.

> do you object to the graph of number types described by that paragraph

I think the problem boils down to using a flawed analogy to arrive at a conclusion and then pretending the conclusion is sound and elegant. There are really two things going on:

First, we've got a tower, or tree, or DAG of "abstract" types. These are mathematical constructs or Platonic ideals. So you can build a tower that says "All Integers are Rationals" and "All Rationals are Reals". And it's supported by Set Theory! So you conclude that you can use an Integer anywhere that a Rational or Real is allowed. Then, knowing that we're going to apply this to a programming language, you add "All Floats are Reals". Fine, we've got abstract Floats, and it looks lovely.

Second we've got actual "concrete" data types. These are things like Float64, Int32, or BigInt. Importantly, you can't have an implementation of Real anything. In general, Real numbers can't be processed on a Turing machine. You can have a tagged union of Computable things, but that's not really the same as "Real" in bold quotes.

Ok, so the mistake comes when you try to combine those first and second sets of things. We say concrete BigInt is like the abstract Integers, and concrete Float64 is like the abstract Floats. So far so good. Then we look at the abstract tower, we decide that Integers and Floats need to become Real, so we say BigInt and Float64 need to use Reals to get a common type. But there is no common type. We said the concrete types are analogous to the abstract types and made an unsound conclusion.

Finally, we write the compiler, and reality hits us. So we go back to the standard and add some bits about "Some things really should be Exact. Conforming implementations should try to avoid Inexact when they can." It's not a separate tower - it's a bandaid for flawed logic.

Anyways, this is all a bit too philosophical. I'm not actually passionate about it, but our discussion kept going, and you kept asking, so I kept trying to explain. Most people like implicit conversions in their programming languages, and so you've got to make up some rules. I just don't like pretending the rules are not ad hoc, and it's nothing a smug lisp weenie should really be smug about.


Okay that makes sense. I do think the issue of overstating is real, given the compromises you need when actually implementing.


> And if someone builds a pure tower that goes int32, double, complex, quaternion, do you think that's inherently self-defeating because it can't live up to the promises of a tower?

Assuming the obvious implementation of complex and quaternion built on two or four doubles, it's fine. Each type represents a set that is a proper subset of the next type in the list.

Annoyingly, it'll all go to crap if you have int64 though.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: