Live data from Hacker News

Why static languages suffer from complexity

hirrolot.github.io

111–120 of 306 posts

Re: Why static languages suffer from complexity

#111
post #37

Earlier quoted context omitted.

Yup, I find this completely insane behavior to think that you somehow benefit from types not being there. You just make it way harder for people to understand your code and contribute to it.

Oh yeah the easiest code in the world to read is some contorted type system and function signatures that look like hieroglyphics that you need a PHd in CS to comprehend. Python is easy to grok, and if you have programmers writing code like bar(foo,baz) then the problem is not Python. You can write crap in any language. Unit tests do much of what typing checks anyway ... and here's the thing ... you NEED unit tests no…

> Oh yeah the easiest code in the world to read is some contorted type system and function signatures that look like hieroglyphics that you need a PHd in CS to comprehend.

You can also make a book easier to read by ripping out all its pages.

If you eliminate the content you need to read to understand something, what have you actually made easier?

> No typing system can tell you that you wrote > when you should have written There are many that can; e.g. via SMT-decidable refinement types, or even full undecidable dependent types coupled with automated solvers and manual proofs.

Re: Why static languages suffer from complexity

#112
post #107
post #88

Earlier quoted context omitted.

They're probably laughing because a) you're suggesting manually doing the work static typing does in a dynamic language because its untenable not to for large projects, and b) you can't easily add type hints to other people's libraries.

No - (a) is not what I'm suggesting. And (b) while disappointing, just doesn't slow one's work down very frequently in daily practice. Look, I just don't buy the suggestion that static typing magically solves a huge set of problems (or that it does so without imposing negative tradeoffs of its own -- the very topic of the original article). Or that dynamic languages are plainly crippled, and that one has to be a kind…

> I just don't buy the suggestion that static typing magically solves a huge set of problems

  // compiles and runs, but does bad things
  function foo(x, y) {
    someDangerousEffect();
    return x + y;
  }

  -- does not compile; huge sets of problems magically solved
  foo :: Int -> Int -> Int
  foo x y = someDangerousEffect >> pure $ x + y

Re: Why static languages suffer from complexity

#113

Fascination with type systems does not seem to be all that useful in practice. Go has a minimal type system, and is able to do much of Google's internal server side work. Most of the problems that cause non-trivial bugs come from invariant violations. At point A, there's some assumption, and way over there at point B, that assumption is violated. That's an invariant violation. Type systems prevent some invariant viol…

> Go has a minimal type system, and is able to do much of Google's internal server side work.

Isn't it stil mostly Java and C++? That's what I hear all the time here.

Also, I'm not sure what point you're trying to make. You start by saying that fascination with types systems is not useful in practice, and end with an example where it is useful (Rust). While Go can stick a GC to avoid most of the issues that Rust is trying to solve, it stil has to ship with a defer mechanism (no linear/affine types/RAII) and a data race detector.

Re: Why static languages suffer from complexity

#114

Earlier quoted context omitted.

The real power of dynamic languages is being able to do: const foo = JSON.parse(arbitraryJsonString); and not having to worry about the structure up front.

In C# I can just parse it to a Dictionary , and I can do that without destroying the usability of the rest of the language.

What if the JSON represents a list, or an int?

Also, how do you then access nested objects, like data['key'][0]['attr'] in Python?

Re: Why static languages suffer from complexity

#115

Having used Clojure for a while now, I will say having 90% of things be a primitive, map, or vector goes a long way in and of itself. A lot of types concocted in a more conventional language just don't need to exist, IMO, and they create so much baggage around themselves.

You know what they say about people with hammers.

Re: Why static languages suffer from complexity

#116

Earlier quoted context omitted.

That's the theory. Works great when there are no bugs and everything's been designed just right. In that world you could wipe implementations from memory because you won't ever need to dive in.. Very often I'm looking at code and "how to use the interface" is not a question I'm looking to find answers for.

