10 ms·
The curse of strong typing
- eternalban 4y agofair warning: "Say, bear, did we just accidentally write a book's worth of material about the Rust type system?"
- smitty1e 4y agoI admit to being Rust-curious, but the syntactic gymnastics were out there between C++ and Perl. Think I'll keep giving Python the squeeze.
- sverona 4y agoI'm sure this is good, like, really really good, but I'm struck by the feeling that it wants to baby talk me the same way Godel, Escher, Bach did. I mean, it reads like a Homestuck pesterlog.
- phibz 4y agoYeah the pacing on this one is a bit slow, especially if you already know these things.
- hackernewds 4y agoPerhaps it's written by GPT-3..
- imron 4y agoOoh, a new fasterthanli.me article > 69 minute read Heh.
- dirtbag__dad 4y ago10/10
- happytoexplain 4y agoThis takes an agonizing amount of vertical space to discuss the fundamental concept of different numeric types and how literals are mapped to them (assuming they do get to the part about literals - I didn't get that far). It's not because the author is long-winded, but because they are pushing the "cute bantering dialogue" style of writing to its logical extreme.
- jen20 4y agoThis criticism comes up every time one of Amos’ posts shows up here. If you don’t like the style that’s fine but it’s not like you have some novel criticism here.
- mpalmer 4y agoFortunately it's novel to plenty of other people here. Crisis averted!
- therein 4y agoI normally don't mind Amos' style but this one was actually a little too much. So I'd consider that novel criticism. The quantity will add into the feedback and provide context.
- quickthrower2 4y agoIt is in tldr territory. If I am going to read a book I need to have a careful think and read some reviews first to see if that is worth my time.
- zarzavat 4y agoIn general people post their criticisms here because it’s assumed, perhaps arrogantly but often justifiably, that authors read HN and will see them.
- happytoexplain 4y agoI haven't noticed, but I also don't assume anything I say is novel. However, being novel isn't necessary for adding information. If a hundred people have the same criticism vs if three people have the same criticism, those two scenarios say different things, and therefore each represent different pieces of information, so the extra 97 people in the former case are adding information on the whole despite not individually saying something novel.
- greenthrow 4y agoThis seems like an article for a beginner programming forum not Hacker News? These concepts should all be understood before I'd consider hiring you as an SE 1.
- Jtsummers 4y agoWho do you think frequents this site? Only the most experienced programmers who all happen to know Rust? I see comments several times a week here from people who self-declare themselves to be high school or college students (or aged at least), I would expect few of them know these things or are experts at them. And then there are all the non-programmers (or non-professional programmers). And for the programmers, there are all the ones who haven't looked at Rust before or tried to but hit a wall for some reason (and quite likely related to the topics discussed in this article).
- greenthrow 4y agoI think of this as a site for tech professionals. And like I said, I'd expect you to understand the concepts discussed here before I's hire you as an SE1. So like I said, it doesn't fit this site in my mind.
- BenjiWiebe 4y agoYou can be a tech professional without knowing how to program, actually.
- afdbcreid 4y agoJump to the end of the articles. I'd really hope SE 1 employees would know all of that stuff.
- xsmasher 4y agoI know how numbers work in JS but not python or Rust. It was interesting to me.
- bb010g 4y agoI enjoyed the explainer on higher-ranked trait bounds, personally, even as someone already familiar with the topic.
- civilized 4y agoSo when do we find out why Rust can't multiply pi by 2? I mean, what is the point of making float x int an unsupported operation? I understand they're different types, but that doesn't seem like a good enough reason. Isn't it obvious that the output type should be float? So why not just cast the int to a float and multiply them and output a float, like other languages do?
- HWR_14 4y agoIts not obvious at all to me the result should be a float. I think the times I'm going to accidentally multiply a float by an int outweigh the times I want to lazily multiply a float by an int. And, some percentage of that time I would want an int anyway!
- aw1621107 4y agoFor what it's worth, Rust isn't the only language that does this. OCaml also doesn't allow mixing ints and floats, and actually has entirely different operators for int and float operations [0]. I think Haskell might do something similar [1]? I don't know for sure why Rust chose this route, but I would guess it's a mix of type inference/type system considerations and a desire to avoid potential implicit loss of data. [0]: https://stackoverflow.com/questions/64244351/why-does-ocaml-have-mandatory-distinct-float-and-int-literal-syntax https://stackoverflow.com/questions/64244351/why-does-ocaml-... [1]: https://stackoverflow.com/questions/19019093/haskell-multiplying-int-and-float-within-a-function https://stackoverflow.com/questions/19019093/haskell-multipl...
- SAI_Peregrinus 4y agoRust just takes "explicit is better than implicit" further than most. No hidden type casts. Floating point operations aren't quite the same as integer operations. Float operations aren't commutative, for one. So it's nice to be suae you really intended to use a float operation on an integer by requiring an explicit cast, so you can get the order correct.
- agumonkey 4y agoAnd considering the influence of ml in rust roots it's not surprising.
- _gabe_ 4y agoI've run into another one of these articles on HN before and both times I was very confused. After about 10-15 minutes of reading I'm still wondering whether I'm reading a tutorial or a discussion about strong typing (or whatever programming concept is being discussed)? Is this article meant to be a tutorial or is it some sort of commentary I'm missing? I'm fine with either one, it just helps me get in the right mindset if that makes sense :)
- IshKebab 4y agoYeah it could do with a preword like "this is a tour of various Rust type features". The title makes it sound like it gets to some kind of point, which it doesn't. But I had to spend 10 minutes skimming it to figure that out.
- sshine 4y agoI experienced the same confusion. Looking for an opinion about Rust's type system, I am presented with a tutorial on the difference between basic number types. I even think this is a great tutorial, but I wasn't looking for a tutorial. I suppose what I've learned from this is that the type of programmer represented by the protagonist doesn't know about this, and may think it's overkill for their use of numbers. I got tired of reading the tutorial before I became smarter about how to close the gap between programmers who care about types and programmers who don't.
- zanellato19 4y agoAmos does deep dives on subjects. This is one such deep dive on Rust type system, it's limitations and why they exist.
- mjfl 4y agoIn the case of arithmetic, strong typing is kind of nice, because math is different dependent on what types you are using. 3/2 = 1 for integers, 1.5 for floats, etc... You really don't want to mix those up in mission critical sections of code.
- ebingdom 4y agoYeah seriously. I'm surprised by the other comments here. It seems like people want loosy goosey typing that magically inserts lossy casts with convoluted semantics, as if they've been brainwashed by JavaScript and C.
- kaba0 4y agoI quite like what Haskell has here. You type in number literals, but they get a type based on context. So 2*3.14 will work there.
- skybrian 4y agoGo does this too.
- smt88 4y agoThat is nice and common in high-level languages, but most math is done at runtime with some kind of input. That's when strict typing is helpful.
- dllthomas 4y ago> That's when strict typing is helpful. How does it help? I don't mean "strict typing" in general, but specifically how does making us decorate numeric literals help with "math done at runtime with some kind of input"?
- smt88 4y ago> specifically how does making us decorate numeric literals help with "math done at runtime with some kind of input" It forces you to be specific about rounding, minimum/maximum, and floating-point arithmetic. Your compiler doesn't/can't know expected extremes of a value. If it defaults to, let's say, int64, then you're potentially wasting enormous amounts of memory (depending on the size of your data). Similarly, the programmer needs to be specific about precision. If you know you're dealing with integers, then an integer type is great. If you know you need N digits of precision, you can select a numeric type that fits. The type system becomes useful if/when you start to mix these numbers together. It can warn you that you're losing precision (or adding artificial precision, by casting an integer to a double, for example). And that isn't even getting into questions of whether you want the number stored on the stack or the heap, which I believe Rust gives you more control over than most languages do.
- iandanforth 4y agoI've never wanted to use Rust less than after encountering this article.
- lisper 4y agoYep, same here. I was seriously considering diving into it, but any language that can't figure out how to multiply a float and an integer without further guidance from me is not worth the time. Life is too short for that sort of nonsense.
- ebingdom 4y agoI personally love that Rust doesn't automatically convert between different types of numbers, with different precision and rounding/overflow behaviors. If I'm multiplying numbers of different types, I want the compiler to force me to convert them to a common type. I've been bitten too many times by implicit and lossy numeric conversions in languages like C.
- lisper 4y agoBut that's just because C's automatic conversions are broken. C's automatic conversions are not the only possible design. Common Lisp (for example) has a vastly better design. But regardless, I don't see how a reasonable result of multiplying (say) 3.14 by 2 can be anything other than 6.28.
- BenFrantzDale 4y agoI got a little way in and assumed by the dumb gopher and code examples that the author was pushing Go.
- sn9 4y agoHilariously, no. https://fasterthanli.me/articles/lies-we-tell-ourselves-to-keep-using-golang https://fasterthanli.me/articles/lies-we-tell-ourselves-to-k...
- Night_Thastus 4y agoIt's a delicate balance. Swing too far one way, and you can make it easy to make very difficult to detect mistakes. Swing the other way, and you now have a system that makes it very hard to just get lost in the process of writing, instead forcing yourself constantly to remember basic low-level details when you should be focusing on the problem. I generally like C++'s approach. Most things that should work together (like doubles, floats, ints, etc) can work together. If you want to have stronger types, you can make your own classes or use enum classes. If you want, the compiler can warn you about different types, or just let it slide.
- masklinn 4y ago> Most things that should work together (like doubles, floats, ints, etc) can work together. Because integer promotion goes every which way, not just strict ext/sext it’s been a regular source of security issues, which is why most low-ish level langages have swung so hard against it.
- ArchD 4y agoFloating-point numbers, existing on finite computers, are just erroneous approximations of real numbers, so the same operation on floating-point and on ints means different things, yielding different results. Thus, allowing the programmer to magically unconsciously convert between floating-point and ints is a recipe for disaster arising from hidden/misunderstood floating-point error. The safe way is to require the programmer intend about the type to use to be clear in the code and to force the programmer to be mindful about whether or not he is using floating-point. This is just what some languages do, including Rust. In the first example, the author is essentially complaining that he has to type '2.0' instead of '2'. I don't think that's a lot of extra typing. Perhaps it is good and convenient to have automatic int-to-float conversion, but such conversion involves error if the int values are large. Conversion in the opposite direction is similarly lossy/erroneous, even if the floating-point type can represent every real number perfectly, since not every floating-point value is an int value. Even with a perfect floating-point type, supporting automatic conversion only in one direction is weird/confusing from a user-interface POV, so the normal thing to do is to just not do automatic conversion. To drive the point about floating-point error, perhaps some people complaining about lack of automatic conversion may be surprised by how the following round-trip conversion between int64 and float64 accumulates error, as demonstrated in a Python interpreter: >>> int(float(0xffffffffffffff)) - 0xffffffffffffff 1 If you drop one digit, there is no error. A language forcing you to do the conversion explicitly forces you to be mindful of the potential for floating-point error. A language that does automatic conversion promotes blissful thinking and eventually big surprise.
- move-on-by 4y agoI’ve certainly spent way too much time tracking down and fixing these automatic conversations to bat an eye at any extra verbosity required to make the intent clear.
- e_i_pi_2 4y agoMy best story of this is JS integer parsing - we were passing IDs to the frontend through C# as ints, parsed by JS on the frontend from the JSON HTTP response. We spent at least a day trying to figure out why our links weren't working and it was because our numbers were too big for JS In a browser console it drops off after 16 digits and right-pads with zeros > 11111111111111111111 > 11111111111111110000 Our solution was to pass all IDs as strings because they aren't ever going to be manipulated like a number will
- shrubble 4y agoWouldn't any person with even a passing familiarity with the Pascal-family of languages, immediately recognize the issue? I think this post is longer than the entirety of the Oberon-2 language specification, which is about 24 pages long (not including details of certain modules etc.) : https://link.springer.com/content/pdf/bbm%3A978-3-642-97479-3%2F1.pdf https://link.springer.com/content/pdf/bbm%3A978-3-642-97479-...
- invalidname 4y agoIt's our job to explain to the computer what it needs to do. Being explicit is always helpful since our minds aren't computers. I want to be 100% explicit and when I'm not I want the compiler to ask. Not assume. Writing a cast or a clarification of some sort is a small price to pay for a potentially undetectable bug.
- foxes 4y agoStrong typing is not a mistake or a curse. Use a more advanced language that supports stuff like generics, or model your problem with the appropriate type. If you need real numbers you need real numbers, not some weird mix. I don't think it is good to just let it arbitrarily switch between int and float, that can hide bugs or mistakes. Computers are much stricter about what is what. In mathematics people are on the surface less strict, a lot of maths is done up to some sort of isomorphisms/forgetful functor, but we are smart enough to fix up potential type errors. Doing maths, as a mathematician is using a much more expressive language that takes care of some details for you. For 2 \pi, \pi ( ) is a program, an infinite list, a monad, and we implement it as a lazy calculation sometimes we can extract numbers up to a certain accuracy. 2 \pi is 2 \pi or if you know more, you can write it as another sequence, or pull the 2. As for integer * float, well what is this supposed to actually mean to a computer? Integers are not subsets of the reals. Integers are not sets, the reals are not sets. There is a representation of the integers in the reals represented as a set however. There is however a way to act Z on R. It even seems like a very natural operation. However we are doing maths, using our powerful reasoning abilities. Now it is your job to explain all these differences to a computer. Pretty tricky, so how about we just make things more restrictive. If you need real(integer) * real how about you just use that.
- skorgu 4y agoThis comment section is the most absolute proof I've ever seen that absolutely nobody reads the article before commenting. Hint: it's not about integer types at all
- nhumrich 4y agoThen please enlighten us and tell us what you feel the article is about rather than a snarky "rtfm" comment. Because I started reading. I got pretty far, and it was _still_ talking about integer types. The article is very long, and I gave up, not having any idea why I should keep reading. So saying the article isnt about them "at all" is wrong. Maybe, the int type thing is an intro to some other thing? But thats a long intro. So, tl;dr, at least not all the way. Why don't you tell us the point so we have desire to actually read it.
- jrimbault 4y ago> I hope I was able to show, too, that I don't consider Rust the perfect, be-all-end-all programming language. There's still a bunch of situations where, without the requisite years of messing around, you'll be stuck. Because I'm so often the person of reference to help solve these, at work and otherwise, I just thought I'd put a little something together. [emphasis mine] As you can also see from the table of contents at the top of the article page, it goes through a great breadth of topics. And you can use that table of contents to jump to the afterword.
- Jtsummers 4y agoConveniently, there's a table of contents at the start that hints at the later topics: Different kinds of numbers Conversions and type inference Generics and enums Implementing traits Return position Dynamically-sized types Storing stuff in structs Lifetimes and ownership Slices and arrays Boxed trait objects Reading type signatures Closures Async stuff Async trait methods The Connect trait from hyper Higher-ranked trait bounds Afterword So 17 sections, 16 technical (excluding the Afterword) and only the first two focus on the int/float stuff. So to answer your question: > Maybe, the int type thing is an intro to some other thing? No, it's not an intro, it's just the first two sections.
- imaginaryNumb3r 4y ago> I'm not sure where they got that idea from. Maybe they've been reading propaganda. Maybe they fell prey to some confident asshole, and convinced themselves that Rust was the answer to their problems. That's a very strong statement and I don't see any back up on this claim. > At any rate, I now find myself in a beautiful house, with a beautiful wife, and a lot of compile errors. Sounds like a layer 8 problem to me. I already questioning everything in this blog post that comes after.
- justin_oaks 4y agoI didn't downvote you, but other people are because it seems you're misunderstanding what the author wrote. For example, the "confident asshole" link goes to the author's own site. He's referring to himself as the "confident asshole". He's being tongue-in-cheek, funny, joking. The "propaganda" is also a joke because, well, it's true that memory safety issues lead to security problems.
- imaginaryNumb3r 4y agothanks a lot, that makes much more sense now! I'm just so used to "rage culture" and uninformed complaining that I tend to overreact.
- Allamande 4y agoThis guy is weird.