I love TypeScript, if nothing else for how it's been able to popularize types.
I love TypeScript, if nothing else for how it's been able to popularize types.
There are some genuinely untyped languages, or more typically "stringly typed" ones. I hacked around on AREXX as a youth, where all values are strings, even when they look like numbers. Most of the Unix CLI tools like sed could be, uh, said, to be stringly typed. Most of the "discussions" about typing, though, involved Python and similar dynamically typed languages. I don't think I've ever heard someone claim that weakly typed or untyped languages were great for building large project. I've heard plenty of people claiming that Python couldn't be used to build large projects because it was dynamically typed, or "untyped" as they wrongly described it, which was confusing to those of us using it to build large projects.
> where people would say goofy things like they couldn't use Python because it's untyped. That's insane: Python is strongly typed. It's also dynamically typed, which is a different dimension.
hmm maybe you don't understand type-checking INSIDE IDE, NOT during runtime?
I'm increasingly convinced that "strong/weak" has no useful meaning. Some people regularly use it interchangeably with "static/dynamic", others use it to vaguely refer to how much casting exists in a language, or how easy it is to transmute a value of one type into a value of a different type. There is no academic definition at all.
Mostly it gets used as a kind of cheap attack - it's like the meme "it's over, I've portrayed you as the soyjack and me as the chad". Good languages are strong, bad languages are weak, so if I say your favourite language has weak typing, and my favourite language has strong typing, then it's clear that my favourite language must be superior.
In general, I think it's more helpful to just reference the specific language feature you're talking about. Rather than say that JavaScript is a weakly typed language, instead say that there are a lot of implicit type conversations. Rather than say Erlang is strongly typed, say that there is no variable reassignment or shadowing. That way, you avoid the ambiguity about what you actually mean when you talk about strong or weak typing.
* Maybe. Not quite sure about "weak" for this one, but I think it makes sense because you can just lie to typescript and then after compilation it just runs as javascript.
Like I said, if you're going to talk about automatic type conversion, then calling it "automatic type conversion" is probably the simplest option - strong vs weak typing doesn't really need to come into it. Then you avoid any definitional confusion.
But what Python does have is tagging: when you create an object you tag it, and then whenever you operate on those values, you check the tag and maybe raise an exception or not. This is happening at runtime.
Strongly typed and weakly typed do not seem to have good definitions. A good one I've read is that "strong typing describes the typing you like".
It is great though if people go to the same extent as you to define what they are talking about, as this reduces the chances of misunderstandings. But it should not be taken as fact that the definitions you have chosen are the universally accepted ones.
Is strongly typed not “I compiler/runtime guarantee the bytes I read adhere to type T”?
In Typescript this is by design. The most obvious is array variance. Typescript makes them covariant because that's what a lot of sane TS and JS code uses them as, but they should be invariant because you can write to them.
Example:
const dogs: Dog[] = []
// A sound type system would error here,
// but there's too many useful cases where you want to do this
const animals: Animal[] = dogs
animals.push(new Cat())
animals[0].bark() // runtime TypeError here class Animal { }
class Dog extends Animal{
bark(){return 1}
}
class Cat extends Animal{
bark(){return 1}
}
const dogs: Dog[] = []
const animals: Animal[] = dogs
animals.push(new Cat())
animals[0].bark() <<<<< "Property 'bark' does not exist on type 'Animal'."I didn't go to college for software engineering or anything so when I ran into that for the first time I assumed there must have been some good academic reason that was simply beyond me as to why it was done that way.
It turns out that no, it's just as weird to those that do have the formal background, boy am I feeling vindicated ;)
For example, I find it highly annoying to have to sprinkle type annotations all over the place when the compiler isn't smart enough to figure out what I mean, in the absence of ambiguity. Like imagine this C code:
int main() {
int i = 23;
auto j = i;
printf("i = %d, j = %d\n", i, j);
}
There wasn't a great way until recently (C23, I think?) to say "just make j whatever type it needs to be here and don't pester me with it". Contrast with Rust which is strongly, statically typed but also infers types where it can: fn foo1() -> i8 {
23
}
fn foo2() -> String {
"foo2".into()
}
fn main() {
let f1 = foo1();
let f2 = foo2();
let f3 = f1 + f2;
println!("Hello, world!");
}
Here, that bit in "foo2" says "cast this str into whatever type you can infer it's suppose to be". Since it's going to be the return value of a function that returns a String, it must be a String, so Rust casts it to a String. Similarly, the first line of main() says f1 is an i8 because it's assigned to something that returns an i8. f2's a String for the same reason. The f3 line is an error because you can't add an i8 and a String, and Rust can figure all that out without having to annotate f1 or f2.I love Rust's typing because it's helpful and makes strong guarantees about the program's correctness. I'm not "anti-typing" at all. I'm just not a big fan of languages that make you annotate everything everywhere. Back when such arguments were in fashion, a pre-auto C fan might reduce my whole argument to "you don't like typing, newbie!", which would make me roll my eyes and hand them a lollipop.
FWIW, I think TypeScript's pretty great. I never like JS. I tolerated it, and could use it, but didn't enjoy it at all. TS is fun, though.
In C++ one can declare a completely typeless lambda:
auto callsAdd = [](auto x, auto y) { return x + y; }
And the programmer need never specify what x and y are, as long as there exists a reachable declaration of operator+ that has two arguments that accepts whatever x and y resolve to, at instantiation time (which is compile time).I've had a good experience developing small to medium sized Python programs/scripts using type annotations plus ruff connected to my editor through its LSP (Language Server Protocol). It helps a lot, and I don't like to write Python without it.
You can create types from literal values and use union types, which I feel makes it more pleasant than Go's type system for example.
So:
i = 23 # Create an int(23) object and store its address in i
i = "foo" # Create a str("foo") object and store its address in i
i isn't typed. It's a reference to a thing with a type, not a thing with a type itself. It's also pragmatic, in that 99.9% of cases, `1.5 + 2` has a completely obvious meaning. I don't recall ever seeing int+float being the source of a Python bug. Surely someone has, but I haven't.> Python's strong typing mostly boils down to some operator rejecting mixed types.
Well... yeah. Turns out that plus duck typing is very nearly all most people want out of a type system. I went from Python to Rust and found nearly no difference in how they handle types, except Rust does it at compile time. Judging from the number of people I've seen make the same migration, that seems to be common. And yet no reasonable person makes claims that Rust is weakly typed, even when IMO it's basically Python but enforced at compile time.
> It's also pragmatic...
So it's almost like Javascript. That something is not a source of bugs, is not proof of strong typing. Python uses type information in some cases, that's it. E.g., it's trivial to load some record or file of the wrong type, and only find out much later. That's a real source of very unpleasant bugs.
But by most people definitions, Python certainly is NOT strongly typed.
My take at a definition... Strongly typed languages make a serious effort to use the type system to prevent whole categories of bugs.
It kinda bites with the "dynamic typing" (a euphemism or marketing-speak for "weak typing") that Python/Ruby/JS implement. Sure some are adding typing now (trying to make big codebases in those languages more manageable), but it's always an optional add-on.
for the record - I agree completely.
(glad people are over the unicode thing!)
the kind of types that helps you reason and read the code. As opposed to the type you mostly don't have to think about anyway, which is complete missing the point.
I'm not sure I would go that far, but I would definitely say that I remember many, many moments where a Python codebase hit critical mass and the amount of time I spent documenting and checking types exploded. It wasn't really about static, explicit typing, so much as "once my tools (IDE) are taken into account, how much time am I spending trying to reason about correctness?" Reasoning about types was the main contributor to that with Python before type annotations.
Get the f*ck outta here.
Come on, that was very clearly what he was talking about. No need to be this pedantic.
I'm one of those, but what I mean is that there are no static types you (and the compiler) can reason about.
Moreover there's a difference between types as compiler bookkeeping, as in Fortran or C, and types as propositions about program behavior like in ML, which highly influenced modern type systems, including TypeScript, albeit Ocaml, F# and the Rust type system belong to the ML family.
Unfortunately this was in the middle of browser wars, so no one cared about the standards and all of that work was lost like tears in rain.
Around that time I attended MS conference where they introduced IntelliSense and it was a forming experience for myself. You could do actual programming basically with <space>, <dot>, arrow keys and <enter>.
"x = " and there are only two variables in the scope with the same type so IDE will present them to you in a drop down and you can already think about the next line.
Fast forward to ~2015 when I'm working on Angular project. The whole idea feels like a caricature Chinese whispers of an OOP framework. Each component is divided into three files, all of them have to identify themselves using a magic string, and that string has to be manually entered into each file.
There are couple of type systems, like the one from Facebook, but no one is using them. And everyone claims that OOP and types are the thing of the past.
Part of that corelates to a joke I was making back in 2013, soon after Apple killed Flash and everyone started doing JS everywhere. Major companies where posting job offers for senior javascript devs asking for 5-7 years of experience. But someone who was doing JS for 7 years in 2012 has all his career focused around gluing together jquery plugins.
Anyway, I'm as well glad that we finally did a full circle and finally have some sanity in the industry...
> Unfortunately this was in the middle of browser wars, so no one cared about the standards and all of that work was lost like tears in rain.
> Around that time I attended MS conference where they introduced IntelliSense and it was a forming experience for myself. You could do actual programming basically with <space>, <dot>, arrow keys and <enter>.
I think you’re off by at least 6-7 years. Visual Studio had autocomplete since at least version 6. And yes it was magical the first time you experienced it.
Ever wondered why, even on modern websites, css is riddled with repeated statements with this weird "moz-" prefixes?
In 2006 when working at Wikia I wrote a tiny lib for deep linking.
The lib started at 25 lines with naive implementation of the documentation. Two weeks later when I had all browsers on all operating systems mapped out it was close to 1,000 lines.
I've spent half of my coding time working with Flash, and the monopoly was great. You could make a layout, write a code and have absolute certainty that the outcome will look and feel exactly the same regardless if you ran it on desktop, in the browser - any browser, mobile or kiosk.
Few years later I did UI for The Witcher and Dead Island and with that you can add xbox and playstation to the list.
Last time I did some web programming was 3 years ago, but it was still a far cry from that experience.
My father took me to that conference so that would be closer to 2000 or 2001.
Fun fact, around that time I attended 3 "microsoft summit" - that was the name of the event - and every time the absolute banger, booked out months before the event, was a workshop with a guy who specialized in optimizing windows licensing for enterprise.
That was still the time when MS charged per CPU on servers, and the guy used to give couple seemingly basic scenarios and asking crowd how would they deal with licenses. Every time his version was 3-4x cheaper than what you would think of.
It's more common on consultancy than product companies.
Consultancy is getting paid for doing things. Product company is getting paid for getting things done.
I don't enjoy writing it, but I don't mind to maintain it, all apps have a predictable architecture.
Performance wise it's also extremely good, between stream based rendering and deferred rendering you can trivially ship lean and fast code.
It's a great fit for large parts of the industry defaulting to react which is notoriously difficult to tame when performance matters.
My read is that people were never really against types: they were against type systems that got in the way. Older ones often weren't expressive enough, so you ended up writing verbose patterns just to appease the compiler.
That's why dynamic languages gave startups a sizable velocity edge for a while. Modern type systems (with optionals, unions/sum types, inference, etc.) are completely different.
To paraphrase a comment I once read here on Hacker News: I'll take static typing with sum types over dynamic typing, but I'll take dynamic typing over static typing without sum types...
The discussions and articles online seemed to infer that, but that's uh. media bias? Hype? Things written about and things you read online are not the full story, is all.
Why certain approaches didn't catch on until recently, or ever, is an interesting thing to think about but "we didn't know how" is not the story here.
That's the difference between "having a typing error" and "having an error due to typing".
well kinda
> if nothing else for how it's been able to popularize types.
This is such an odd, javascript dev take.
Even before JS became the language for everything, there was a good chunk of time - maybe between 2005 and 2015? - when Python and Ruby were dominant in this environment, and this dismissive attitude towards static typechecking was similarly dominant.
Of course in the enterprise space everyone was using Java, and in the systems space or game dev space everyone was using C++. But those worlds get a lot less airtime here.
Plus everyone on HN is a good little pg disciple, and Lisp is dynamically typed. If the One True Language doesn't need static typechecking (though SBCL offers some very helpful heuristics) surely it's not worth it. Right? Right?
"Lisp" isn't a single language. Arguably the language people speak about when they say Lisp without qualifier, ANSI CL, allows conforming implementations (e.g. SBCL) to offer gradual typing, not just heuristics.
Ish.
SBCL aggressively infers types wherever possible. It can do dynamic typing with tags of course. You can also write it with 100% static types.
Dynamic typing isn't a defining feature of Lisp style languages (even GC isn't necessary). Some historic Lisps and modern ones are 100% statically typed.
Um, isn't it? Don't all Lisp variants have it? IIRC McCarthy's LISP just ran out of memory until the GC was written.
No. There's been GC-less Lisp's over the years, here's a good paper on one: https://dl.acm.org/doi/10.1145/142137.142162
There was also pre-Scheme, GOAL, nowadays there's Carp and Dale. Zeta Lisp (and now SBCL) had/have arenas and you can manually allocate, etc...
> McCarthy's LISP
McCarthy also envisioned it having M-expressions.
P.D: Before, the exposure of types was from C++/Java, and special C++ is always a horrible exponent of anything except how make a overly complex language.
Once you see what good application of types look like, is far better sell!
Functional programmers keep hyping up ADTs like this but the normie programmer doesn't care about ADTs or immutability. What really brought back static types was Golang & typescript, both have local variable type inference, good IDE support & other tooling, and (at least superficially) lighter weight syntax than Java. Normies don't care about algebraic types, pattern matching, immutability, referencial trasparency, type classes. What matters is libraries and tooling.
Yes, it's a skill issue, but oh dear the amount of developers who have that issue.
At worst, TS can only really be as bad as JS, no?
”Look the type says the data has this shape”, but it doesn’t. This has led to so many cases of ”no data validation” in my experience, how people solve that is usually then with zod, and now you have added a massive runtime dependency instead of local validation.
Even without TS, I'd be using zod (or a similar library). I haven't had any issues with zod's bundle size, and I don't see a good reason to write custom encoders/decoders everywhere.
That's a bit hyperbolic so I'm sure I'm wrong, but I have an ace: if you point me at very smart people who argued against types I'm gonna say that they weren't serious. I think it's not possible, if you have the relevant experience of working on both typed and untyped codebases of at least moderate complexity with at least one collaborator, to come away seriously believing that the untyped way is superior (unless you were forced to use a really bad typed language, I guess). And arguing that untyped languages are better without that experience is also not serious, in the sense that anyone can unseriously say anything if they don't care about being well-informed enough to be right.
Static vs dynamic typing is no less ubiquitous in online forums over the decades than tabs vs spaces and vim vs emacs.
e.g. Gradual typing was since added to PHP and Python which ended some debate like how linting tools shut down a lot of whitespace debates.
In the early days they would often say things like "but we have prop types, why use TypeScript", "why not use JSDoc" (this made no sense at the time), or "it's an exercise in needless complexity". It was really tough to sell them on TypeScript for years.
I think there are developers who are very goal-oriented with a narrow perspective on getting from point A to point B, and their understanding of the process isn't particularly holistic, rigorous, or geared towards external or knock-on factors like maintainability, performance, bugs, etc. They deal with it when circumstances force them to, and no sooner. Defining types is a complete waste of time to someone like that.
These people thrive where teams are primarily expected to just ship things, and in my experience they often hate needing to think about things like types, tests, or code quality beyond running a linter.
So, they're serious people in one school of thought. They contribute meaningfully to projects. I think they're a large constituent of the new class of vibe coders who laugh at you if you look at the code. That's fine, they're doing their thing, and there are more than a few ways to get programs into people's hands. That way just isn't the way I like to.
Obviously "production quality" varies greatly from shop to shop, but I think there's more legitimacy to the idea than you're giving it.
This is totally fine sometimes though, because like you say, there are shops where this type of execution is suitable. It's why vibe coding is actually okay in many cases; it's not a lot different from what it replaces in these cases. There are a lot of situations where this is the bar, it produces enough utility an value, and that's great.
Personally - I also think people really underestimate just how much the tooling around types has improved over the last 20 years.
If I'm having to try to look up the difference between iBrowserInterface6 and iBrowserInterface5 and iBrowserInterface4... (and yes - shit like this really did exist: https://learn.microsoft.com/en-us/windows/win32/api/shdeprec...)
And I have no tooling for autocomplete, and the docs are shoddy, and google is just coming on the scene...
People understandable want to throw their computer out the window.
Types are great. Some forms of them were not.
I just don't think this is true.
Frankly - it's hard to argue this at all (even today) given that JS is the dominate language on the planet, and it lacks types... as does python, which had a reputation for decades as THE language to use to teach new folks to code. Or take PHP which dominated server development for a LOOONG time: also lacks types. Ruby on Rails has a wonderful reputation as the "get shit done" framework: no types.
Types are good for modern software companies, where code size has ballooned up very high (common to work on a codebase with hundreds of thousands of lines) or teams are large (50+ developers) and terrible if you just want to hammer out something that works as a solo dev.
Do I like types today? Sure - the tooling is solid, and I work on large codebases with large teams.
Did I like types as a solo dev at 3 person startup? no.
I am very perplexed by this. I am going through Neetcode's DSA course where he explains what RAM and arrays are, but then he goes on to say something like "but since we are going to use Python, none of this applies." Personally, I learned the most about how software really works from reading The Rust Programming Language. It not only teaches you how to program in Rust, but also how memory works, what a string really is, etc.
At a startup you can choose even fancier languages, since nobody is stopping you!
When companies started making enterprise-scale JS applications they had to solve for the type story because it is unmaintainable otherwise. TS is the winner in a long line of iterating on that problem.
And before Java finally settled on what we have today, we had 3rd-party libraries like jodatime that tried to fix it.
I guess it’s in a good state today, but it took a LocalDateTime.MAX to get there. I mean an Instant.MAX. No, I mean an OffsetDateTime.MAX. No, I mean new Date(Long.MAX_VALUE). Oh wait I meant new Timestamp(Long.MAX_VALUE). No, I mean LocalTime.MAX.
I’ll stop now, but i could go on.
I still feel this way about the state of the art. I want solid type support in my language ... but I do not feel TypeScript is the best possible implementation at all, and for many situations I feel implicitly typed (but still using all of VS Code's type features) Javascript is actually better than using TypeScript.
I eagerly await the day when someone actually gets a JS typing tool right and I prefer using it over raw Javascript.
WinRT for all its pain points, is still COM, only with a different set of base interfaces, and using .NET metadata instead of classical COM type libraries.
was amusing to come back hours later and find out whether this comment ended up more upvoted or more downvoted, it was oscillating all day...
So, not sure that counts as "serious" in your estimation, but I would definitely argue that dynamically typed languages are superior for a large class of problems.
Also, just a tip: it's usually better to be less sure of yourself, and seek to understand other's reasoning. It'll get you a lot farther than trying to convince everyone of how right you are.
If you're not sure why an experienced developer would hold an opinion different than yours, why not just ask?
it is not an either or.
https://world.hey.com/dhh/turbo-8-is-dropping-typescript-701...
That comment is expected by a Ruby enthusiast, which is arguably one of the most dynamic languages in existence.
I think that comment is clear in that he likes to work alone which for problems of a certain size just isn't feasible
I have migrated to TypeScript just about a year ago and it's my third try to migrate to TS from JS during the last decade and finally a successful one. While TS went a long road since the first versions which were incredibly hostile, my rewrite of a large codebase from js to ts revealed exactly zero type-related bugs.
1. 20% were type-coercion bugs, 30% were non-boolean values being passed to boolean-named fields (with some overlap with the former). Linters have come a long way, but compile-time type-checking is better in almost every way.
Static types are IMHO more useful for speed, maintenance/refactoring of large projects, and code completion in IDEs. But a codebase in production is unlikely to have much type related bugs...
I don't think that's an acceptable way to treat your users. If something is trivial to prevent, do it.
The concept of them being more than compiler bookkeeping, but as propositions about program behavior and invariant encoding is more than 50 years old at this point.
What IDE/LSP do you use? I was on VSCode/ruby-lsp and disabled sorbet, but after working with Zod, I became quite intrigued with the value of letting the schema do a lot of the guarding. I was under the impression that things like Crystal (statically typed Ruby) were not in vogue, and that the reason no one was moving toward static typing was because Matz did not give his blessing.
(Just checked sorbet landing page, looks like it's mainly/only for fn signatures?)
A lot of Rubyists deeply care about code aesthetics and Sorbet annotations are unfortunately quite ugly. There are also RBS comments, which look a bit better, but tooling/LSPs are not quite there yet IME.
Me when my manager asks to complete the JIRA ticket.
edit: the downvote button HN is not for disagreeing with comments or unpopular opinions. please dont turn hn into reddit.