Which Result?
Quote from dandl on November 17, 2021, 1:24 pmA "float" is not a thing in "my system".
OK, well, one could construct something from the set of numbers that the IEEE spec supports and add in the flags etc and call that a float.. and such a type could be made available to those who "know what they are doing", but in general, for "business users" it would not be a thing - apart, maybe, from when importing data from external systems.
If I did have such a set of values.
2
would never ever denote one. I would use some unique denotation for the thing that is a float that is constructed from the value2
andfalse
for theIEEE
flags and whatever else is needed to fully capture the exposed information content of float values.2e0
might even be the chosen denotation of such a thing.
Arguably there is really only one kind of number: a string of digits (by convention in base 10 but not necessarily so) containing a single decimal point. But the problem is the operators. But for business users it's hard to escape the need for integers (counting), decimal (exact) and real (floating point) because of the different set of operators each supports.
A programming language may or may not distinguish literals representing the number "2." in each type.
A "float" is not a thing in "my system".
OK, well, one could construct something from the set of numbers that the IEEE spec supports and add in the flags etc and call that a float.. and such a type could be made available to those who "know what they are doing", but in general, for "business users" it would not be a thing - apart, maybe, from when importing data from external systems.
If I did have such a set of values.
2
would never ever denote one. I would use some unique denotation for the thing that is a float that is constructed from the value2
andfalse
for theIEEE
flags and whatever else is needed to fully capture the exposed information content of float values.2e0
might even be the chosen denotation of such a thing.
Arguably there is really only one kind of number: a string of digits (by convention in base 10 but not necessarily so) containing a single decimal point. But the problem is the operators. But for business users it's hard to escape the need for integers (counting), decimal (exact) and real (floating point) because of the different set of operators each supports.
A programming language may or may not distinguish literals representing the number "2." in each type.
Quote from Paul Vernon on November 17, 2021, 5:44 pmQuote from dandl on November 17, 2021, 1:24 pmfor business users it's hard to escape the need for integers (counting), decimal (exact) and real (floating point)
How do you exactly represent the number
3⁴¹³⁴⁷⁄₆₂₂₆₅
by your decimal ("exact") type? Or, for that matter¹⁄₃
?How do you exactly represent the number
𝜋
in your "real" (floating point) type?
Quote from dandl on November 17, 2021, 1:24 pm
for business users it's hard to escape the need for integers (counting), decimal (exact) and real (floating point)
How do you exactly represent the number 3⁴¹³⁴⁷⁄₆₂₂₆₅
by your decimal ("exact") type? Or, for that matter ¹⁄₃
?
How do you exactly represent the number 𝜋
in your "real" (floating point) type?
Quote from Paul Vernon on November 17, 2021, 5:54 pmQuote from dandl on November 17, 2021, 1:13 pmNo operator can take an input value of different types.
Not even
=
? Oh. I see, if you have N types, you have N*N equals operators all of the same name but different input types. Well, if you like such conceptual complexity fine. I prefer to think that I have just one=
operator that is defined for all values regardless of "type".
Quote from dandl on November 17, 2021, 1:13 pm
No operator can take an input value of different types.
Not even =
? Oh. I see, if you have N types, you have N*N equals operators all of the same name but different input types. Well, if you like such conceptual complexity fine. I prefer to think that I have just one =
operator that is defined for all values regardless of "type".
Quote from Paul Vernon on November 17, 2021, 7:22 pmQuote from dandl on November 17, 2021, 6:22 amQuote from Paul Vernon on November 16, 2021, 10:48 pm
2 + 3.54
evaluates to5²⁷⁄₅₀
and I will explain why that is the only reasonable result.By following this line of reasoning you are relying on choosing a particular type for those values. Given other types and operators values such as 5.54, 23.54 and 5.539999999 are equally possible.
Well, anything is possible.
"aardvark"
is a possible result, but the only reasonable result is the one that follows from the definition of plus. Ask a mathematician (or my Mum), I am sure they will say that2 + 3.54
does not equal5.539999999
. If the nines went on for infinity, then (as I understand) that would be another way of writing5.54
but without such a notation, what you suggested as the answer is not reasonable. If your operator does not follow the definition of plus (https://en.wikipedia.org/wiki/Addition), calling it plus is (again) not reasonable.The fact that there are very many unreasonable programming languages already out there is not my point. I'm interested in what should happen, not what does in various arbitrary (or not so arbitrary) existing systems. (Well, I'm am interested to know if there are any reasonable programming languages (in the above sense) out there that I might not be aware of)
I mean, have you ever had to explain to a normal person why almost all programming languages think that
0.1 + 0.2
does not equal0.3
. I can even right now click Inspect, Console and type in0.1 + 0.2 === 0.3
or0.1 + 0.2 == 0.3
and in both cases I getfalse
. My computer can do billions, nay trillions of calculations in the time it takes me to test that out. What on earth is the excuse for it not following simple definitions of mathematics? Yes, I know the history... I know why this is the case, but still, surly we can do better, can't we?
Quote from dandl on November 17, 2021, 6:22 amQuote from Paul Vernon on November 16, 2021, 10:48 pm
2 + 3.54
evaluates to5²⁷⁄₅₀
and I will explain why that is the only reasonable result.By following this line of reasoning you are relying on choosing a particular type for those values. Given other types and operators values such as 5.54, 23.54 and 5.539999999 are equally possible.
Well, anything is possible. "aardvark"
is a possible result, but the only reasonable result is the one that follows from the definition of plus. Ask a mathematician (or my Mum), I am sure they will say that 2 + 3.54
does not equal 5.539999999
. If the nines went on for infinity, then (as I understand) that would be another way of writing 5.54
but without such a notation, what you suggested as the answer is not reasonable. If your operator does not follow the definition of plus (https://en.wikipedia.org/wiki/Addition), calling it plus is (again) not reasonable.
The fact that there are very many unreasonable programming languages already out there is not my point. I'm interested in what should happen, not what does in various arbitrary (or not so arbitrary) existing systems. (Well, I'm am interested to know if there are any reasonable programming languages (in the above sense) out there that I might not be aware of)
I mean, have you ever had to explain to a normal person why almost all programming languages think that 0.1 + 0.2
does not equal 0.3
. I can even right now click Inspect, Console and type in 0.1 + 0.2 === 0.3
or 0.1 + 0.2 == 0.3
and in both cases I get false
. My computer can do billions, nay trillions of calculations in the time it takes me to test that out. What on earth is the excuse for it not following simple definitions of mathematics? Yes, I know the history... I know why this is the case, but still, surly we can do better, can't we?
Quote from Dave Voorhis on November 17, 2021, 8:01 pmQuote from Paul Vernon on November 17, 2021, 5:54 pmQuote from dandl on November 17, 2021, 1:13 pmNo operator can take an input value of different types.
Not even
=
? Oh. I see, if you have N types, you have N*N equals operators all of the same name but different input types. Well, if you like such conceptual complexity fine. I prefer to think that I have just one=
operator that is defined for all values regardless of "type".If all you need is equals and you have only one type (like "string"), then binary identicality is fine. Some systems do that.
It doesn't work for less-than and greater-than, which need different implementations for different types. Ideally, all the implementations have one of two names, like
<
and>
.Of course, you could have less-than and greater-than operators with more names, like
S<
for strings and<
for numerics. Though you'll probably want a way to prevent users invoking<
on strings orS<
on numerics.
Quote from Paul Vernon on November 17, 2021, 5:54 pmQuote from dandl on November 17, 2021, 1:13 pmNo operator can take an input value of different types.
Not even
=
? Oh. I see, if you have N types, you have N*N equals operators all of the same name but different input types. Well, if you like such conceptual complexity fine. I prefer to think that I have just one=
operator that is defined for all values regardless of "type".
If all you need is equals and you have only one type (like "string"), then binary identicality is fine. Some systems do that.
It doesn't work for less-than and greater-than, which need different implementations for different types. Ideally, all the implementations have one of two names, like <
and >
.
Of course, you could have less-than and greater-than operators with more names, like S<
for strings and <
for numerics. Though you'll probably want a way to prevent users invoking <
on strings or S<
on numerics.
Quote from Dave Voorhis on November 17, 2021, 8:05 pmQuote from Paul Vernon on November 17, 2021, 7:22 pmQuote from dandl on November 17, 2021, 6:22 amQuote from Paul Vernon on November 16, 2021, 10:48 pm
2 + 3.54
evaluates to5²⁷⁄₅₀
and I will explain why that is the only reasonable result.By following this line of reasoning you are relying on choosing a particular type for those values. Given other types and operators values such as 5.54, 23.54 and 5.539999999 are equally possible.
Well, anything is possible.
"aardvark"
is a possible result, but the only reasonable result is the one that follows from the definition of plus. Ask a mathematician (or my Mum), I am sure they will say that2 + 3.54
does not equal5.539999999
. If the nines went on for infinity, then (as I understand) that would be another way of writing5.54
but without such a notation, what you suggested as the answer is not reasonable. If your operator does not follow the definition of plus (https://en.wikipedia.org/wiki/Addition), calling it plus is (again) not reasonable.The fact that there are very many unreasonable programming languages already out there is not my point. I'm interested in what should happen, not what does in various arbitrary (or not so arbitrary) existing systems. (Well, I'm am interested to know if there are any reasonable programming languages (in the above sense) out there that I might not be aware of)
I mean, have you ever had to explain to a normal person why almost all programming languages think that
0.1 + 0.2
does not equal0.3
. I can even right now click Inspect, Console and type in0.1 + 0.2 === 0.3
or0.1 + 0.2 == 0.3
and in both cases I getfalse
. My computer can do billions, nay trillions of calculations in the time it takes me to test that out. What on earth is the excuse for it not following simple definitions of mathematics? Yes, I know the history... I know why this is the case, but still, surly we can do better, can't we?There are entire university units/modules/courses -- probably whole Masters degrees, even -- on numerical computation, number representations, and all the myriad tradeoffs that go into providing machinery that can do (deceptively!) simple calculations.
People get PhDs in this.
Yes, you can do better -- for certain definitions of "better". For other definitions of "better", you've got exactly what you need.
Quote from Paul Vernon on November 17, 2021, 7:22 pmQuote from dandl on November 17, 2021, 6:22 amQuote from Paul Vernon on November 16, 2021, 10:48 pm
2 + 3.54
evaluates to5²⁷⁄₅₀
and I will explain why that is the only reasonable result.By following this line of reasoning you are relying on choosing a particular type for those values. Given other types and operators values such as 5.54, 23.54 and 5.539999999 are equally possible.
Well, anything is possible.
"aardvark"
is a possible result, but the only reasonable result is the one that follows from the definition of plus. Ask a mathematician (or my Mum), I am sure they will say that2 + 3.54
does not equal5.539999999
. If the nines went on for infinity, then (as I understand) that would be another way of writing5.54
but without such a notation, what you suggested as the answer is not reasonable. If your operator does not follow the definition of plus (https://en.wikipedia.org/wiki/Addition), calling it plus is (again) not reasonable.The fact that there are very many unreasonable programming languages already out there is not my point. I'm interested in what should happen, not what does in various arbitrary (or not so arbitrary) existing systems. (Well, I'm am interested to know if there are any reasonable programming languages (in the above sense) out there that I might not be aware of)
I mean, have you ever had to explain to a normal person why almost all programming languages think that
0.1 + 0.2
does not equal0.3
. I can even right now click Inspect, Console and type in0.1 + 0.2 === 0.3
or0.1 + 0.2 == 0.3
and in both cases I getfalse
. My computer can do billions, nay trillions of calculations in the time it takes me to test that out. What on earth is the excuse for it not following simple definitions of mathematics? Yes, I know the history... I know why this is the case, but still, surly we can do better, can't we?
There are entire university units/modules/courses -- probably whole Masters degrees, even -- on numerical computation, number representations, and all the myriad tradeoffs that go into providing machinery that can do (deceptively!) simple calculations.
People get PhDs in this.
Yes, you can do better -- for certain definitions of "better". For other definitions of "better", you've got exactly what you need.
Quote from Paul Vernon on November 17, 2021, 9:42 pmQuote from Dave Voorhis on November 17, 2021, 8:01 pmIt doesn't work for less-than and greater-than, which need different implementations for different types. Ideally, all the implementations have one of two names, like
<
and>
.Implementation matters should not leak through to the model (unless, that is, it is impossible for things not to leak through, then the leaking should be come part of the model and hence the implementation would no longer be leaking).
Of course, you could have less-than and greater-than operators with more names, like
S<
for strings and<
for numerics. Though you'll probably want a way to prevent users invoking<
on strings orS<
on numerics.I would have a total order over all values. Obviously that does require making seaming arbitrary decisions such as does
true
order before or after2
or indeed"aardvark"
. Still, I see that as no real problem (I might even be able to come up with some argument on which is the only reasonable ordering... !?)That would not disallow other operators giving other orderings for things like enumeration and culturally aware string collation. Of course, such additional operators would have different names.
Quote from Dave Voorhis on November 17, 2021, 8:01 pm
It doesn't work for less-than and greater-than, which need different implementations for different types. Ideally, all the implementations have one of two names, like
<
and>
.
Implementation matters should not leak through to the model (unless, that is, it is impossible for things not to leak through, then the leaking should be come part of the model and hence the implementation would no longer be leaking).
Of course, you could have less-than and greater-than operators with more names, like
S<
for strings and<
for numerics. Though you'll probably want a way to prevent users invoking<
on strings orS<
on numerics.
I would have a total order over all values. Obviously that does require making seaming arbitrary decisions such as does true
order before or after 2
or indeed "aardvark"
. Still, I see that as no real problem (I might even be able to come up with some argument on which is the only reasonable ordering... !?)
That would not disallow other operators giving other orderings for things like enumeration and culturally aware string collation. Of course, such additional operators would have different names.
Quote from Dave Voorhis on November 17, 2021, 9:51 pmQuote from Paul Vernon on November 17, 2021, 9:42 pmQuote from Dave Voorhis on November 17, 2021, 8:01 pmIt doesn't work for less-than and greater-than, which need different implementations for different types. Ideally, all the implementations have one of two names, like
<
and>
.Implementation matters should not leak through to the model (unless, that is, it is impossible for things not to leak through, then the leaking should be come part of the model and hence the implementation would no longer be leaking).
Of course, you could have less-than and greater-than operators with more names, like
S<
for strings and<
for numerics. Though you'll probably want a way to prevent users invoking<
on strings orS<
on numerics.I would have a total order over all values. Obviously that does require making seaming arbitrary decisions such as does
true
order before or after2
or indeed"aardvark"
. Still, I see that as no real problem (I might even be able to come up with some argument on which is the only reasonable ordering... !?)That would not disallow other operators giving other orderings for things like enumeration and culturally aware string collation. Of course, such additional operators would have different names.
For a paper exercise, you can of course simply declare that there is one > and one <, and they work as expected (for some logical definition of "expected") on every value regardless of type.
In practice, you'll need an implementations of > and < for each type. But that could be an implementation detail. You can hide the fact that > and < are overloaded from your users, of course, which is what some languages do. But as a language implementer, it's something you'll want to consider.
Then, if you overload some operators to hide complexity from your users, you might want to give them the same capability to define overloaded operators so they can have the same power to hide complexity from themselves.
Quote from Paul Vernon on November 17, 2021, 9:42 pmQuote from Dave Voorhis on November 17, 2021, 8:01 pmIt doesn't work for less-than and greater-than, which need different implementations for different types. Ideally, all the implementations have one of two names, like
<
and>
.Implementation matters should not leak through to the model (unless, that is, it is impossible for things not to leak through, then the leaking should be come part of the model and hence the implementation would no longer be leaking).
Of course, you could have less-than and greater-than operators with more names, like
S<
for strings and<
for numerics. Though you'll probably want a way to prevent users invoking<
on strings orS<
on numerics.I would have a total order over all values. Obviously that does require making seaming arbitrary decisions such as does
true
order before or after2
or indeed"aardvark"
. Still, I see that as no real problem (I might even be able to come up with some argument on which is the only reasonable ordering... !?)That would not disallow other operators giving other orderings for things like enumeration and culturally aware string collation. Of course, such additional operators would have different names.
For a paper exercise, you can of course simply declare that there is one > and one <, and they work as expected (for some logical definition of "expected") on every value regardless of type.
In practice, you'll need an implementations of > and < for each type. But that could be an implementation detail. You can hide the fact that > and < are overloaded from your users, of course, which is what some languages do. But as a language implementer, it's something you'll want to consider.
Then, if you overload some operators to hide complexity from your users, you might want to give them the same capability to define overloaded operators so they can have the same power to hide complexity from themselves.
Quote from Paul Vernon on November 17, 2021, 10:07 pmQuote from Dave Voorhis on November 17, 2021, 8:05 pmThere are entire university units/modules/courses -- probably whole Masters degrees, even -- on numerical computation, number representations, and all the myriad tradeoffs that go into providing machinery that can do (deceptively!) simple calculations.
People get PhDs in this.
Sure. Still, I see no real problem here. Trade offs just need to be explicit. For example
PSQRT π
would return√π
(or some other canonical representation of that particular Real value). If a user wants to see that value to a certain precision, then they would need to use another operator over the result sayto10DecimalPlaces
orresolveUsingXYZmethod
or whatever. I don't have time to get a PhD, and I'm surly being naive but can't see any model problem here. Just (ha) represent your Reals symbolically until the user wants to actually see a useful approximation. Rationals, for their part would just keep getting bigger and bigger until some "cost" system suggests to the user they might want to round them (at points) to make things faster/cheaper/tractable.
Quote from Dave Voorhis on November 17, 2021, 8:05 pm
There are entire university units/modules/courses -- probably whole Masters degrees, even -- on numerical computation, number representations, and all the myriad tradeoffs that go into providing machinery that can do (deceptively!) simple calculations.
People get PhDs in this.
Sure. Still, I see no real problem here. Trade offs just need to be explicit. For example PSQRT π
would return √π
(or some other canonical representation of that particular Real value). If a user wants to see that value to a certain precision, then they would need to use another operator over the result say to10DecimalPlaces
or resolveUsingXYZmethod
or whatever. I don't have time to get a PhD, and I'm surly being naive but can't see any model problem here. Just (ha) represent your Reals symbolically until the user wants to actually see a useful approximation. Rationals, for their part would just keep getting bigger and bigger until some "cost" system suggests to the user they might want to round them (at points) to make things faster/cheaper/tractable.
Quote from Dave Voorhis on November 17, 2021, 10:15 pmQuote from Paul Vernon on November 17, 2021, 10:07 pmQuote from Dave Voorhis on November 17, 2021, 8:05 pmThere are entire university units/modules/courses -- probably whole Masters degrees, even -- on numerical computation, number representations, and all the myriad tradeoffs that go into providing machinery that can do (deceptively!) simple calculations.
People get PhDs in this.
Sure. Still, I see no real problem here. Trade offs just need to be explicit. For example
PSQRT π
would return√π
(or some other canonical representation of that particular Real value). If a user wants to see that value to a certain precision, then they would need to use another operator over the result sayto10DecimalPlaces
orresolveUsingXYZmethod
or whatever. [...]Sounds like a computer algebra system. See https://en.wikipedia.org/wiki/Computer_algebra_system
Quote from Paul Vernon on November 17, 2021, 10:07 pmQuote from Dave Voorhis on November 17, 2021, 8:05 pmThere are entire university units/modules/courses -- probably whole Masters degrees, even -- on numerical computation, number representations, and all the myriad tradeoffs that go into providing machinery that can do (deceptively!) simple calculations.
People get PhDs in this.
Sure. Still, I see no real problem here. Trade offs just need to be explicit. For example
PSQRT π
would return√π
(or some other canonical representation of that particular Real value). If a user wants to see that value to a certain precision, then they would need to use another operator over the result sayto10DecimalPlaces
orresolveUsingXYZmethod
or whatever. [...]
Sounds like a computer algebra system. See https://en.wikipedia.org/wiki/Computer_algebra_system