frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

Open in hackernews

What Dynamic Typing Is For

https://unplannedobsolescence.com/blog/what-dynamic-typing-is-for/
46•hit8run•4d ago

Comments

hit8run•4d ago
Just read this article and it vibes with my personal journey. I've built and maintained many web applications for more than 20 years. PHP, Ruby, Python, Java, Dotnet, Go, Node, Bun etc.

The most maintainable codebase is the one that requires the least guessing from the developers perspective. Where everyone that looks at the code immediately gets a good understanding of what is going on. When it comes to this I personally had the best experience with Go so far as it is verbose when it comes to error handling (I don't need to guess what happens or what can go wrong etc.). Is it the most elegant? No, but I don't need to build a big context window in my brain to understand what is going on immediately (looking at you Rails callbacks).

Anyways I found the article interesting and as I am also using SQLC I think it is something that goes in that direction.

TeaVMFan•3h ago
I agree strong typing is a necessity in the front end. To prevent the language explosion issue, I recommend writing your single page apps in Java. The Flavour framework makes this quick and easy with complete maven tooling and powerful components.

Flavour book: https://frequal.com/Flavour/book.html

Flavour home page: https://flavour.sourceforge.io/

Example app: https://frequal.com/wordii

kstrauser•2h ago
The article isn’t about strong typing. It’s about static vs dynamic typing. For example, Python is strongly and dynamically typed.

Personally, I’d rather stop writing software than write everything in Java, and writing software is just about my favorite thing in the world. I don’t contend that Java is a bad language. However, it’s almost diametrically opposed to how I think about programming logic, and its style and conventions set my teeth on edge. I’m sure Java programmers would say the same about my preferences, too, and that’s OK! I’m not saying that my opinions are objectively right. But I am saying that no one would be willing to pay me what it would take to get me to write Java for a living.

smt88•2h ago
You can use the Java ecosystem with a number of other languages that are completely different paradigms, like Scala or Clojure, or you can use Kotlin as a "better Java"
jamesclar•3h ago
nice article !
BoppreH•2h ago
I agree, but I also thing that static analysis is a requirement for high quality. The obvious solution is (global) type inference, but I have yet to see a language that embraces it.
_flux•2h ago
Have you seen OCaml? Though its inference stops at module boundaries (but you don't need to annotate them) and for some more special type features. In addition it solves some type inference problems by having e.g. different operators on integers and floats, there are no type-directed traits.

But in practice it's quite handy to annotate module interfaces and even individual functions.

BoppreH•1h ago
I hear that OCaml without interface files can cause spooky-action-at-a-distance type errors[1]. Have you had experience with that?

> But in practice it's quite handy to annotate module interfaces and even individual functions.

Yes, but it also limits what information the types can represent because of syntax and human patience limitations. A fully inferred language could associate numbers with possible value ranges, lists with their sizes, enumeration of fixed string values, etc.

[1] https://news.ycombinator.com/item?id=39615796

pjc50•1h ago
Hindley - Milner dates from the 70s, but the only language to fully embrace it is ML.
IshKebab•2h ago
Well... Yeah but then you lose all the advantages of static typing that he rightly acknowledges!

TSX in particular is a terrible example to make the point. It's very very similar to HTML so there is barely anything more to learn, and in return you get type checking, auto complete, go-to-definition, etc. Its so good I use it for completely static sites.

The SQL example is more compelling, but again it's really hard to paint "SQL makes static typing a bit awkward" as "dynamic typing is great here!". Like, you shouldn't be super happy about walking across a desert because your car can't drive on sand. "Look how simple legs are, and they work on sand".

That said, the SQL example does suck. I'm surprised nobody has made something like sqlx that generates the Rust types and does all the mapping for you from your schema. That's clearly the way to go IMO.

8n4vidtmkvmk•1h ago
Kysley and others give you the types in TS. I believe you can write SQL in Linq C# but it's been ages since I've done it. If rust truly doesn't have that yet.. I guess they're missing out.
pydry•2h ago
The thing I think most arch enemies of dynamic typing miss is the underlying economics of writing software.

~98% of software gets thrown on the trash heap before it reaches the point where it really needs to be maintained.

That last 2% of gold dust desperately needs to be maintained well and to work, but to get to the point where you have that asset you'll probably find you need to throw away an awful lot of code first.

If you write that 98% using static typing it will slow you right down - potentially to the point where you dont even get to the gold dust.

If you write that 2% with dynamic typing it will fall apart. A lot of programmers see this process without ever appreciating the fast prototyping that got it there in the first place.

So, this is why Im a fan of gradual typing.

chuckadams•2h ago
I find static types actually speed up writing new code, since that's when I'm most likely to make typos in fields -- just today I had to fix some goofs where I used snake_cased fields when it was expecting camelCase. LLMs love types, and any hallucinations are instantly red-lined. Agreed on gradual typing, but I'd rather approach it from a strict language with an opt-out dynamic type like TS's 'unknown' rather than a duck-typed language with type "hints" the runtime has to always check anyway.

Structural subtyping usually hits the sweet spot for me: I can just create random structures on the fly, the type system makes sure I use them consistently, and my IDE helps me extract a named type out of them after the fact with just a few keystrokes.

lycopodiopsida•1h ago
I like common lisp, where sbcl will catch the worst type errors while compiling, but you can also specify types and they will speed up your code.
Devasta•40m ago
I'm the same. When writing python I write some lines, run and test, write some more, run and test... with Rust I bash out lines of code for an hour then have the compiler and Clippy help me fix it all afterward.
weavejester•2h ago
Static typing is a useful constraint, but it's not the only constraint. Focusing too much on dynamic vs. static typing can make one miss the more general problem: we want code that's expressive enough to do what we want, while being constrained enough to not do what we don't.

Immutability, for example, is another great constraint that's not considered in the article, but should certainly be on your mind if you're deciding between, say, Rust and Java.

The article delves into some of the drawbacks of static typing, in that while it can be more expressive, it can also contain a lot of information that's useful for the compiler but decidedly less useful for a reader. The Rust example that loads a SQL resultset into a collection of structs is a standard problem with dealing with data that's coming from outside of your static type system.

The author's solution to this is the classic one: we just need a Sufficiently Smart Compiler™. Now, don't me wrong; compilers have gotten a lot better, and Rust is the poster child of what a good compiler can accomplish. But it feels optimistic to believe that a future compiler will entirely solve the current drawbacks of static typing.

I was also slightly surprised when templates were suggested. Surely if you're aiming for rigor and correctness, you want to be dealing with properly typed data structures.

addaon•1h ago
> we want code that's expressive enough to do what we want, while being constrained enough to not do what we don't

I don't think that's an ideal mental model. Code in any (useful) language can do what you want, and can not do what you don't want. The question is how far that code is from code that breaks those properties -- using a distance measure that takes into account likelihood of a given defect being written by a coder, passing code review, being missed in testing, etc. (Which is a key point -- the distance metric changes with your quality processes! The ideal language for a person writing on their own with maybe some unit testing is not the same as for a team with rigorous quality processes.) Static typing is not about making correct code better, it's about making incorrect code more likely to be detected earlier in the process (by you, not your customers).

vlovich123•26m ago
> we want code that's expressive enough to do what we want, while being constrained enough to not do what we don't.

Have you somehow solved the halting problem? AFAIK, all Turing complete languages are perfectly capable of expressing the exact same programs.

otikik•6m ago
A program does not tell the machine what to do. It tells the next programmer what we wanted the machine to do.
brabel•2h ago
Very good summary of why static types are so useful, and when they're not so much...

BTW, Java has a framework called Manifold that provides type-safe SQL just like the author wants, with IDE support and everything:

https://github.com/manifold-systems/manifold/blob/master/man...

zahlman•1h ago
> Unsurprisingly, the equivalent Rust code is much more explicit.

Okay, but you can do the same in dynamically typed Python, while still using familiar exception logic and not requiring the type annotation on `req` (although of course you can still use one):

  def authenticate(req):
      match req.cookies.get("token"):
          case None:
              raise AuthenticationFailure("Token not included in request")
          case cookie_token:
              pass
      match req.db.get_user_by_token(cookie_token):
          case None:
              raise AuthenticationFailure("Could not find user for token")
          case user:
              return user
Although I normally use plain old `if`/`else` for this sort of thing:

  def authenticate(req):
      cookie_token = req.cookies.get("token")
      if cookie_token is None:
          raise AuthenticationFailure("Token not included in request")
      user = req.db.get_user_by_token(cookie_token)
      if user is None:
          raise AuthenticationFailure("Could not find user for token")
      return user
Nothing ever forces you to pass "null objects" around in dynamically-typed languages, although it might be more idiomatic in places where you don't care about the reason for failure (or where "failure" might be entirely inconsequential).

The nice thing about the Rust syntax shown is that constructs like `let` and `match` allow for a bit of type inference, so you aren't declaring manifest-typed temporaries like you'd have to in many other languages.

> It's possible to write sloppier Rust than this, but the baseline is quite a bit higher.

The flip side: the baseline for Python might be low, but that's deliberate. Because there are common idioms and expectations: dictionaries have both a `.get` method and key-indexing syntax for a reason (and user-defined types are free to emulate that approach). So indeed we could rewrite again:

  def authenticate(req):
      try:
          cookie_token = req.cookies.get("token")
      except KeyError:
          raise AuthenticationFailure("Token not included in request")
      user = req.db.get_user_by_token(cookie_token)
      if user is None:
          raise AuthenticationFailure("Could not find user for token")
      return user
And for that matter, Pythonistas would probably usually have `req.db.get_user_by_token` raise the exception directly rather than returning `None`.

You can always add more checks. The Zen says "explicit is better than implicit", but I would add that "implicit is better than redundant".

> In essence, dynamically-typed languages help you write the least amount of server code possible, leaning heavily on the DSLs that define web programming while validating small amounts of server code via means other than static type checking.

Well, no; it's not because of access to the DSLs. It's because (as seen later) you aren't expected to worry about declaring types for the interfaces between the DSLs and the main code. (Interfaces that, as correctly pointed out, could fail at runtime anyway, if e.g. an underlying SQL database's column types can't be checked against the code's declared data structures at compile time.)

The main thing that personally bothers me with static typing is that, well, sometimes the type calculus is difficult. When your types don't check, it's still on you to figure out whether that's because you supplied the wrong thing, or because you had the wrong specification of what to supply. And understanding the resulting compile-time error message (which is fundamentally written in terms of what the type is) is typically harder than understanding a run-time dynamic type error (which can usually be understood in terms of what the object does).

hazbot•1h ago
> Okay, but you can do the same in dynamically typed Python

But the rust code is still safer, e.g. you haven't checked for an `AttributeError` in case `req.cookies`, the point is Rust protects you from this rabbit-hole, if you're prepared to pay the price of wrestling the compiler.

qbane•1h ago
Nitpick: SQL is a programming language. But for most CRUD tasks you should rely less on SQL's programming capabilities until processing information is too expensive outside the SQL server/engine. The advice is also for maintainability.
skybrian•1h ago
A fundamental limitation is that static analysis enforces guarantees when a compiler can see and understand all the code at the same time.

It's great when you compile large amounts of code written in the same language into a single binary.

It's not so great for calls between languages or for servers communicating across a network. To get static guarantees back again, you often need to validate your inputs, for example using something like Zod for TypeScript. And then it's not a static guarantee anymore; it's a runtime error.

Database tables often live on a different server than the server-side processes that access them, so mix-and-match between different schema versions that the compiler never saw together is possible in most systems.

To prevent this, you would need some kind of monolithic release process. That runs into lifecycle issues, since data is often much longer-lived than the code that accesses it.

dzonga•1h ago
or just use primitive types - maps, arrays & you skip this noise. if a map key is empty then it's empty.

maybe people should watch Rich Hickey's Value of Values.

jonorsi•59m ago
Very much enjoyed the article, it aligns with a lot of my own thoughts on coding :P.

nitpick - in the Rust example it seems the events are not passed into rendering the events.html template.

https://unplannedobsolescence.com/blog/what-dynamic-typing-i...

t43562•32m ago
Tests are how one constrains dynamically typed programs to make sure they work as expected. I have found that adding tests to untyped python code is far better at exposing bugs than adding typing is. I like my IDE to do completion too but I tend to add typing where I think it helps most rather than everywhere.

It just seems that some people like static types and good for them. Dynamic languages are for those of us who are, perhaps, lazy and want to be free to think about how to solve the problem at a slightly higher level without having to get into details.

For me the details activate my perfectionism and that blocks me from advancing with thinking about the goal and the effort of creating an elegant set of types makes me less willing to suddenly throw everything away when I realise there's a better approach. Dynamic languages give me that ability to "sketch" until I have an answer and at that point I have to ask: do I really need this to be in a higher performance language? Once or twice the answer has been yes but working out the approach in a dynamic language allowed me to do it right in the static language first time.

Waterluvian•16m ago
What I say is that the types exist in your code whether you write them down or not.

When you don’t write them down, you’re saying, “trust me, this works.” But now the types are written down in your head (a very volatile form of memory that can’t be accessed easily by others).

One time when dynamic works well is when “prove this works” is simply not worth the time. Eg. a quick script.

Root System Drawings

https://images.wur.nl/digital/collection/coll13/search
197•bookofjoe•7h ago•33 comments

Is Postgres read heavy or write heavy?

https://www.crunchydata.com/blog/is-postgres-read-heavy-or-write-heavy-and-why-should-you-care
33•soheilpro•1d ago•0 comments

Tinnitus Neuromodulator

https://mynoise.net/NoiseMachines/neuromodulationTonesGenerator.php
171•gjvc•5h ago•115 comments

Flowistry: An IDE plugin for Rust that focuses on relevant code

https://github.com/willcrichton/flowistry
103•Bogdanp•6h ago•17 comments

What Dynamic Typing Is For

https://unplannedobsolescence.com/blog/what-dynamic-typing-is-for/
47•hit8run•4d ago•30 comments

Who invented deep residual learning?

https://people.idsia.ch/~juergen/who-invented-residual-neural-networks.html
53•timlod•5d ago•15 comments

Solution to CIA’s kryptos sculpture is found in Smithsonian vault

https://www.nytimes.com/2025/10/16/science/kryptos-cia-solution-sanborn-auction.html
61•elahieh•2d ago•14 comments

./watch

https://dotslashwatch.com/
273•shrx•11h ago•75 comments

How to sequence your DNA for <$2k

https://maxlangenkamp.substack.com/p/how-to-sequence-your-dna-for-2k
10•yichab0d•1h ago•3 comments

Chen-Ning Yang, Nobel laureate, dies at 103

https://www.chinadaily.com.cn/a/202510/18/WS68f3170ea310f735438b5bf2.html
35•nhatcher•15h ago•11 comments

Using CUE to unify IoT sensor data

https://aran.dev/posts/cue/using-cue-to-unify-iot-sensor-data/
18•mvdan•8h ago•0 comments

Secret diplomatic message deciphered after 350 years

https://www.nationalarchives.gov.uk/explore-the-collection/the-collection-blog/secret-diplomatic-...
47•robin_reala•2d ago•4 comments

K8s with 1M nodes

https://bchess.github.io/k8s-1m/
49•denysvitali•1d ago•9 comments

Liva AI (YC S25) Is Hiring

https://www.ycombinator.com/companies/liva-ai/jobs/inrUYH9-founding-engineer
1•ashlleymo•4h ago

Titan submersible’s $62 SanDisk memory card found undamaged at wreckage site

https://www.tomshardware.com/pc-components/microsd-cards/tragic-oceangate-titan-submersibles-usd6...
65•WithinReason•1d ago•27 comments

Ripgrep 15.0

https://github.com/BurntSushi/ripgrep/releases/tag/15.0.0
277•robin_reala•7h ago•65 comments

New Work by Gary Larson

https://www.thefarside.com/new-stuff
464•jkestner•23h ago•122 comments

Why the open social web matters now

https://werd.io/why-the-open-social-web-matters-now/
39•benwerd•4d ago•3 comments

Coral NPU: A full-stack platform for Edge AI

https://research.google/blog/coral-npu-a-full-stack-platform-for-edge-ai/
70•LER0ever•2d ago•8 comments

Show HN: The Shape of YouTube

https://soy.leg.ovh/
14•hide_on_bush•6d ago•6 comments

Ruby Blocks

https://tech.stonecharioteer.com/posts/2025/ruby-blocks/
163•stonecharioteer•4d ago•93 comments

When you opened a screen shot of a video in Paint, the video was playing in it

https://devblogs.microsoft.com/oldnewthing/20251014-00/?p=111681
88•birdculture•2d ago•9 comments

Picturing Mathematics

https://mathenchant.wordpress.com/2025/10/18/picturing-mathematics/
25•jamespropp•5h ago•0 comments

Attention is a luxury good

https://seths.blog/2025/10/attention-is-a-luxury-good/
127•herbertl•5h ago•74 comments

Lux: A luxurious package manager for Lua

https://github.com/lumen-oss/lux
46•Lyngbakr•8h ago•12 comments

SQL Anti-Patterns

https://datamethods.substack.com/p/sql-anti-patterns-you-should-avoid
186•zekrom•8h ago•133 comments

Fast calculation of the distance to cubic Bezier curves on the GPU

https://blog.pkh.me/p/46-fast-calculation-of-the-distance-to-cubic-bezier-curves-on-the-gpu.html
103•ux•11h ago•22 comments

Our Paint – a featureless but programmable painting program

https://www.WellObserve.com/OurPaint/index_en.html
31•ksymph•6d ago•5 comments

Carbonized 1,300-Year-Old Bread Loaves Unearthed in Turkey

https://ancientist.com/1300-year-old-communion-bread-unearthed-in-karaman-a-loaf-for-the-farmer-c...
5•ilamont•5d ago•1 comments

The Hunt for the World's Oldest Story

https://www.newyorker.com/magazine/2025/10/20/review-the-roots-of-ancient-mythology-books
10•pseudolus•5d ago•2 comments