Live data from Hacker News

Why static languages suffer from complexity

hirrolot.github.io

181–190 of 306 posts

Re: Why static languages suffer from complexity

#181
post #146

Earlier quoted context omitted.

Hmm, how well does this scale though? you are passing around these giant maps of vectors of tuples and then you pass it to someone unfamiliar with the code, how the hell do they know what's in there? Is the order price the first element of the tuple or the second? What happens when I refactor things and now all the tuple elements shift over one? Surely you'll end up writing just as much in documentation as you would…

If your data is not position-dependent a tuple doesn’t sound like the correct choice. In the price example you provided, a map would be much better. As for how you know what’s in there - you should only know whether what’s relevant to your function is in there and not care about the rest of the world. For the former, tools like clojure.spec are helpful but ultimately good design helps the most (something that typed l…

> If your data is not position-dependent a tuple doesn’t sound like the correct choice.

That's kind of the problem though. Software is written by humans, and humans are fallible. We don't always make the correct choices. Also, there are economic pressures, deficiencies in specification, and changes in business requirements.

Personally, I believe businesses should accept the aforementioned reality and optimise for cost of change.

Re: Why static languages suffer from complexity

#182
post #170

Earlier quoted context omitted.

You’re putting structural types in the same boat as dynamic types, which I don’t think is fair. Some of the most popular static type systems out there have structural typing, including Go (as you mentioned) and TypeScript. And that’s not even getting into languages that do extensive type-inference, including TypeScript Haskell and ReScript (which also saves you from locking into over-broad contracts).

One works with the type system they have, not the one they want. Out of the top 20 most popular languages according to Stack Overflow [0], TypeScript and Go are the only statically-typed languages that also have structural types support. [0] https://insights.stackoverflow.com/survey/2021#technology-mo...

[deleted]

Re: Why static languages suffer from complexity

#183

This article spends many words to say, “there is no silver bullet”. But dynamically typed languages produce at least the same amount of accidental complexity, just in different ways.

Indeed, the article has it backwards. The types are always there. Your program will fail at runtime if it's not correct. The type system merely surfaced that. Complexity in the types happens when the type system isn't expressive enough. Or when you're trying to do something that would make the compiler try to solve the halting problem. To that last point, this is why the PLT community has pushed in the direction that…

> Kind of like how we realized years (decades?) ago that we didn't need pointer arithmetic

who's "we" here? pointer arithmetic is useful for all kinds of things.

Re: Why static languages suffer from complexity

#184
post #149

The problem I find with static typing is that it so easily leads you over-specifying the requirements / constraints. In fact, it makes such a virtue out of that over-specification that many people would consider it a best practice to do so. For example, perhaps my `calculate_price` function only depends on 2 attributes of the order which has 65 attributes. Am I creating a 2-element data type for that function to proc…

In addition to what others have said about just passing two parameters, there also row types, where the signature of `calculate_price` can be specified to accept any record that has the two required fields.

Re: Why static languages suffer from complexity

#185

Earlier quoted context omitted.

Try working in a big system without them =P I think they are invaluable

They are especially useful when refactoring, or as a documentation tool. However, without a type checker, choosing your names wisely will get you a long way. I think anyone advocating type systems should spend a year working in a dynamic language, to get out of their echo chamber and form a more objective opinion.

The average user of Haskell, Rust, or ML today has certainly spent sufficient time in the Python/JS/Tcl/what have you mines.

The opposite is much less likely to be true; at best they may have done a project or two in Java or started migrating to TypeScript.

(Please also keep in mind: The average ML user probably reads, or intentionally avoids, HN. The average JS user doesn’t know it exists.)

Re: Why static languages suffer from complexity

#186
post #67

Earlier quoted context omitted.

> 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. People who just learn programming probably think the same about whatever language they are learning. > No typing system can tell you that you wrote > when you should have written The more the compiler can figure out for you, the quicker problems ca…

FWIW, sqlite now has 'strict' tables.

Thanks! I still like sqlite a lot and plan to use it again someday, so I will be happy knowing that in advance.

Re: Why static languages suffer from complexity

#187

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…

> Fascination with type systems does not seem to be all that useful in practice. And yet type theory is an excellent way to express all kinds of invariants. The more rich the type system the more you can express. If you get to dependent types you essentially have all of mathematics at your disposal. This is the basis of some of the most advance proof automation available. What is super cool is that proofs are program…

> The more rich the type system the more you can express

Why is this interesting? You pay an extremely heavy price in terms of language complexity. In practise, you almost never have the invarants at all or correct when you begin programming, and your programs evolve very rapidly. Since with dependent types you loose type-inference, you now what to evolve two programs rather than one. Moreover proofs are non-compositional: you make a tiny change somewhere and you might have to change all proofs. In addition we don't have full dependent types for any advanced programming language features, we have them only for pure functions that terminate.

> the same language to prove theorems about them

That sounds like a disadvantage. Ultimately verification is about comparing two 'implementations' against each other (in a very general sense of implementations where logical specs and tests also count as implementations). And the more similar the two implementations, the more likely you are to make the same mistake in both. After all, your specification is just as likely to be buggy as your implementation code.

> type systems suffer from complexity.

This is clearly false for just about any reasonable notion of complexity. For a start pretty much as soon as you go beyond let-polymorphism in terms of typing system expressivity, you looks type-inference. Even type-checking can easily become undecidable when the ambient typing system is too expressive.

There is no free lunch.

Re: Why static languages suffer from complexity

#188

FWIW, I've been developing code directly in MLIR recently, and in MLIR "Comparing types is cool" is indeed true. It's amazing what you can do when you have compiler transformations and targets always available. Suddenly, "little DSLs" (MLIR dialects) don't seem so bad, since they are defined the same way and map in semantically-sound ways to lower-level dialects. You can have dedicated dialects, like Halide, for doin…

Can I pick your brain on MLIR? It sounds awesome from what you describe, but I want to know more about whether it's specialized to machine learning types of workloads or whether it's good for more general things.

Well, we're using it for business automation. We have automated agents that are selectively override-able by humans on an as-needed basis (e.g. a case we don't currently handle, or because of a runtime error).

