5 ms·
Another example of the support for type hints turning code which should be invalid into valid code with unexpected behaviour: https://mobile.twitter.com/reuven
by pansa2 6y ago
Another example of the support for type hints turning code which should be invalid into valid code with unexpected behaviour:
https://mobile.twitter.com/reuvenmlerner/status/1290317124997648386 https://mobile.twitter.com/reuvenmlerner/status/129031712499...
- IgorPartola 6y agoI still can’t quite figure out why type hinting is such a sought after feature. Over the years I’ve worked with various programming languages and I can’t recall any instance where I wrote code that contained a type bug that I didn’t instantly catch without the aid of any specialized tooling. The only use for it I can see is type checking for user input. Say you create an API for calculating sales tax and as an input it takes a subtotal of the cart as an integer and I instead pass in a dict or a list. But at the same time, shouldn’t you be sanitizing your inputs more than just by type? Like for example against negative numbers? I suppose code highlighters and autocomplete could also use that information but then again I rarely use those. What am I missing with the obsession over type hinting?
- munchbunny 6y agoOver the years I’ve worked with various programming languages and I can’t recall any instance where I wrote code that contained a type bug that I didn’t instantly catch without the aid of any specialized tooling. Guess you're just a better programmer. I've run into many in JavaScript and Python.
- IgorPartola 6y agoI don’t think that’s it. Maybe it’s my style of debugging or some such, but while I am a competent developer I wouldn’t attribute this to some kind of brilliance or exceptional way of thinking. I’ve pair programmed enough to know that I do things the conventional way. About the only thing I can think of is that I still routinely switch to C for Arduino projects so I am cognizant of things needing to be the right type and don’t rely on automatic casting like you get in PHP and JS.
- wokwokwok 6y agoThere are lots of ways to ensure correctness; tests, types, formal methods (not caring and just having bugs), but probably the biggest eye opener for me was introducing new programmers to a python code base without type hints. How do you know what the argument “details” should be? The function documentation says “takes the query details” ... so people sit down in the repl and just screw around with the functions to try to figure out what they do, or search for examples of how they’re used. with type hints, this discovery process for other programmers was significantly quicker and on boarding was faster. I mean, sure, just write better docstrings, but type hints can’t get out of date, because it’s a type checking error. Maybe a better solution is rust style “compiled doc strings” so the documentation can’t be wrong, or rust style inline unit tests that show examples of how to use functions... but python has neither. It’s been my experience that type hints for your own code... eh. But if you’re working in a team, they’re valuable.
- IgorPartola 6y agoIt might be in the nature of what I work on. If I don’t know what arguments a method or a function takes I go and read its source. It is usually very quick and obvious to figure out if it’s a simple type: int, dict, list, float, string, etc. If it isn’t, type hints won’t save you: charge_customer(order_details: dict) That fact that it’s a dict is the least of my worries. I need to know what goes into it, for which I need to either read the docs or the code. So you try to organize it more and avoid using something like a dict of order details. Instead you create an order object that has methods like add_item(id, qty). Can you guess what those are or deduce it quickly by looking at docs or the implementation of the method? Most likely. I’m not saying that type hints won’t help. But as far as just type checking at compile time they only really work as a very obtuse tool, and at runtime they are a very feature-barren form of contracts.
- wokwokwok 6y agoSure, but I challenge you to argue they are a worthless tool. You can do it in other ways, sure... but I don’t accept that you can argue type hints have no worth. ... if they are the correct solution for every case? If they are worth the (honestly fairly trivial) effort to write and maintain? Those are fair questions. The question is, if you’re or using type hints what are you using instead? ...I how the answer isn’t “nothing”, because that just means you not using a tool because you don’t like it, not because you have a good reason.
- HotHotLava 6y agoI mean, how would you possibly know about the type bugs that you didn't catch? I once ported a medium-size (ca. 5k LoC) python library to native C++, and we discovered a ton of latent type bugs that had stayed unnoticed in the code base for almost a decade. Things can randomly work for a long time due to duck typing, and then break in unpredictable ways. Over time, this has a very noticable impact on development speed, and in a very painful way for the individual developers who need to spending your time tracing the various call paths in unrelated code and build up a mental model of the involved types every time they want to do a nontrivial change, and then deal with the fallout of unintentional bugs due to missed code paths for an unpredictable amount of time as they are discovered. So when there is a solution that can completely eliminate this class of bugs in an automated way, this sounds like a very appealing feature.
- IgorPartola 6y agoI know because monitoring tools tell me when bugs occur, because exceptions are thrown. And I know because the code doesn’t run if you pass on a dict instead of an int. Statically typed languages have type systems that are by necessity strict but in a language like Python you don’t need to worry about whether your variable is a uint8_t or a uint16_t unless you specifically care about that. And more complex bugs like passing a list with the wrong number of members is not going to be caught by the type checker.
- HotHotLava 6y agoOnce a bug starts causing exceptions, it's no longer undetected. Then it becomes part of the post-deployment "fallout".
- Too 6y agoYou still need to worry whether an user_id-argument is int, str or maybe even uuid, though.
- david422 6y ago> Things can randomly work for a long time due to duck typing It's basically like they work by accident. It's not documented what goes in or goes out, so someone throws some data into a function and if it doesn't break then consider it success. And any future person that has to make a change has to untangle that whole mess.
- jacobsenscott 6y agoI've been using ruby for many years after using C++, Java, and C# prior to that and always thought the same thing. It wasn't until I used Elm a little and started looking at Ruby Sorbet that I understood what a good type system can do for you. C#, Java, and C++ all have at best worthless, and often harmful, type systems, and that was my point of reference. But times have changed. For example I'm sure you've had runtime production errors where you tried to call a method on a null object many times. That is the kind of thing last generation type systems couldn't help you with, and new systems do.
- kortex 6y agoI have negative patience for null, None, nullptr, etc sort of errors after working only briefly with rust's options and results. It's the one thing that I think really holds back go from being phenomenal (I still love it), and I hope generics help with that.
- bobbylarrybobby 6y agoI use it almost exclusively for autocomplete and documentation. It’s nice to able to tab complete a method name and hover my mouse over the method to get its documentation — but this is only possible when the type of the caller is known.
- IgorPartola 6y agoWhat’s a mouse? :)
- bobbylarrybobby 6y agoI believe gh does the same in Vim?
- Gene_Parmesan 6y agoI've never used a dynamic lang with type hints (edit -- but perhaps TypeScript counts?), but with static typing, IMO one huge benefit comes from the tooling that it enables. Being able to hover over a function in an IDE and see the types of the arguments it takes is a massive speed-up. Being able to type a dot after an argument name inside a function and see all the methods available on that type/interface is huge. This sort of static analysis is not possible without type information. For instance, in my free time I do a lot of low-level 2D game engine programming for kicks, and I end up working a lot with SDL (and sometimes Win32 directly). The number of arguments some of those functions take is extraordinary. Without static typing, working with those libraries would be so much more arduous. With static typing, it's... well, maybe not a breeze, but certainly better. Another big benefit is how it makes your code self-documenting -- and makes that self-documentation self-enforcing. If you are making an API for consumption, it's dead simple to make it very clear how it's structured, and to set & enforce contracts for its usage. For me, in general it is more about its power to ease the cognitive load associated with coding. Having to constantly look up documentation to see what the types of arguments are and in what order they need passed brings me out of flow. When I don't have to think about that, I can spend more time focused on the problem at hand. That doesn't mean I can't program without them; I have to do a fair amount of Vue stuff at work and I make it work despite not being a front end guy. But my preference is always for static typing.
- IgorPartola 6y agoThat makes sense. I haven’t touched something like a C++ gaming engine in a while so the idea of a function with more than like five arguments is not something I’ve seen in a while. I can see type hinting being useful to give an IDE more info.
- floxy 6y agoI don't think you can appreciate types until you start dabbling in something like Haskell.
- pansa2 6y ago> I still can’t quite figure out why type hinting is such a sought after feature. Same here. The arguments for it seem to be: - It allows you to find bugs in your code without running it. I’ve concluded that my workflow must be different from people who make this claim - I never write code without testing it. This is more comprehensive than relying on a type checker, because it finds all kinds of errors, not just type errors. - It’s a form of documentation of function parameter and return types. This is better served by comments, because type hints are usually inaccurate in a duck-typed language like Python. For example, I see hints like `def twice(x: int) -> int: return x+x`. The correct type for a function like that isn’t `int`, it’s something like `addable`.
- duckerude 6y ago`addable` might be too broad. It describes the implementation, but not the intent. If you know that x is only ever an int then you can safely change the implementation to `return 2 * x`. Sometimes constraints give you extra possibilities.
- pansa2 6y agoI think this represents a difference in philosophy. I want to write functions once and use them wherever suitable, not write separate functions like twice_int, twice_string etc.
- duckerude 6y agoYou can write it for ints, figure out it's also useful for strings, and change the signature to also accept str. And then if you do ever want to change the implementation you can reason about the callers more easily and you won't have to create a new variant function for fear of breaking them. But perhaps that only makes sense for some functions. Probably not twice().
- BerislavLopac 6y agoThat's called "protocols" in Python.
- 6y ago
- hikarudo 6y agoThe pros and cons of types should always be discussed in the context of type systems. Types exist in a type system. There are many, many things that can be expressed with types... depending on the type system. In Haskell, when you look at a function type, you instantly know whether it returns an optional value (a Maybe), or if it has side effects (IO), etc. You can also tell how general the function is, by how abstract its parameters are. An example of something that becomes possible with a rich type system: https://hoogle.haskell.org/ https://hoogle.haskell.org/
- int_19h 6y agoExplicit typing causes errors to be reported early, aka fail fast. This is very helpful to debugging, because the closer the error is to its source, the easier it is to understand the cause. In a language with dynamic typing, it's not uncommon for the "wrong thing" to be passed around for a very long time before some piece of code actually tries to use it, and blows up because it's not what it expected it to be. Tracking down where such a value came from can be very tedious in large codebases. (In statically typed languages with implicit nullability, nulls create the same problem.) Basically, explicit contracts are Good, and types are a subset of explicit contracts that are more easily enforceable than most.
- BadInformatics 6y agoThis is my biggest pet peeve with (dynamic) languages that don't distinguish between declaration and assignment. Python's drive to make type annotations look "nicer" certainly doesn't help either. `list[1, 2, 3]` feels a little too clever.