[HN Gopher] How types make hard problems easy
       ___________________________________________________________________
        
       How types make hard problems easy
        
       Author : tlf
       Score  : 36 points
       Date   : 2024-12-19 19:38 UTC (3 hours ago)
        
 (HTM) web link (mayhul.com)
 (TXT) w3m dump (mayhul.com)
        
       | tinthedev wrote:
       | Not to devalue the author, or their findings/learnings... but I
       | could see this was a JavaScript/Typescript coder (very likely
       | self-taught) learning about typing paradigms.
       | 
       | A lot of people, especially people from the same background,
       | would benefit from branching out and learning some other
       | programming languages/paradigms.
       | 
       | Some... statically typed and actually compiled languages. Maybe
       | to take an entry course in CS.
       | 
       | It's very popular to hate on formal education, especially in
       | software, but all these lessons would have been learned in the
       | first semester or two.
        
         | tugu77 wrote:
         | 100% this. For a C++ or Rust programmer this reads so weird.
         | 
         | Don't get me wrong, I'm not hating on JS here, and I have lots
         | of beef with C++, but I fully agree with your take that TS
         | barely scratches the surface of the statically typed world.
        
           | throwuxiytayq wrote:
           | Based on my small amount of work done in TS, it seemed like
           | one of the more advanced type systems out there. To the
           | detriment, even. The language was just huge, and that was
           | years ago.
        
             | eyelidlessness wrote:
             | And it's so advanced because it was/is designed to
             | represent the types of real world dynamic JavaScript. More
             | often than not, when people complain about the complexity
             | of the types they encounter in the TS type system, they're
             | really complaining about the types of the underlying JS
             | (which are the same whether they're expressed statically or
             | not).
        
               | wk_end wrote:
               | There's a cultural problem in the TypeScript ecosystem, I
               | find, where people are impressed (with both themselves
               | and others) when complex interfaces can be expressed in
               | the type system, and tend to embrace that instead of
               | settling for simpler (and often admittedly more verbose)
               | ones. Maybe that's because they're an ex-JS programmer
               | who wants to use the exact same interface they'd use in
               | JS with no compromise, or maybe it's just because they
               | think it's cool. Either way I think it's really
               | detrimental to TypeScript as a whole.
        
               | TheHegemon wrote:
               | Do you have some examples for that?
               | 
               | Most cases I've seen with more complex interfaces is due
               | to the fact that it is what the interface truly expects.
               | Usually making it simpler tends to mean it's actually
               | wrong or incomplete.
        
           | FractalHQ wrote:
           | This isn't true, is it? I've only ever heard that TypeScript
           | has one of the most advanced type systems of any mainstream
           | language.. but I don't have enough experience with other
           | languages to know how true that is.
        
         | throwuxiytayq wrote:
         | In my experience, university is one of the least efficient ways
         | to learn CS. The actually useful classes are few and far
         | between, dwarfed by useless outdated courses, courses that
         | aren't very relevant to the job, and classes that are sadly
         | lead by incompetent burnouts who don't know that they're
         | teaching, come terribly unprepared, and in general seem to hate
         | their job. Most of the people there have _theoretical_
         | experience in writing software. But maybe that's just my shitty
         | university. I dunno. Supposedly one of the better ones.
        
           | CaptainNegative wrote:
           | I think the problem is in going for a Computer Science degree
           | when you really meant to study Software Engineering.
        
             | n4r9 wrote:
             | I imagine quite a bit of a Computer Science degree _is_
             | relevant if you plan to be a computer scientist.
        
           | karaterobot wrote:
           | On the other hand, as an Engish Lit major who taught himself
           | programming from zero, and worked as a programmer for over a
           | decade, _all_ my experience writing software was practical,
           | and I don 't think that's the right way to go either. I wish
           | I'd had any level of theoretical education that might have
           | exposed me to fundamental concepts you ( _with yer fancy
           | book-learnin '_) probably take for granted. If someone just
           | learns on the job, or just learns as they go, they don't
           | learn stuff until they need to. They learn it in a hurry, and
           | on a deadline. That's not the best way to get a firm handle
           | on tricky subjects, and maybe as a consequence, I always felt
           | a couple steps behind my peers.
        
         | thorum wrote:
         | I've spent many years working in statically typed languages and
         | doing formal study. I expect the author's "inordinate amount of
         | time spent working on the Heartbeat codebase, a 300k+ line
         | Typescript full-stack application" is a much more powerful
         | education.
         | 
         | Actually wrestling with the problems that a thing was made to
         | solve, in a real world project, is always a better teacher than
         | someone just telling you to use the thing because it's best
         | practice.
        
         | tlf wrote:
         | That's interesting to hear. I started out with a formal CS
         | education learning Java & C in school. I've found that
         | traditional CS education doesn't really take this approach. A
         | lot of what I was exposed to was very OOP-heavy practices that
         | emphasized data modeling via class hierarchy. To me, the
         | expressiveness of the Typescript system (being able to do
         | things like sum types or branded types) is what unlocked a lot
         | of potential despite not being a compiled language.
        
         | motorest wrote:
         | > A lot of people, especially people from the same background,
         | would benefit from branching out and learning some other
         | programming languages/paradigms.
         | 
         | I completely agree. I started reading the article expecting to
         | read something interesting or smart about functional
         | programming,but it turns out the blogger is just very vocal at
         | telling the world their excitement over reinventing the wheel
         | and being completely obliovius to what actually represents very
         | basic things in any intro to software engineering course.
        
       | t-writescode wrote:
       | It's always fun getting to see people experience the positives of
       | type systems. So many of the most popular and "easy" / "user-
       | friendly" languages drop types in favor of friendliness and
       | speed. The most vocally popular web languages - Python, Ruby and
       | Javascript - all seem to either ignore or not have types at all.
       | 
       | People make huge projects in them and start learning new
       | techniques and then the weight of the choices they made begin to
       | grow.
       | 
       | Enter: Types, a frequent savior. Not always the best choice for
       | everyone, but a very good and useful thing.
       | 
       | I welcome this person on their journey!
        
         | stavros wrote:
         | > The most vocally popular web languages - Python, Ruby and
         | Javascript - all seem to either ignore or not have types at
         | all.
         | 
         | All three of those languages have ways to use typing, so this
         | statement is only true in the sense of types not being
         | mandatory, which is also the case in any language that has the
         | Any type.
        
       | Barrin92 wrote:
       | >Using the same language everywhere. Naturally, if we want to
       | share type information as much as possible, we need to be using
       | the same language
       | 
       | This goes to the heart of what's not great about this, types
       | impose global semantics on a piece of software, they introduce
       | coupling. (It's why Alan Kay used to stress "late binding of all
       | things") as a feature of managing complexity.
       | 
       | In fact one result of this kind of programming were
       | microservices. What do they do? _Reintroduce runtime dynamism_.
       | It 's not often framed that way but there's a reason you see more
       | statically typed microservices than Lisp or Erlang ones. It's
       | because they're an attempt to get away from the coupling imposed
       | by type driven programming and towards more independence of each
       | service. Which is already baked into message based, dynamic
       | languages.
       | 
       | And there's also a fundamental misunderstanding about data and
       | types in the article.
       | 
       | > Making our types represent the "truth"
       | 
       | Types can't represent truth. Real world data doesn't have types.
       | It changes incrementally however it wants, and all the time. You
       | can use types to not let something you don't want into your
       | program, but you can never represent arbitrary real world data by
       | matching types onto them.
        
         | esafak wrote:
         | > Types can't represent truth. Real world data doesn't have
         | types. It changes incrementally however it wants, and all the
         | time.
         | 
         | What do you mean? If a variable is a date/time or an integer
         | etc. in the real world it should stay that way and be
         | represented as such in software.
        
           | leeeeeepw wrote:
           | AI chatbot example, you're chatting and then there could be
           | some Mark down, latex, images maybe base64 encoded webp,
           | audio files, we can type all this stuff do all the
           | validations and such, understand it better and there's some
           | gains to be had doing that, then likely someone like Facebook
           | comes along with this Giant byte Transformer expert system
           | with all of the data specific optimisations, that's kind of
           | the bitter lesson but I guess the main point is that the
           | problem itself of how to best communicate with AI is not
           | necessarily solved so you can get bogged down typing the best
           | possible ways to do it but it's a moving target.
           | 
           | Same with a lot of systems like say a search system that
           | tracks data using the best embedding, well we don't know what
           | that best embedding is in terms of price performance and
           | encoded knowledge perf it's just a moving target.
           | 
           | Send me the system that tracks important metrics effecting
           | the stock market, or a weather system etc... the sensors are
           | all updating and then an entirely new thing comes along like
           | Starlink that helps us track the weather in totally new ways
        
             | msanlop wrote:
             | > get bogged down typing the best possible ways to do it
             | but it's a moving target
             | 
             | As someone who is still learning this is a huge reason why
             | I've come to love dynamic languages. Any project I do
             | involves a lot of rewriting as the code evolves, I found
             | that trying to predict ahead of time what the structures
             | and types is a big waste of time. I've found the best
             | middle ground for me to use python with type hints. It
             | allows for quick iteration and I can experiment and only
             | then update the types to match what I have, so that I can
             | still get LSP help and all that.
             | 
             | But I could see this being less relevant with more
             | experience
        
           | ervine wrote:
           | Not if your types represent something you don't control, like
           | an API response.
        
         | Garlef wrote:
         | > you can never represent arbitrary real world data by matching
         | types onto them.
         | 
         | I think that's why the article references the 'parse, don't
         | validate' article: Real world data is messy and so you ingest
         | it into your business logic at the system boundaries via
         | parsing.
        
       | wryoak wrote:
       | The first point lost me because it pushed responsibility for
       | functioning software onto the user. If your entire application
       | ecosystem has to be recompiled because you conceived of a new
       | clever way to conceptualize the data that doesn't actually affect
       | the user experience, what happens is I have to update my damn
       | bank app every time you think you've done a smart, even though
       | you've changed nothing in regards to my checking my balance.
        
       | digging wrote:
       | I loved this paragraph:
       | 
       | > This dichotomy gels really well with the way my brain works.
       | I'm able to channel short bursts of creative energy into
       | precisely mapping the domain or getting type scaffolding set up.
       | And then I'm able to sustain long coding sessions to actually
       | implement the feature because the scaffolding means I rarely have
       | to think too hard.
       | 
       | It's why I keep begging my team, every time there's a new
       | codebase (or even a new feature), to stop throwing `any` onto
       | everything more complicated than a primitive. _It is exhausting_.
       | It forces me to waste energy on the shitty, tedious parts. It
       | forces me to _debug working code_ just to find out how it works
       | before I can start my work.
       | 
       | They tend to take the quickest solution to everything -- which
       | means everyone else has to do _the same work_ over and over again
       | until someone (me, invariably) sits down and makes a permanent
       | record of it.
       | 
       | In doing this they ensure that _I can 't trust any of their
       | code_, which is counterproductive for what should be obvious
       | reasons. Every time I work on established, untyped (or poorly
       | typed) code, it's like I'm writing new code with hidden, legacy
       | dependencies.
        
         | ervine wrote:
         | Why is `any` allowed at all? Enable strict mode, set up your
         | linter, don't allow any implicit or explicit `any` anywhere.
         | 
         | Without this, Typescript is next to useless. Not knowing if the
         | types are good is worse than no types at all.
        
           | phyrex wrote:
           | Progressive typing of an untyped code base. Types that are
           | too complex to represent in that type system.
        
             | t-writescode wrote:
             | * Common functions such as parsing functions in languages
             | that don't support function overloading            *
             | "equals" and other global functions.
        
             | ervine wrote:
             | Yep, adopting strict after the fact is a different
             | conversation, but one that has been talked about a bunch
             | and there is even tooling to support progressive adoption.
             | 
             | Types that are too complex... hmmmm - I'm sure this exists
             | in domains other than the bullshit CRUD apps I write. So
             | yeah, I guess I don't know what I don't know here. I've
             | written some pretty crazy types though, not sure what
             | TypeScript is unable to represent.
        
               | mikepurvis wrote:
               | Progressive code QA in general is IMO an underexplored
               | space. Thankfully linters have now largely given way to
               | opinionated formatters (xfmt, black, clang-format) but in
               | the olden days I wished there was a way to check in a
               | parallel exemptions file that could be periodically
               | revised _downward_ but would otherwise function as a line
               | in the sand to at least prevent new linter violations.
        
           | umvi wrote:
           | Sometimes you don't have the type for something, especially
           | if it's 3rd party code. For example, if you are integrating
           | recaptcha with your page:
           | https://developers.google.com/recaptcha/docs/loading
           | 
           | You could try to craft your own type to match google's schema
           | or hunt down 3rd party types, but just doing `(window as
           | any)["__grecaptcha_cfg"]` gets the job done much faster and
           | it's fairly isolated from the rest of the code so it doesn't
           | matter too much.
        
             | ervine wrote:
             | Yeah, those are few and far between, generally there will
             | be a DefinitelyTyped for anything popular, and you start
             | choosing libs that are written in TypeScript over ones that
             | aren't.
             | 
             | But for your own handwritten application code, there is no
             | excuse to use `any`.
        
             | swatcoder wrote:
             | You don't have to provide complete types. If you know what
             | you need to access, and what type to expect (you darn well
             | should!), you only have to tell TypeScript about those
             | specific properties and values.
             | 
             | Generally, the conveniences of allowing any are swamped by
             | the mess it accumulates in a typical team.
        
               | digging wrote:
               | [delayed]
        
           | digging wrote:
           | That's what I would do if I were the project lead, but when
           | the most senior developers are the ones who refuse to budge
           | and just ignore anyone raising concerns, letting type-fix PRs
           | rot for weeks, they disable the rule making `any` an error
           | and do what they want. I never said I was in a well-
           | functioning team.
        
       | alephxyz wrote:
       | >Changing our database schema should cause us to see errors in
       | our frontend code.
       | 
       | I shuddered.
        
       | axelthegerman wrote:
       | And:
       | 
       | > How types make easy problems hard
       | 
       | Sure that's sometimes an issue with the type system itself
       | (looking at you Sorbet) but also preventing the programmer from
       | taking advantage of the flexibility, expressiveness and elegance
       | the language itself my add (yes, Ruby).
       | 
       | But even Typescript, which is arguably one of the better type
       | system/language pairings out there, often causes more headache
       | than it's worth.
        
         | umvi wrote:
         | I've seen some truly insane TS types. Ones that validate SQL
         | queries and stuff.
         | 
         | The problem with complex TS types is that there's no debug
         | tooling. You can't set a breakpoint, you can't step through the
         | type propagation. If there's an issue you have to just do trial
         | and error, which can be very tedious.
         | 
         | Here's a super complex type I ran into in the wild that has a
         | bug that is extremely difficult to fix unless you burn hours on
         | trial and error: https://github.com/openapi-ts/openapi-
         | typescript/blob/main/p...
         | 
         | (the bug in question, still unfixed):
         | https://github.com/openapi-ts/openapi-typescript/issues/1769
         | 
         | It was so hard to fix this bug that I found it easier to just
         | rewrite the entirety of the library but using code generation
         | instead of ultra complex TS types to accomplish the same
         | outcome.
        
       | shreddit wrote:
       | I also recently switched from javascript to typescript and
       | noticed a clear improvement on my speed to write code. Before i
       | had to constantly switch between files to check what i exactly
       | passed to a function. But I knew C# before so a typed language is
       | nothing new for me. But when i started with javascript exactly
       | this "untyped" language felt like something good, it felt much
       | less of a burden to think about the code beforehand. Now i look
       | at dozens of projects which a have to be converted to typescript
       | because I simply cannot deal with this typelessness anymore...
        
       | TZubiri wrote:
       | Looking forward to the response article on how types can make
       | easy problems hard.
        
       | moshegramovsky wrote:
       | C++ guy here. I love being able to make a change and watch the
       | compiler tell me what's broken. In the past year, I was able to
       | justify large scale changes to a big codebase because I could say
       | with confidence that the type system would reveal all. And it
       | did.
        
       ___________________________________________________________________
       (page generated 2024-12-19 23:00 UTC)