Live data from Hacker News

Diminishing returns of static typing

blog.merovius.de

431–440 of 632 posts

Re: Diminishing returns of static typing

#431
post #349

Earlier quoted context omitted.

It's worth noting that Elixir (by descent from Erlang) can emulate at least a basic static typing system pretty easily through pattern matching. You miss out on some features common in more traditionally-object-oriented languages (namely: subtypes), but tagged tuples and structs do provide a lot of the same safety benefits in runtime (and tools like Dialyzer can - last I check - use such pattern matching as a basis f…

Elixir and Erlang still lack the ability to typecheck any process behaviors because messages can take any type anywhere.

You can still pattern match when receiving, though (in fact, 'receive' in both Erlang and Elixir does pattern matching already in the same vein as 'case'); just match messages based on a tagged tuple or a record (Erlang) / struct (Elixir) signature or however else you want to define your "types".

Re: Diminishing returns of static typing

#432
post #12

The biggest issue with claims like "there are only diminishing results when using a type system better than the one provided in my blub language" is that it assumes people keep writing the same style of code, regardless of the assurances a better type system gives you. "I don't see the benefit of typed languages if I keep writing code as if it was PHP/JavaScript/Go" ... OF COURSE YOU DON'T! This is missing most of th…

> This is missing most of the benefits, because the main benefits of a better type system isn't realized by writing the same code, the benefits are realized by writing code that leverages the new possibilities.

The inverse is also true; you don't really get the benefits of dynamic typing until you start doing things differently to take advantage of that difference. If you still code like you're in a static language, you'll miss the benefits of a dynamic one.

Re: Diminishing returns of static typing

#433

Earlier quoted context omitted.

You're kinda damning it with faint praise when you say that you can use dynamically typed languages on small projects that fit in your head (and are also probably written by a single developer). You can pretty much use any language in that scenario. But the chickens come to roost around day 30+ or so.

A large project is a poorly decoupled set of small projects.

May be.

Meanwhile real-world non-trivial projects tend to be large projects.

Nice to be prepared for that instead of gambling on "surely we'll extract out smaller projects that fall on the right abstraction boundaries in the face of unknown future requirements."

Re: Diminishing returns of static typing

#434

So the article does praise Go, but how is Rust? Does it strike that sweetish spot? Is it a language a startup should use?

I wonder if they would praise Java, especially ancient Java. It was a very similar language. Easy concurrency was a big selling point. Generics were a matter of casting to Object.

What’s old is new again, though one can hardly imagine cat-v touting the merits of Java.

Re: Diminishing returns of static typing

#435
post #409

Earlier quoted context omitted.

It depends on your type system. In new languages like Idris or F* you can encode in the type the correctness of an algorithm and it will not compile if the compiler can not prove that correctness. For example I can prove my my string reverse works in Idris ( https://www.stackbuilders.com/news/reverse-reverse-theorem-p... ). Or I could prove that my function squares all elements in a list. Etc. Now a big part of the p…

There's no such thing as "proving correctness". You can have bugs in the type definitions. You can have bugs in the english (or whatever your native language is) description of what you think the algorithm should be doing. You can prove a program does what the types say it should do but that is not what "correctness" means. >Now a big part of the problem is expressing with sufficient accuracy what the properties of t…

> There's no such thing as "proving correctness". You can have bugs in the type definitions.

You can have bugs in type definitions and you can have bugs in tests as well and that'll be a problem until computers can read our minds. Type definitions are superior at checking what you specified though because the checking is exhaustive. Perfect is the enemy of good and all that.

> This is no different from writing tests in a dynamic language.

It's not. In that example, the type system will verify the stated property is true for all values of "s". Tests only check some specific examples whereas using types in this way tests all possible input and output pairs. It's like comparing a maths proof to checking an equation holds for a few examples you tried.

Re: Diminishing returns of static typing

#436
post #424

Earlier quoted context omitted.

List typing isn't as superficial as it seems. The following has happened to me multiple times, perhaps in the last month : I have a large code base. I want to replace a fundamental data structure to support more operations/invariants/performance guarantees. I change the type at the roots of the code base. My instance of ghcid notifies me of the first type error. I fix it. This repeats until the program compiles again…

I find that people doing these claims have seldomly really worked in large Python codebases... Personally, I find it pretty workable in Python with a big codebase (but you have to respect the rules like having a good test suite -- you change the time from compiling to running your test suite -- which you should have anyways)... I find that the current Python codebase I'm working on (which has 15 years and around 15k…

> I definitely had much more null pointer exceptions on java than typing errors on Python

Null pointers are a type error. The fact that several nominally "statically" typed languages don't differentiate between nullable and non-nullable types is a significant source of failure in their type systems. Using a modern language that properly identifies nullable values as a distinct type from non-nullable ones goes a long way towards eliminating a whole host of problems. It will be interesting to see what things look like in 10 years or so once Rust has had time to really displace a significant portion of the C and C++ code in the wild, and hopefully Kotlin has killed off Java (and if we're really lucky Typescript has done the same more or less with Javascript).