Some information is a lot better than none. In some cases you might want to know what implements the interface: that information is also statically available. In Rust, you can look at a trait and see what types implement that trait. If you need to know exactly which implementation is being used in a particular context then maybe you shouldn't be using an interface, but should be using the concrete type?

> If you need to know exactly which implementation is being used in a particular context then maybe you shouldn't be using an interface, but should be using the concrete type?

Look again at the original comment by dandotway. It's not a question of "what type should I be using here", nor is it "how should I use this interface", but "what do I need to do to understand this code?". Even if an abstract interface is used correctly and is the right thing to do, you still need to understand the code before you can (debug|rewrite|extend|whatever) it.

And it's a pipe dream to say you can look just at the interface. Something blows up, is it the interface used wrong? Maybe, maybe not? Is it the interface implemented wrong? Maybe, first you need to know what implementation you're looking at. Subtle interactions between abstract and concrete send you spelunking through the layers when you're debugging or trying to extend the interface to account for something the original author didn't anticipate, and often the devil (in the details) comes from concrete implementations.

Re: Why static languages suffer from complexity

#117
post #107

Earlier quoted context omitted.

No - (a) is not what I'm suggesting. And (b) while disappointing, just doesn't slow one's work down very frequently in daily practice. Look, I just don't buy the suggestion that static typing magically solves a huge set of problems (or that it does so without imposing negative tradeoffs of its own -- the very topic of the original article). Or that dynamic languages are plainly crippled, and that one has to be a kind…

> I just don't buy the suggestion that static typing magically solves a huge set of problems // compiles and runs, but does bad things function foo(x, y) { someDangerousEffect(); return x + y; } -- does not compile; huge sets of problems magically solved foo :: Int -> Int -> Int foo x y = someDangerousEffect >> pure $ x + y

A problem but not a huge one in practice.

And you're neglecting the part of my statement you conveniently truncated.

Re: Why static languages suffer from complexity

#118

Earlier quoted context omitted.

Pre/post conditions are complementary to a type system. They can ensure logical properties that may not be encodable in your underlying type system (that is, essentially every mainstream statically typed language). Such as the relationship between two values in a collection. Trivial example, if you have a range such as [x,y] where x < y must hold, how would you convey that in any mainstream type system?

The Haskell-y way to do this is to use a smart constructor[0]. [0]: https://wiki.haskell.org/Smart_constructors

The first part of that page demonstrates what amounts to pre/post conditions, but placed in the constructor. The range is checked dynamically, not statically.

The second part is using Peano numbers to enforce the constraint. I guess you could try and force that into some mainstream languages, probably C++. With its template programming you could get something going in this vein, though I'm not sure how well it would work if the number were calculated at runtime rather than compile time. You'd still end up with a dynamic check somewhere.

Re: Why static languages suffer from complexity

#119
post #74

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

Indeed. An interesting reading is https://lexi-lambda.github.io/blog/2020/01/19/no-dynamic-typ...

This is one of my favourite blog posts on the Internet and I implore every programmer to read it.

> The claim is simple: in a static type system, you must declare the shape of data ahead of time, but in a dynamic type system, the type can be, well, dynamic! It sounds self-evident, so much so that Rich Hickey has practically built a speaking career upon its emotional appeal. The only problem is it isn’t true.

Re: Why static languages suffer from complexity

#120

Fascination with type systems does not seem to be all that useful in practice. Go has a minimal type system, and is able to do much of Google's internal server side work. Most of the problems that cause non-trivial bugs come from invariant violations. At point A, there's some assumption, and way over there at point B, that assumption is violated. That's an invariant violation. Type systems prevent some invariant viol…

> Go has a minimal type system, and is able to do much of Google's internal server side work.

And yet Go is adding generics in 1.8. And I'm sure its type system in another 5 years will be much more expressive than 1.8's. The community has long been saying that the minimal type system isn't enough.

Post reply on HN