6 ms·
> Python is never the best language to do it in, but is almost always the second-best language to do it in. I've been writing python from the last century and
by gopalv 1y ago
> Python is never the best language to do it in, but is almost always the second-best language to do it in.
I've been writing python from the last century and this year is the first time I'm writing production quality python code, everything up to this point has been first cut prototypes or utility scripts.
The real reason why it has stuck to me while others came and went is because of the REPL-first attitude.
A question like
>>> 0.2 + 0.1 > 0.3
True
is much harder to demonstrate in other languages.
The REPL isn't just for the code you typed out, it does allow you to import and run your lib functions locally to verify a question you have.
It is not without its craziness with decorators, fancy inheritance[1] or operator precedence[2], but you don't have to use it if you don't want to.
[1] - __subclasshook__ is crazy, right?
[2] - you can abuse __ror__ like this https://notmysock.org/blog/hacks/pypes https://notmysock.org/blog/hacks/pypes
- librasteve 1y agolol, here it is in the https://raku.org https://raku.org repl… Welcome to Rakudo™ v2025.06.1. Implementing the Raku® Programming Language v6.d. Built on MoarVM version 2025.06. To exit type 'exit' or '^D' [0] > 0.1 + 0.2 > 0.3 False
- mbrameld 1y agoI might be wrong, but I was under the impression that result is platform-dependent? https://docs.python.org/3/tutorial/floatingpoint.html#floating-point-arithmetic-issues-and-limitations https://docs.python.org/3/tutorial/floatingpoint.html#floati...
- eesmith 1y agoRaku represents 0.1, 0.2, and 0.3 internally as rational numbers. https://docs.raku.org/type/Rat https://docs.raku.org/type/Rat. 1/10 + 1/5 == 3/10 Note that "On overflow of the denominator during an arithmetic operation a Num (floating-point number) is returned instead." A Num is an IEEE 754 float64 ("On most platforms" says https://docs.raku.org/type/Num https://docs.raku.org/type/Num) Python always uses IEEE 754 float64, also on most platforms. (I don't know of any Python implementation was does otherwise.) If you want rationals you need the fractions module. >>> from fractions import Fraction as F >>> F("0.1") + F("0.2") == F("0.3") True >>> 0.1 + 0.2 == 0.3 False This corresponds to Raku's FatRat, https://docs.raku.org/type/FatRat https://docs.raku.org/type/FatRat. ("unlike Rat, FatRat arithmetics do not fall back Num at some point, there is a risk that repeated arithmetic operations generate pathologically large numerators and denominators")
- librasteve 1y agogood explanation that said, decimals (eg 0.1) are in fact fractions, and the subtlety that 0.1 decimal cannot be precisely represented by a binary floating point number in the FPU is ignored by most languages where the core math is either integer or P754 bringing Rational numbers in as a first class citizen is a nice touch for mathematicians, scientists and so on another way to look at it for Raku is that Int → integers (ℤ) Rat → rationals (ℚ) Num → reals (ℝ)
- eesmith 1y ago"In fact" is a big strong, no? "0.1" is what the language specification says it is, and I disagree with the view that it's ignored by most languages when it's often clearly and explicitly stated. That most people don't know IEEE 754 floats, and do things like store currency as floats, is a different matter. (For that matter, currency should be stored as decimal, because account rules can be very particular about how rounding is carried out.) Similarly, 3 * 4 + 5 may 'in fact' be 17 .. sometimes. But it's 27 with right-to-left precedence ... and 19683 in APL where * means power (3 to the power of 9). While 3 + 4 * 5 may be 35 or 23 (or 1027 in APL). FWIW, FatRat is ℚ, not Rat. Rat switches to Num if the denominator is too high, as I quoted. Bringing it back to Python, ABC (which influenced Python's development) used a ratio/fraction/FatRat natively, which handled the 0.1 + 0.2 == 0.3 issue, but ran into the 'pathologically large numerators and denominators' problem even for beginning students. I see Rat as a way to get the best of both worlds, but I'm certain it has its own odd edge cases, like I suspect x + 1/13 - 1/13 might not be the original value if x + 1/13 caused a Rat to Num conversion.
- librasteve 1y agowhen I was a kid in junior school, I was taught that 0.1 means 1/10 something like the . is a division sign, digits to the right are the numerator and the denominator is the position of the digit to the power of 10 true, in fact the syntax of Python consumes the literal '0.1' as a double [float64] ... so ok maybe I was a bit strong that my fact trumps the Python fact (but it still feels wrong to say that 0.1 + 0.2 > 0.3) --- I welcome your correction on FatRat ... btw I have just upgraded https://raku.land/zef:librasteve/Physics::Unit https://raku.land/zef:librasteve/Physics::Unit to FatRat. FatRat is a very useful string to the bow and imo cool that it's a core numeric type. See also https://raku.land/zef:librasteve/FatRatStr https://raku.land/zef:librasteve/FatRatStr as my path to sidestep P754 literals. --- We are on the same page that the Rat compromise (degrade to P754) is optimal. --- As you probably know, but I repeat here for others, Raku has the notion of https://docs.raku.org/language/numerics#Numeric_infectiousness https://docs.raku.org/language/numerics#Numeric_infectiousne... which means that `x + 1/3' will return a Rat if x is an Int or a Num if x is a Num. All "table" operators - sin , cos, log and so on are assumed to return irrationals (Num).
- Jtsummers 1y agoRaku uses a rational type by default for those which will give an exact value. If you use Python's Fraction type it would be equivalent to your Raku. The equivalent in Raku to the Python above would be: 1e-1 + 2e-1 > 3e-1 Which will evaluate to True.
- librasteve 1y agowell, yes - but the funny thing is that the example chosen to illustrate the convenience of a REPL is - errr - factually wrong a scientist knows that 0.1 + 0.2 is not greater than 0.3, only a computer geek would think that this is OK
- emil-lp 1y agoYou completely miss the point twice over. The REPL example intends to show what the program does, not whether or not something is intuitive for you. Second, using your same argumentation, >>> 010 + 006 == 14 True Is also wrong. It's based on a misunderstanding of what representations of numbers in programming languages are. In Python (and almost all other languages), 0.1 means the IEEE float closest to the decimal number 0.1, and arithmetic operations are performed according to the IEEE standard.
- librasteve 1y agoI am not “missing the point”, I am disagreeing with you. (Hopefully in an agreeable way) I am making the point that using a decimal literal (eg 0.1) representation for a IEEE double is a bad choice and that using it as a representation for a Rat (aka Fraction) is a better choice. I 100% accept your point that in Python 0.1+0.2>0.3 is true which is why I prefer Raku’s number system.
- reddit_clone 1y agoThis is the third Raku reference I came across since morning. Happy to see Raku getting some press.
- tialaramex 1y agoGiven how slow Python is, isn't it embarrassing that 0.2 + 0.1 > 0.3 ? I have some test Rust code where I add up about a hundred million 32-bit floating point numbers in the naive way, and it takes maybe a hundred milliseconds, and then I do the same but accumulating in a realistic::Real because hey how much slower is this type than a floating point number, well that's closer to twenty seconds. But if I ask Python to do this, Python takes about twenty seconds anyway, and yet it's using floating point arithmetic so it gets the sum wrong, whereas realistic::Real doesn't because it's storing the exact values.
- shagie 1y agohttps://0.30000000000000004.com/#rust https://0.30000000000000004.com/#rust
- tialaramex 1y agoEr, yes, I'm aware why this happened, my point is that this happens in the hardware floating point, but Python is as slow as the non-accelerated big rationals in my realistic::Real (it's actually markedly slower than the more appropriate realistic::Rational but that's not what my existing benchmarks cared about)
- rbanffy 1y ago> this happens in the hardware floating point Not really. It's a limitation of the IEEE floating point format used in most programming languages. Some numbers that look nice in base 10 don't have an exact representation in base 2.
- shagie 1y agoRational numbers where the denominator is a multiple of the prime factors of the base have an exact fractional representation in that base. 1/3 doesn't have an exact representation in base 10 or base 2. 1/5th does have an exact representation in base 10 (0.2), but doesn't in base 2. 1/4th has an exact representation in base 10 (0.25) and in base 2 (0.01)
- shagie 1y agoshagie@MacM1 ~ % docker run -it openjdk:latest jshell Unable to find image 'openjdk:latest' locally latest: Pulling from library/openjdk ... Status: Downloaded newer image for openjdk:latest Oct 01, 2025 6:23:46 PM java.util.prefs.FileSystemPreferences$1 run INFO: Created user preferences directory. | Welcome to JShell -- Version 18.0.2.1 | For an introduction type: /help intro jshell> 0.1 + 0.2 > 0.3 $1 ==> true jshell> This has been around since JDK 9. https://docs.oracle.com/en/java/javase/17/jshell/introduction-jshell.html https://docs.oracle.com/en/java/javase/17/jshell/introductio... That said, changing how you think about programming... even with jshell I still think Java in classes and methods (and trying to pull in larger frameworks is not as trivial as java.lang packages). However, I think Groovy (and a good bit of Scala) in a script writing style. jshell itself is likely more useful for teaching than for development - especially once you've got a sufficiently complex project and the ide integration becomes more valuable than the immediate feedback. Still, something to play with and one of the lesser known features of Java.
- worik 1y ago>>> 0.2 + 0.1 > 0.3 True That is false. What is it that is "...is much harder to demonstrate in other languages? I am missing something
- deleted 1y ago[deleted]
- Jtsummers 1y ago> That is false. What's false about it? That is the result if you're using IEEE floating point arithmetic.
- tialaramex 1y agoIt's the result if your programming language thinks 0.2 + 0.1 means you want specifically the 64-bit IEEE floating point binary arithmetic. But, where did we say that's what we want? As we've seen it's not the default in many languages and it isn't mandatory in Python, it's a choice, and the usual argument for that choice would be "it's fast" except, Python is slow, so what gives ?
- deleted 1y ago[deleted]
- deleted 1y ago[deleted]
- Jtsummers 1y agoYou aren't answering my question. I asked worik why they're claiming that something that happens is false. It's insane to claim that reality isn't reality. Run that in a Python REPL and that is the result you get.
- leephillips 1y agoInteresting observation about Python providing the worst of all possible worlds: unintuitive arithmetic without any of its speed advantages. But in answer to “where did we say that's what we want?” I would say, as soon as we wrote the expression, because we read a book about how the language works before we tried to use it. Αfter, for example reading a book¹ about Julia, we know that 0.1 + 0.2 will give us something slightly larger than 0.3, and we also know that we can type 1//10 + 2//10 to get 3//10. [1] https://lee-phillips.org/amazonJuliaBookRanks/ https://lee-phillips.org/amazonJuliaBookRanks/
- lloda 1y agoJust about anything that has a repl has a better repl than Python.
- hirvi74 1y ago>>> 0.2 + 0.1 > 0.3 Swift will also return true unless you specify the type. Though, I suppose that is the key difference -- proper typing.