Live data from Hacker News

Dynamic type systems are not inherently more open

lexi-lambda.github.io

201–210 of 286 posts

Re: Dynamic type systems are not inherently more open

#201
post #189
post #90

Six notable things I took away from this post: - Structural typing, i.e. instead of "you eagerly write a schema for the whole universe", just limit to what you need (basically, encode only the same kinds of assumptions you would make in a dynamically-typed language). - It’s easy to discover the assumptions of the Haskell program [...] In the dynamically-typed program, we’d have to audit every code path — Left implici…

I thought the article was good and addressed a real point of confusion, as evidenced by the two included comments (from Reddit and HN). You can consume arbitrary data using a program written in a statically typed or dynamically typed language. Whether it's decoupled from changes in the data depends on how the code is written and the data model, which have nothing to do with static vs dynamic typing. To me the stronge…

I think it's a question of efficacy and productivity. People routinely make mistakes using type systems. While static typing tends to be really good at solving problems it itself introduces (change a type and, wow! My IDE knows where that type is everywhere and can change it for me! Nevermind that only the producer and final receiver should care, it's everywhere now...)

There hasn't been a lot of study on this topic* but what little there is shows that 3% of errors found can be mitigated with type systems, where they do not exist, fixing these classes of errors takes less time than it took to use the type system.

* https://www.infoq.com/presentations/dynamic-static-typing/

Re: Dynamic type systems are not inherently more open

#202
post #97

The author doesn’t really address the issue raised in the first (longer) quoted post. Given a set of reasonable requirements I think pretty much no one would claim a general-purpose language couldn’t satisfy them without too much trouble. In fact, that might be a fair definition of a general-purpose language. I’m fine with strong and expressive static type-checking, but you need to hold the main limitation in mind as…

I think it's absolutely addressed. With either a dynamic or static language, you have to make decisions about which fields are essential, whether you can ignore additional fields, etc. And this post shows how you can do that in Haskell. Versioning is hard, because it's a coordination problem, but it's not the type system that produces the pain.

> And this post shows how you can do that in Haskell.

the actual critique of the first post wasn't really that Haskell can't do it in a literal sense, but that ignoring or reasoning about unknowns diminishes the advantages of static typing.

Sure, you can define an "unknown" type if you want and make your static language as permissive as possible, but then you lose the actual static guarantees, which is automating reasoning about the correctness and capacities of your program at compile time.

The question then is if you're already conceding that there are so many unknowns which better ought to be dealt with at runtime, what is there to be gained from making that explicit in your program other than just having to write more code?

Re: Dynamic type systems are not inherently more open

#203
post #151

This have a mirror with the "sql"/"nosql" debate. Being "schemaless" is supposedly a great advantage of nosql, but the thing is that sql/relational is as schemaless as you want! The only thing is that rdbms push to create a static modeling of the FINAL STORAGE that is close to be the ideal of it. But anyway, you can create/delete/change tables as you wish (is not impossible to see dbs withs 100/200 tables), and SQL i…

>Where is truly weak is that not extend the relational model to INNER values (so you can't "SELECT (SELECT chars FROM name)) but is a limitation of sql, not the relational model.

True, but fortunately most database systems have proprietary ways to achieve some of that. For instance in PostgreSQL

  select * from regexp_split_to_table('abc', '') chars;
gives you

   chars 
  -------
   a
   b
   c
It's called table-valued functions and it's extensible. Obviously, it's not quite as general as what you are talking about because the values are not actually stored as tables. To get a bit closer to that you could use composite types and arrays. I'm not convinced it's worth the added complexity though.

Re: Dynamic type systems are not inherently more open

#204
post #96

Earlier quoted context omitted.

Productivity can be really subjective. Those that are used to modeling the problem domain with the type system find that their most productive approach, even with prototyping.

Right, and the type system is such a big help in refactoring - especially in small projects - that you don't have to be all that right in your first N cuts at the model. You can write code and find out where you're wrong, and fix it fast.

It’s even more help in larger projects :) The dividends of type-checher aid refactoring really start paying off once the project is above a a certain size/age.

Re: Dynamic type systems are not inherently more open

#206
post #189
post #90

Six notable things I took away from this post: - Structural typing, i.e. instead of "you eagerly write a schema for the whole universe", just limit to what you need (basically, encode only the same kinds of assumptions you would make in a dynamically-typed language). - It’s easy to discover the assumptions of the Haskell program [...] In the dynamically-typed program, we’d have to audit every code path — Left implici…

I thought the article was good and addressed a real point of confusion, as evidenced by the two included comments (from Reddit and HN). You can consume arbitrary data using a program written in a statically typed or dynamically typed language. Whether it's decoupled from changes in the data depends on how the code is written and the data model, which have nothing to do with static vs dynamic typing. To me the stronge…

> If systems that extend beyond a single program require dynamic typing, doesn't it make sense to invest more in ways to do dynamic typing better?

Isn’t dynamic typing more or less a default state of not knowing anything at compile time about the values your data will take?