Re: Diminishing returns of static typing

#437

I'm converting a codebase of Javascript of about 200+ js files to Typescript today. I am about 5% complete... already found two places where the argument list was wrong and was being sent into a void. I also see the code that was making up for the fact that the third argument was being ignored (basically patching downstream because they thought the feature was broken). Now this codebase was written with a high degree…

>I'm converting a codebase of Javascript of about 200+ js files to Typescript today.

Pity you! I fear such tasks.

As mentioned,take advantage of async/await. Also, make sure you wrap everything in modules and access from outside through module exports.

Re: Diminishing returns of static typing

#438
post #96

I think what's often missing from these arguments is that statically checking (or inferring) homogenous lists is probably one of the most superficial uses of the type system in Haskell (and indeed not the interesting feature most power-users of Haskell are interested in as far as I can tell). What is interesting is using the type system to specify invariants about data structures and functions at the type level befor…

> The developer is encouraged to think of the invariants before trying to prove that their implementation satisfies them. This approach to software development asks the programmer to consider side-effects, error cases, and data transformations before committing to writing an implementation. Writing the implementation proves the invariant if the program type checks. I really wish more languages took this to the logica…

Racket took the baton from Eiffel: https://docs.racket-lang.org/guide/contract-boundaries.html

Re: Diminishing returns of static typing

#439
post #409

Earlier quoted context omitted.

It depends on your type system. In new languages like Idris or F* you can encode in the type the correctness of an algorithm and it will not compile if the compiler can not prove that correctness. For example I can prove my my string reverse works in Idris ( https://www.stackbuilders.com/news/reverse-reverse-theorem-p... ). Or I could prove that my function squares all elements in a list. Etc. Now a big part of the p…

There's no such thing as "proving correctness". You can have bugs in the type definitions. You can have bugs in the english (or whatever your native language is) description of what you think the algorithm should be doing. You can prove a program does what the types say it should do but that is not what "correctness" means. >Now a big part of the problem is expressing with sufficient accuracy what the properties of t…

[deleted]

Re: Diminishing returns of static typing

#440

Earlier quoted context omitted.

Yup, love that about statically typed languages. This happens all the time for me in C#. I have several libraries I like that do a lot of code generation. When the project is young, directly handling the generated classes works well but as the project grows, I inevitably want to wrap the handling of the generated classes. It's awesome to be like, welp... it's time to handle this one type differently. Change the retur…

I’d argue that code generation is an anti—pattern that is only necessary because of static typing. A dynamic language would let you change the implementation of all generated objects simultaneously.

Code generation is, in essence, the ultimate static construct since it allows you to compile any feature you would achieve through late binding and reflection, but with a static code path. Which in turn lets you leverage the compiler toolchain more and bring more errors towards compile time(where they're cheap to resolve).

Dynamic languages can always lean on runtime features, but that's also their peril. Late binding deprives you of leveraging the tools in favor of "trust me".

In both cases you can get a maintenance nightmare, of course. The point as I see it is to move things toward the runtime when the error case is not troublesome, and towards the compiler when automating in more safeguards would help.

Post reply on HN