Also, most of our code needs to support suspend/resume on another machine, either in the middle of an action or more often between actions. So, a "behavior" might begin on machine A and then migrate to machine B to do more work, then on to machine C. While doing work, its execution state might be serialized to Postgres while some dependency is waited on—say, a human task that doesn't get done until the following Monday. It's then resumed in the same execution state, potentially on an entirely different worker/machine, and continues executing.

The suspend/resume stuff completely destroys the code if you're writing it by hand, as does moving from machine to machine.

So we write the core logic in our own internal MLIR dialect and then output code that has the suspend/resume semantics automatically (i.e. literal compiler transformations, plus our own "interpreter" (which is just JavaScript/v8 with all of the extra suspend/resume cruft added in).

We don't translate out of SSA form at all, our codegen can execute it directly. We also insert debug hooks so when there's an error, you can map the execution state to the original code.

Most of the cool machine learning stuff MLIR can do, we're not even doing yet outside of some internal prototypes. So far, just the methodology of MLIR has made a huge impact—it gives really nice structure (read: tooling) for the kinds of code transforms we've needed to do.

HTH

Re: Why static languages suffer from complexity

#189
post #155
post #110

Earlier quoted context omitted.

PEP 257, and local conventions in certain projects. What all comes down to is: if you really have people on your project writing code like the foo/bar/baz example way up above - then you have problems way bigger than static type checks can possibly help you with.

Wouldn't it be something if there existed tooling that enforced this level of discipline and checked its validity before executing any code such that you didn't rely on the entire ecosystem to adhere to the same standards and remove that as a source of ambiguity...

Which Python has had since 3.5.

Re: Why static languages suffer from complexity

#190
post #120

Earlier quoted context omitted.

> 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.

Nit: they're adding Generics in 1.18 (not 1.8). Regarding "another 5 years": I'm not so sure. Go is very conservative about language changes. The type system didn't change at all from version 1.0 through version 1.17 (a 12-year period).

Some changes to nil accesses were made in 1.3. Tags were ignored in casts since 1.8. Overlapping methods were allowed in 1.14. New array pointer casts were added in 1.17. (Arguably, also type aliases in 1.9.)

None of these are as significant as generics, but things do change.

Post reply on HN