5 ms·
Rewrites only make sense if you get a multi-fold improvement. In the history of computing, that's rare. So they rarely make sense. Well, JavaScript was really
by wegs 6y ago
Rewrites only make sense if you get a multi-fold improvement. In the history of computing, that's rare. So they rarely make sense.
Well, JavaScript was really horrible when it came out. It was just about the worst major programming language ever made. It sort of reminds me of an interpreter I threw together for a programming language I invented when I was in high school, when I really didn't get any aspect of programming language design, and I based it on a misunderstanding of Lisp.
Given its central role, lots of people used JavaScript, and lots of smart people tried to fix it. Every few years, it'd get a lot better. It actually made sense to rewrite everything -- you got that multi-fold improvement in productivity going 1995 JS to 2000 JS, 2005 JS to 2010 JS, and so on. I mean, with each iteration, it was still obnoxiously bad, but it was that much less bad.
It looked like an exponential growth curve for a while, but you always knew it was an S-curve -- you hit an inflection point when you reach the level of competently-designed programming languages.
At some point in the past five years, JavaScript stopped being really bad. I mean, it's no Python, but it's at least within spitting range. Heck, it's better than Java. I won't even lose 2x productivity writing in JavaScript over best-of-breed languages, at least core language (ecosystem aside -- there is no numpy/scipy/pylab -- but that will come too).
With that, rewrites every five years no longer make sense. Unless there's some fundamental progress in computing, I expect JavaScript code I write today may still be used in 20 years. That's not something I would have said in 2010 or 2000.
- mettamage 6y agoHow about using Typescript? That still seems like a huge improvement, especially because you can implement it incrementally (aka for parts of code where type checking is vitally important). I'm using it now at my work and I'm surprised how much info I'm getting compared to whatever JS is throwing at me.
- gfodor 6y agoTypescript doesn't strike me as a multi-fold improvement. Dynamic vs static typing is an age-old debate, and in general, advocates can be found arguing that moving your code in either direction results in benefits. So, regardless of your stance on it, it seems unlikely to be unambiguously beneficial. Many large programs exist written in dynamic languages that do just fine.
- throwaway894345 6y agoIt seems like it's trending toward static, at least recently. I think the big driver for this is the popularization of statically typed languages that aren't C++ and Java. A lot of people had painful experiences with C++ and Java and attributed that pain to static typing. It's now more clear that static typing is a net benefit, but it must be implemented reasonably and it doesn't solve other language design issues. Also, C++ and Java have each evolved some rudimentary type inference, which improves ergonomics (although I think excessive type inference a la Haskell actually makes it harder to debug issues--the sweet spot seems to be function-scoped type inference).
- gfodor 6y agoHard to say. It seems as cyclic as anything else. Hard to tease apart real benefit from the usual fad/hype cycles. Ruby, Python, Erlang/Elixir, Lisp/Clojure, etc, all doing just fine without it. (Some, with some lightweight annotative-oriented typing for a subset of projects.) The best counterargument to static typing I can articulate is that in general, the only way to be sure software works is to run it. And so, ultimately you need to backstop your software with testing, QA, and observability infrastructure to actually execute it and validate it. At that point, the question is what marginal gains remain from catching a subset of those problems at complile time, also incorporating a potential a false sense of security which may lead to less actual execution validation, and more user-facing issues. The other potential tradeoff of static typing is if the software design and architecture changes for better or worse, or if the velocity of shipping changes changes. I believe there isn't yet any hard evidence of which way this tilts in either case. There's also a lot of innovation in the area of validation-by-execution as well, and so I think that will result in continual debate: state-of-the-art static typing may benefit compared to yesterday's testing/fuzzing tools, but may not compared to state-of-the-art testing/fuzzing tools, for example.
- pacala 6y agoOne of the greatest boons of static typing is formal documentation of data structures and interfaces. Catching errors early is a bonus :)
- nisten 6y agoI would avoid doing state management in Typescript. It's still too early in my opinion. Use as many hooks and context as possible and keep your redux store as simple as you possibly can because if you end up with a deprecated state management library (redux-thunk, sagas, easy-peasy) replacing that is like pulling gum out of hair. If you add up the time spent working around typescript errors when dealing with state, it's possible for it to be more time than you need to rewrite the entire app. For backend work then yes, I'd say doing a singleton or an abstract class in typescript makes more sense in hardening your API code and even making it more readable too.
- acemarke 6y agoI'm a Redux maintainer, and I'm _strongly_ in favor of using TypeScript for any meaningful app development [0] [1]. Also, I don't know why you're referring to thunks and sagas as "deprecated". Thunks are the recommended default approach for async logic in Redux [2], and we include them out of the box in our Redux Toolkit package [3]. While most apps don't need sagas, they're a great power tool to have in your toolbox. Neither of those is in any way "deprecated". [0] https://blog.isquaredsoftware.com/2019/11/blogged-answers-learning-and-using-typescript/ https://blog.isquaredsoftware.com/2019/11/blogged-answers-le... [1] https://redux.js.org/style-guide/style-guide#use-static-typing https://redux.js.org/style-guide/style-guide#use-static-typi... [2] https://redux.js.org/style-guide/style-guide#use-thunks-for-async-logic https://redux.js.org/style-guide/style-guide#use-thunks-for-... [3] https://blog.isquaredsoftware.com/2020/02/blogged-answers-why-redux-toolkit-uses-thunks-for-async-logic/ https://blog.isquaredsoftware.com/2020/02/blogged-answers-wh...
- nisten 6y agoSorry I meant as in an older version of a library that an app has been built on and hasn't been updated or maintained for a few months. I should have put that better, the libraries themselves are not deprecated, their dependencies can be. While this negligence problem would be on the fault of the dev team and management for not doing regular package updates it is an all too common issue in many companies. What I am saying is that bad typescript is harder to fix than bad javascript because type errors compound the problems of convoluted code.
- kqr 6y agoIn my opinion, if you're going to add a compilation stage to your bundling anyway, you can get far more mileage out of other options (such as Fable) than the tiny improvement TypeScript is. The additional compilation complexity is not worth the small benefits of TypeScript, in my opinion. An even better language, though? I'm in.
- mettamage 6y agoNever heard of Fable, will check it out! :D
- wegs 6y agoTypeScript? Erm... Not for me. There were many such systems in the past. CoffeeScript was a big improvement over 2010 JavaScript. Before that was GWT, which was sooo much nicer than 2006-era JavaScript. I could list a bunch of others. If you used any of them, you're now stuck with a legacy system(+), and you'll find fewer and fewer people able to read/write your code, and otherwise. I'm also not a big fan of static typing. And if you do static typing, you should at least do it properly, which is not what TypeScript does. Types should be things like "This is an integer between 0 and 100," "Meters/second," or similar. We've known this for a long time. Ada is now 40 years old and was mandated for military work since if you added feet and inches without a conversion, that was a problem, and that resulted in more robust systems (TypeScript would make them both of type "number" and never catch the error). If you tried to have 120% of your fuel tank full, you'd violate an assertion as well. Those were turned on in dev and in your test suite (but generally turned off in your deployment system, which was running on a 33MHz CPU if you were lucky). C++ templates let you define things like "This is a list of lengths, in meters." Duck types languages like Python won't do this statically, but it's easy enough to do dynamically; while you won't catch errors at compile-time, at run-time, you'll get a clear exception. (+) Standard disclaimers apply.
- rowanG077 6y agoDependently typed language can check at compile time if you violate a ranged integer value among many other things. I'm curious though why you are not a fan of static typing? I feel like if you have a language with inference it's pretty good. I mean you could imagine python with type inference and you could essentially write anything in it you can today (baring stuff like heterogenous data structures) without specifying the type manually.
- wegs 6y ago(1) I like generic code which I can use as I see fit later. In Scheme, I can write: (lambda (x) (* x (+ 3 x))) A half-decade later, someone can take that code, pass a pair of specially-crafted objects to it to introspect what it does, and take a symbolic derivative, pretty-print that derivative with LaTeX, combine it with a few other pieces, and compile it into native code (and yes, that does happen). But a lot of my code is generic in a way where types get in the way. (2) If I do have typing, the type should usually be specified manually, but it should have semantic meaning, not be based on inferring whatever types my programming language happens to have built-in. What's important isn't that something is an integer, but that it's a count-of-apples. I should be able to compare a count-of-apples to a count-of-oranges without first converting them to a count-of-fruit. This is especially important for numerical code, and especially in education. A lot of Scratch tutorials have little kids add a velocity to a position, without first multiplying it by a time. That leads to deep-rooted misconceptions. I don't mind type inference if it's designed to give me feedback. I've seen a few systems (designed for students) which do things like take JavaScript: let x=5; let y="hello"; let z=x+y; And flag that in the IDE. That's kinda nice. And obviously, many systems do optimization at runtime based on inferred types. That's not a problem either. So there's a fuzzy layer in between. But the discussion was about TypeScript, not that fuzzy layer.
- pacala 6y agoTypescript greatest features are optional types and the extensive type inference. On small projects this can work well, but on larger ones I can see overly rigid style guides requiring typing everything explicitly in triplicate becoming cumbersome in an Enterprisey way. Curious what people's experiences are.
- mercer 6y agoTypescript, for me, makes JS jump from 'good enough' to 'might use it even if I have other options'. I still prefer using other languages when I can (back-end), but hypothetically, if I had to choose between Ruby and Typescript I'd actually go for the latter. And I like Ruby!
- nwienert 6y agoTypescript is leagues ahead of Python. Types and async/await are the big ones, but destructuring, no lambda weirdness, optional chaining, nullish coalescing, proxies, JSON support, and generally debugging tools are all better.
- throwaway894345 6y agoI'm not well-versed in TypeScript, and I have plenty of frustrations in Python so it's not that I don't believe you, but I do have a few questions: * Python has async/await. It's not as pleasant as goroutines, but it exists and is presumably about as pleasant as async/await in TS, at least assuming you're using or not using the type system in both cases. * Python has tuple/list/iterable destructuring. What is the specific limitation here? Maybe key/value destructuring? * What's python's lambda weirdness? The single expression limitation? I agree that's tedious, albeit you can do a lot with a single expression (but not handling exceptions). * JSON support. What's wrong with Python's JSON support? I mean, the type system can't model recursive types yet and that's super annoying, but the JSON stdlib seems fine. JSON maps pretty neatly onto Python dict/list/str/int/float/None/etc types. * What are proxies and why are they desirable? Genuinely curious.
- nwienert 6y agoPython has some async, but it never felt as core and easy. Tbh, it’s been years since I’ve done much Python. But the last time I did it was just really clear that TS had leapt ahead. Ecosystem may be part of it. Proxies are essentially meta programming tools, tbh not fully sure Python doesn’t have similar but on looking they don’t seem as intuitive.
- throwaway894345 6y agoAs previously mentioned, I'm a Python critic, but it has changed a lot since you last used it. Async (for better or worse) has gained a lot of traction as have type annotations (although the type checker is a huge pain--can't model JSON or any other recursive type, can't express a callback that takes kwargs, getting it to acknowledge type stubs on upstream libraries is a forbidden art, it's pretty slow, etc). No doubt that TS is better, however. It has amazing engines, an MS-backed developer experience, coherent type system, not the worst package management ecosystem, etc. If I could switch us off of Python to any language, I would choose Go but I wouldn't be angry if we landed on TS.