4 ms·
While I respect people that prefer programming without explicit types, I can’t understand it.
by osigurdson 3y ago
While I respect people that prefer programming without explicit types, I can’t understand it.
- tnecniv 3y agoThis was something that was in vogue in the mid / late 2000s, then Haskell became the cool kid language and types are back. The thing that drives me crazy about Python typing is that I need to import stuff to make full use of the type system. Like I get that the typing is option because that would be a huge language overhaul, but it feels weird that so many tools get hidden inside libraries (standing or otherwise).
- deleted 3y ago[deleted]
- scubbo 3y agoAFAIK, you only need to import the actual types that you're using (`from typing import List, Iterable, Optional, ...`). What else is there?
- bbkane 3y agoIn newer Python versions, you don't need most of those imports either: foo: list[str] = ["a"] bar: int | None = 1
- saulpw 3y agoYeah, but that's completely unnecessary friction.
- scubbo 3y agoGranted - but the original claim was that "it feels weird that so many tools get hidden inside libraries", and I'm asking for an example of more than one of these "so many".
- abdullahkhalids 3y agoBut why do we have to import any? They should be part of the core language by now. The lack of boldness of Python core developers is sometimes very annoying.
- verbatim 3y agoMost of it is part of the core language now.
- CameronNemo 3y agoYep the only one I've found myself importing as of late is Any.
- ShamelessC 3y agoMany programmers don't get a choice in the language they have to use. Or they don't get a choice in the language they learn first. In either case, it is best to steel-man the case for the language you're using at any given time. Ideally, you should do this once for a language with explicit types (e.g. C++/Rust), once for a language with dynamic/implicit types (e.g. JS, Python3) and maybe once for a gradual typing system like TypeScript. Then you can appreciate which tool to use and when, rather than getting distracted by strange religious notions about how "this language is better than that one". It also prevents you from forcing conventions the language doesn't align well with, and that if you're going to _try_ to do so - you should do so gradually and very carefully.
- winstonewert 3y agoI can make two observations that explain some of it. Other aspects of a language can matter more than the types. Python, for example, was a well constructed language in many ways that make up for much of its disadvantage on the typing side. Many commonly used statically typed languages have poor type systems. They will both fail to detect some important errors (like null pointers) and get in the way when writing more generic code.
- impulser_ 3y agoI use to think the same, then I tried Elixir. It made me realize the language ecosystem can outweigh cons as big as not having types. The Elixir ecosystem is top notch. Phoenix, Ecto, Livebook, Mix, Hex, Nx, Axon, Scholar, Explorer, Broadway, and Rustler are libraries and tools that make it hard to use anything else even when the language doesn't have types. I never enjoyed programming in a language more than Elixir. Tho, they are currently are in the process of researching a type system for Elixir.
- s6ro 3y agoElixir is functional and immutable first, (and structs) - that alleviates somewhat the pain of not having a strong type system. I really like the architecture of OTP, but I still find myself using Elixir in anger. Especially, if I'm trying to bring and old(er) codebase (Elixir 1.9) up to the newest release... and upgrading packages, checking if things are likely to brake etc. I constantly find myself realising that I cannot trust the compiler, which means more defensive coding, more tests, more time spent... As an example, upgraded postgrex. The return tuple of one its functions had changed from 2 elements to 3 elements. Did the compiler caught it? No. Had I had dialyzer type spec-s on my private function, I would at least gotten a warning. Thus, morale of the story: always type spec even your private functions , especially if they use 3rd party code.
- datadeft 3y ago{:ok, x} | {:err, y} is my favorite pattern. You can make sure that the caller handles both cases, the ok case and the error case. What you put in y is up to you. If you have dependencies you can decide the bubble up error or return something that you want. We have a bigger system in Elixir and it was trivial to write the correct implementation for exponential backoff to interact with the outside word (calling lots of external services that sometimes time out). With Python this is not as trivial because Guido hates pattern matching and you have catch exceptions and do if else a lot. With Elixir I see immediately while developing if I left out a case. With Python I see it in production when we crashed.
- dbrueck 3y agoI'm one of those people. :) Well, it's not so much that I prefer no explicit types, I just dislike how most languages require you to specify them, and to do so at the least opportune time, so I end up preferring languages that don't require them at all. (Ideally, the language would let you start with none and then layer them in as the design gels.) FWIW, there are definitely ways to do it "right" in languages like Python, but it's a slightly different approach to dev than in other languages, so people create a mess if they don't shift, or if they are just untrained/sloppy/lazy/whatever. But when you have a team of people doing it right, it's really quite nice, even as the codebase grows large. But if even just one person on the team can't be trusted to do it that way, you're probably better off in some other language.
- skitter 3y agoWhat do you think about e.g. Roc having whole-program type inference that always works and always infers the most general types?
- dbrueck 3y agoIn isolation, I love the idea. I don't have a strong sense of how the tradeoffs would affect things in practice though. Perhaps they are not a big deal, but if they are too restrictive, then maybe the next best thing would be to have anything go (like in Python or Javascript), but the compiler guides you to where it's having trouble inferring things.
- irrational 3y agoFor me it is that I learned to program in dynamically typed languages and have used them for decades. I am interested in using types, but it is not enforced at my work, I am not given time to learn how to use them at work, and I’m too busy at home to learn it on my own.
- dsQTbR7Y5mRHnZv 3y agoI find it helps to think about it like this: Whether you specify them or not, the data moving around your application _has_ types. Strings, ints, booleans - they're all there. You're just keeping that information in your head while you work. By writing them in the code, you're simply offloading all of that and saying "I trust the computer to validate this better than I can." Which is exactly the kind of thing we should be trusting computers to do. They won't forget what type something is 5 function calls deep and they won't get tired from lack of sleep. I know I prefer having the computer tell me I made a mistake while I'm developing something rather than a user emailing me after I've shipped it.
- irrational 3y agoSure, I just have no idea how to write them, what the syntax is, where to write them, etc. Since my work doesn’t care to give me time to find out, and I don’t have time to do it on my own, it isn’t going to happen until it becomes a priority at work.
- neilwilson 3y agoTypes are really just a way of applying certain tests to part of your code. In dynamic languages the typing is just moved to the test suite. We can see that with the way type hints are enforced in Python and Ruby - by running a program that takes those hints and essentially runs a bunch of tests. If you look at the code of Terraform, for example, you'll see that it spends a lot of time trying to get around the limitations of Go typing. The rise of dynamic languages in the early 2000s was a direct result of the perceived limitations of the type systems of Java, C++, etc. and the ability to use a different way of constraining code (Test driven development, behaviour driven development). Now it is swinging back the other way with the implementation of more flexible type systems. Before too long the limitations of those type systems will start to grate and the pendulum will swing back to dynamic languages again - based upon some new innovations there. Get used to the back and forth in IT. The static/dynamic cycle is but one of many. (Centralisation/decentralisation is the other main one). You'll find lots of work in IT is reimplementing existing stuff in the current fashionable paradigm.
- elcritch 3y agoNo modern type systems are powerful and flexible enough that I don't believe the pendulum will swing back toward dynamic languages, at least to the same degree. Especially with dependent typing becoming more of a thing. Then again perhaps LLM programming will become the new thing. ;)
- HdS84 3y agoTypes replace some tests and introduce a lot of ceremony. If this a worthwhile tradeoff depends. E.g. I wrote c# and Python for a living. Especially in the mid 2010s python was much better for the Microservices I wrote because they are so small that you could unit test them exhaustively. The lack of ceremony and small domain model made development super easy. C# just felt clunky and limiting. You spend lots of time wrangling types which could have been figured out by the compiler. Nowadays c# has gotten a lot of features that reduce type ceremony and extend their usefulness (nuallibility checks, better tuples etc) so it feels much more ergonomic (unlike java where the culture still goes off on needless verbosity) . Python also got types which I use a lot, it helps to document it for other developers, ides and spot bugs.