12 ms·
A lot of us still feel that way. The trade off is still there, and in many situation I still don’t find types to be worth the trouble.
by phyrex 8y ago
A lot of us still feel that way. The trade off is still there, and in many situation I still don’t find types to be worth the trouble.
- DonaldPShimoda 8y ago> The trade off is still there Not really, in my opinion. Type inference especially has come a long way. If I offer you a choice between language A and language B and claim that their syntax is nearly identical and you'll use essentially the same number of keystrokes to accomplish the same task in both, but language B can inform you about mistakes you've made at compile-time instead of waiting until run-time... which one are you going to choose? While dynamic languages afford some degree of freedom, that freedom comes at a cost. The tradeoff used to be that safety required lots of extra writing (e.g., Java). Now that this isn't the case... the freedom of dynamic typing can be more harmful than helpful. (I still use Python all the time, so don't mistake me for a static-only zealot of some sort. But I think the landscape of type systems has changed a lot since Kay made these claims.)
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- staticassertion 8y agoThere's definitely still a cost to static types. Types can be thought of as a way to defensively program - encode what you can to avoid runtime errors. At minimum this means you have to think about your constraints - we may both agree that that's a fine tradeoff, but it's a tradeoff nonetheless. Erlang, an actor based system, does not do this. Instead, it assumes that even if you added types youd run into failures and any reliable system should spend its efforts not trying to avoid that but to deal with it. Erlang allows you to instead encode failure modes in an extremely resilient way (supervisory trees) and to trivially move code across networks to avoid hardware failures. Languages like Python, in my opinion, are the worst of both worlds. Python encourages lots of shared mutable state but, until recently, offered very little static analysis. Time was instead spent on testing code - something that I do not believe it does any better than Erlang or a statically typed language. To me, the answer is sort of... why not both? We can use actors and supervisory trees and static types. As an example, I write Rust services that execute on AWS lambda in response to queue events. I get state isolation and all of the good bits of the actor model, and static types. Pony is a more fine grained solution, offering static types and in-process actors.
- gridlockd 8y agoTypes aren't just for catching type errors, they're also a way of defining and enforcing at least parts of the programming contract. Most type systems are poor at this, but it still goes beyond just catching runtime type errors. The time you save from writing a dynamic program is time not spent on defining that contract. You will eventually be paying for that when the first major refactor comes - if it comes, that is. You will pay for it with extra test coverage, if that's in the budget. Or you will pay for it by re-writing everything. Those may all be worthwhile tradeoffs, but in the long run, I think static types win out.
- staticassertion 8y ago> Types aren't just for catching type errors, they're also a way of defining and enforcing at least parts of the programming contract. I don't disagree. To be clear, I'm a type safety zealot. > You will eventually be paying for that when the first major refactor comes - if it comes, that is. This is fine but not relevant. Erlang, for example, just assumes you'll fuck up the refactor. Actors are isolated interfaces and you can not share state - so a failure in one actor can not impact other actors directly. It's fine to say that static types are better but if you read about Erlang you may find the approach very compelling - Erlang's managed to provide the basis for extremely reliable systems, without types. And as I said, it is not either or. You can build power supervisory structures and statically type your code if you like, but no languages really do it, so you have to reach outside of the language (like using a distributed queue/ microservice approach).
- hota_mazi 8y ago> It's fine to say that static types are better but if you read about Erlang you may find the approach very compelling - Erlang's managed to provide the basis for extremely reliable systems, without types. I have yet to see some convincing proof of that, besides that Ericsson router from 20 years ago that ended up being rewritten in C++. Also, even if it is true like you say that > Erlang's managed to provide the basis for extremely reliable systems, without types. This still doesn't prove that there are no languages that can do a better job at it than Erlang. 99.99% of extremely reliable software today runs on non Erlang: C, C++, Java, you name it. Finally, in my experience, writing supervisors in Erlang is just as painful, and if not harder, than writing resilient code based on exceptions in Java or C++.
- gridlockd 8y ago> If I offer you a choice between language A and language B... Realistically you don't have the choice between hypothetical buffet languages A and B, you have a choice between Java or C# and Python or Javascript and maybe a handful others. Those are the type systems you will have to deal with, most likely. I'm sure the type inference in Haskell (or similar) is fantastic but virtually nobody uses those languages so those benefits are purely theoretical for most programmers. By the way, static type inference in Javascript also has gotten pretty good and in many cases it can catch all of the bugs that an ordinary type checker would catch.
- chriswarbo 8y ago> Realistically you don't have the choice between hypothetical buffet languages A and B, you have a choice between Java or C# and Python or Javascript and maybe a handful others. Those are the type systems you will have to deal with, most likely. > I'm sure the type inference in Haskell (or similar) is fantastic but virtually nobody uses those languages so those benefits are purely theoretical for most programmers. I think this argument would hold more water if the dynamic language under discussion wasn't Smalltalk...
- rifung 8y ago> Not really, in my opinion. Type inference especially has come a long way. Does dynamic typing also make writing tests easier? For example when writing tests in Python it's relatively trivial to mock out specific methods or functions. However, when I was writing tests in Go, I realized to test things which required mocks I would have to change all the type signatures to use interfaces instead of structs, and that required writing a new interface as well. I admit I am not entirely sure whether this difficulty stems from static vs dynamic typing or something else.
- joshuamorton 8y agoHonestly this is why I think dynamic languages with optional type systems tacked on are the best. You get a huge amount of power in your type system (Python is actively working on dependent types and supports variance first class), but for code where that's a burden (test cases), you can drop it. Maybe powerful macros that let you copy an interface (Python's mock.patch with autospec=true, but better) would solve the same problems, but you don't generally have that option.
- narag 8y agoDoes dynamic typing also make writing tests easier? Maybe it's dynamic typing what makes writing (so many) tests necessary to begin with.
- mpweiher 8y agoNope, at least not in general. Tests tend to test values. Types generally don't catch wrong values, so if you implement add() as subtract(), the signatures are the same, but you still get a wrong result. However, tests of values incidentally also test the types, because values have types and for the values to match, the types must also match. So if you write the tests that you need to write anyhow, the ones for the values, you have also tested the types, without extra effort.
- deleted 8y ago[deleted]
- seanwilson 8y ago> Type inference especially has come a long way Maybe you know this, but type inference goes back to the 1970s. It's taken this long to start seeing it in mainstream languages. Similarly, pure functional strongly statically typed languages with type inference, pattern matching, algebraic data types and non-null types have been around for literally decades yet we're still stuck debating about the so-called benefits of dynamically typed languages.
- ridiculous_fish 8y agoNo this completely misses the point! The point is the development model, not the language syntax. Static types assume a "static" phase: an edit-compile-run cycle, with bright lines between each stage. But as a Smalltalk programmer, you inhabit the system and build it inside-out, while it is running. For example, during development it is routine to query live objects. The lines between the edit-compile-run phases disappear. Static types don't make sense in the Smalltalk model because there's no static phase.
- ddragon 8y agoI agree with that. The interesting aspect of dynamic languages is that it's a living program, you can interact with, it can interact with itself and you could even effectively make it an entire new program without ever closing it like the Ship of Theseus. Smalltalk, Lisp Machines and the Erlang Virtual Machine were pushing this idea. Which is why I feel that a dynamic language that doesn't focus on the interactivity, like having a great REPL based development cycle, hot swapping capabilities and strong code as data utilities kinda misses the point in the trade-off between static and dynamic, sacrificing safety for too little. Jupyter notebooks seem to have recently brought a little of the first to the mainstream at least.
- e12e 8y agoBut there's more to type systems than static types - gradual / dynamic typing is a thing. Eg: http://www.strongtalk.org/ http://www.strongtalk.org/
- momentoftop 8y agoStatic types assume no such cycle! Milner's MLs, which introduced the hugely influential simple type theory to functional programming in the late 70s, of which Ocaml and Haskell are derived, supported global type inference, and were very "lispy". They were first used for interactive theorem proving, where you spent all your time spinning around MLs REPL, updating your global environment where your global bindings have a nice static type, and when you had finished for the day, you saved your image (you save-lisp-and-die'd). This is still a way to use Ocaml today, and Poly/ML, which is the standard ML used for the Isabelle theorem prover, makes heavy use of an image based model.
- anon1m0us 8y agoI'm going to choose the dynamic one. It's a risk and reward. You're giving away seconds or so on every line, for what might take a little debugging if one is encountered. I'd rather get the code written and the problem solved than make converting a string into a date the problem to be solved. There are plenty of problems figuring out if something is a date or not, but it's worth it.
- jimmy1 8y agoAnd then you have charts like this https://rollbar.com/blog/top-10-javascript-errors/ https://rollbar.com/blog/top-10-javascript-errors/ 9 out of the 10 most common JavaScript errors are around types, hence why such a large push to type JavaScript (TS, Flow, Elm, ReasonML)
- joe_the_user 8y agoIf things have fundamentally changed, what is that a type-inference based language that's fast but nearly as easy as Python?
- ken 8y agoDepends on what exactly you mean by “type inference”, “fast”, and “easy as Python”. Smalltalk has been pretty fast for ages (without inference, and may or may not be as easy as Python to you). JavaScript JITs can use a form of type inference, so you get the benefits of speed with no change to syntax. Again, it’s pretty fast, and “easy” is in the eye of the beholder.
- yxhuvud 8y agoCrystal.
- gridlockd 8y agoIt's not worth the trouble with "write once" programs that you never refactor. I think the problem is that mainstream statically typed programming languages come with terrible or non-existing metaprogramming facilities to make up for type constraints. Rust supposedly has good metaprogramming but then it also has a type system that is so obnoxious it's not "worth the trouble in many situations".
- courtf 8y agodon’t find types to be worth the trouble This is the part I always fail to grok in discussions about type systems. For me it is just the opposite: I typically don't find dynamic typing to be worth the trouble, so I fail to understand this sentiment when going the other direction. Maybe it's because my degree is in mathematics (lots of proofs written out long-hand), and my first language was Java? I have since all but abandoned many of the ideas that Java so rigidly enforces, OOP among them, but static typing just has so many advantages for me that I have no desire to get rid of it. One thing I've noticed in some recent work is that the static language I'm using (Go) allows me to both be lazier and get more done than comparable work being done in dynamic languages. I'm not reading or writing tons of documentation (I'm reading other people's code directly, or just looking at the types involved and moving on). I'm not constantly handling byzantine runtime errors or having to memorize the arbitrary intricacies of any over-bearing frameworks in order to be productive. I don't need to be on guard quite so much, I lean on static analysis. In general I just don't need to hold so much extraneous crap in my head, it's all spelled out right there in the code and I'm free to think about larger concerns, like the best way to solve the problem at hand. And when I circle back around to some 10-20k line library I wrote 3-6 months ago, I can read, understand and refactor parts of it quickly. People often talk about developer comfort and speed being improved by dynamic languages, and maybe that's true if Rails solves all your business needs, but for many of the tasks I've work on, that just hasn't borne out over the past 10 years. I have no doubt that dynamic languages seemed a breath of fresh air after fighting with C/C++/Java, but to my eyes Ruby/Python/Javascript etc were always a bridge too far for a lot of tasks.