One could equally well ask “given that the boundaries of our systems are necessarily characterized by unpredictability, doesn’t it make sense to invest in more ways to isolate that unpredictability better (e.g. by use of static analysis)?”

Re: Dynamic type systems are not inherently more open

#207

Dynamic type systems are inherently more open. This article really bends over in strange ways to say otherwise. Fact is: dynamic typing is all about making fewer claims in your code about what you expect about the world around you. With dynamic types, to load a property you might just have to say the property name and receiver. With static types, you usually also have to say the type of all other properties of the re…

I think the author is offering "you can’t process what you don’t know" as an example of something that dynamic proponents claim that statically-typed languages can't do, followed by a refutation of it.

Re: Dynamic type systems are not inherently more open

#208
post #189

Earlier quoted context omitted.

I thought the article was good and addressed a real point of confusion, as evidenced by the two included comments (from Reddit and HN). You can consume arbitrary data using a program written in a statically typed or dynamically typed language. Whether it's decoupled from changes in the data depends on how the code is written and the data model, which have nothing to do with static vs dynamic typing. To me the stronge…

I think it's a question of efficacy and productivity. People routinely make mistakes using type systems. While static typing tends to be really good at solving problems it itself introduces (change a type and, wow! My IDE knows where that type is everywhere and can change it for me! Nevermind that only the producer and final receiver should care, it's everywhere now...) There hasn't been a lot of study on this topic*…

> There hasn't been a lot of study on this topic* but what little there is shows that 3% of errors found can be mitigated with type systems, where they do not exist, fixing these classes of errors takes less time than it took to use the type system.

It seems to me like you're cherry picking evidence. Copy-pasting from a previous comment I made in another thread (https://news.ycombinator.com/item?id=19530274):

There is plenty of evidence showing that modern type systems reduce bugs considerably.

In Airbnb, they found out that 38% (!) of bugs could have been prevented by using TypeScript[1].

Another scientific study discovered that TypeScript and Flow could prevent about 15% of bugs in committed code [2]. And these aren't even measuring reduction of bugs in non-committed code!

Stripe is also writing their own type checker for Ruby and engineers have reported an increase in productivity[3].

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

[2]: https://blog.acolyer.org/2017/09/19/to-type-or-not-to-type-q....

[3]: https://sorbet.run/talks/StrangeLoop2018/#/

Re: Dynamic type systems are not inherently more open

#209

Earlier quoted context omitted.

Using Type inference[1] on a language could be able to figure out types in most situations. [1] https://en.wikipedia.org/wiki/Type_inference

Yes, but "Type inference has usability problems". http://web.eecs.utk.edu/~azh/blog/typeinference.html

In practice, not really. A good type inference system like Hindley-Milner infers the most general type of any expression you give it. This usually makes your code more polymorphic i.e. generic than if you would have manually written down the types.

You talk about cognitive load of looking up type info but there's also a cognitive load to having to parse every type annotation over and over again whenever you read the code. And since code is read more often than it's written, that's really just optimizing for the wrong load. As you re-read a codebase over time you'll get familiar with its types. And then the annotations start to get in the way. This is in fact one of the reasons people prefer dynamic typing.

> My response? Go refactor your hideous code.

To what? Would be very interesting to see your suggested refactor of that code.

> Before every language designer blindly accepts type inference as a good thing, I propose that some research be conducted.

What would be the research question(s) specifically?

Re: Dynamic type systems are not inherently more open

#210

Earlier quoted context omitted.

I think at that point you probably need a major refactor, regardless of the language being used. While I don't want to be in that situation, I'll typically use a helper class if I'm forced to pass something through 13 layers (a class containing all the arguments). However, that's pretty much the textbook example for designing with dependency injection in mind. Static typing won't fix a terrible architecture.

I haven't read that textbook. Do you have a good reference. I may have been intentionally been using an anti pattern. I often have a POD class that gets passed down a processing chain.

YMMV. There's probably at least one good use case for virtually every design. What you're doing could be totally reasonable.

The original description sounded like 13 functions being manually chained together, each inside the last. Where to go from there is very situational.

Using a POC is pretty much a given.

For transformation in the simplest form, I'd typically have a series of extension methods (or some equivalent, like a transformation class which only has methods and holds a reference to the object) which can be called to transform and return the object or return a modified copy of the object. That's easier to test and debug as each method doesn't need to know about the one above/below it (they get called in parallel). You can also easily modify the order of the transformation, or cut out parts of it. When testing/debugging, you just initialize data to some state, then test the broken piece of the pipeline.

If the 13 vertical calls are for initialization, DI allows you to turn that into 0 calls. You probably need reflection in your language to make DI work though. I've never liked DI frameworks built by others, and have generally made my own.

All that said, I'd stand by my point that if 1 item is passed vertically through 13 functions before it gets used, then there's probably some way to either make things a bit more horizontal, or to automate the passing.

Another strong belief: If DI or some other "good" design tool results in more lines of code or significantly more confusing code, then either it's being done wrong, or it isn't applicable to the situation. There are generally more wrong places to use a tool or pattern than there are right places to use them. A power drill is a terrible hammer.

Post reply on HN