Live data from Hacker News

Why static languages suffer from complexity

hirrolot.github.io

131–140 of 306 posts

Re: Why static languages suffer from complexity

#131
post #85
post #44

Earlier quoted context omitted.

What the heck is 'bar' and 'baz'? So there's no docstring? And the actual variables are that random and indecipherable? Sounds like the problem is that you're tasked with looking at code written by someone who is either inexperienced or fundamentally careless. When dealing with reasonably maintained codebases, this kind of situation would seem pretty rare. In modern python we now have type hints of course, which have…

In other words, in Python you have to rely on your colleagues manually writing documentation, and if they don't you're out of luck and they're 'bad developers' and potentially the whole product is affected. In static languages this simply isn't a problem. Types are checked for consistency at compile time and you don't have to rely on people toiling on this busy work. Not to say documentation isn't necessary, or good,…

No, actually I advocate static typing approaches for precisely the reasons you give. As does Python, since years and years ago.

I'm just saying that core problem it solves -- "bad developers" -- is going bite you no matter what (if not addressed at the source). And that supposed magical efficacy of measures designed to protect against it is somewhat overstated.

Re: Why static languages suffer from complexity

#132
post #73

This entire article can be summarised as "compile time stuff should use the same language as run time". I guess the author just hasn't encountered Nim before, where anything becomes compile time by just assigning to a const, and macros have access to the real AST without substitution. Macros also allow compile time type inspection, as they are a first class citizen rather than tacked on. The compile time print, AFAIC…

> This entire article can be summarised as "compile time stuff should use the same language as run time". I think the message is more nuanced than that (otherwise wouldn't lisp with its homoiconicity and compile time macros fit the bill perfectly?). Idris uses the same language, but is still too complex. And Zig not general purpose enough. I don't want to put words in the author's mouth but I think the implication is…

+1

Re: Why static languages suffer from complexity

#133

"Why not add X feature? If people don't want to use X, they just don't, and there are basically 0 downsides." In theory this is true. If the compiler is decent, compile times and analysis shouldn't really be affected. Maybe libraries will use X but otherwise they would use a manual implementation of X anyways. But in practice developers misuse features, so adding a feature actually leads to worse code. It also create…

> But in practice developers misuse features, so adding a feature actually leads to worse code.

I have found the opposite to be true. Missing features often leads to what one would call "design patterns". When the language adds official support to solve the problem you're trying to solve with that pattern, the code becomes clearer.

Re: Why static languages suffer from complexity

#134
post #117

Earlier quoted context omitted.

A problem but not a huge one in practice. And you're neglecting the part of my statement you conveniently truncated.

> not a huge one in practice. Our experiences have been wildly different :)

Yeah, life sometimes gets that way.

Re: Why static languages suffer from complexity

#135
post #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.

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

Re: Why static languages suffer from complexity

#136
post #85
post #44

Earlier quoted context omitted.

What the heck is 'bar' and 'baz'? So there's no docstring? And the actual variables are that random and indecipherable? Sounds like the problem is that you're tasked with looking at code written by someone who is either inexperienced or fundamentally careless. When dealing with reasonably maintained codebases, this kind of situation would seem pretty rare. In modern python we now have type hints of course, which have…

In other words, in Python you have to rely on your colleagues manually writing documentation, and if they don't you're out of luck and they're 'bad developers' and potentially the whole product is affected. In static languages this simply isn't a problem. Types are checked for consistency at compile time and you don't have to rely on people toiling on this busy work. Not to say documentation isn't necessary, or good,…

What I've found is even worse: on medium-size personal projects I inevitably pass the wrong type to a function (or refactor and forget to change a call somewhere). Generally it does not fail until somewhere else, which relies on it being a certain type. So even though I know what my functions should take, I still spend a bunch of time tracking down the problems, which involves a printing out a lot of stuff because the error happened outside the current call stack. This is something a static type system would just prevent for me, and I've basically decided that anything beyond really simple stuff is actually faster for me to write in a statically typed language. (Examples in the past are a parser for a static site generator with a mostly Turing-complete language, and 3D model generators)

Re: Why static languages suffer from complexity

#137

Earlier quoted context omitted.

When that JSON payload changes (intentionally or not), you will run into a mysterious problem in some unrelated area of your code. It will be significantly more expensive to fix than failing fast at the point of parsing.

But depending on the situation, that problem may never happen. I'm not a big fan of introducing complexity to guard against code screwups in the same codebase.

[deleted]

Re: Why static languages suffer from complexity

#138

Earlier quoted context omitted.

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…

The way that the value floats through the system is checked statically, and the program can (and should) be designed so that the value with the appropriate type cannot be constructed unsafely. If you need to statically check the construction of values in Haskell, there are things like refinement types[0]. [0]: http://nikita-volkov.github.io/refined/

> The way that the value floats through the system is checked statically, and the program can (and should) be designed so that the value with the appropriate type cannot be constructed unsafely.

Except that in the first example from the first link you sent me, there is no static guarantee that the inputs to the constructor are valid, thus the error branch (it would be unnecessary if static guarantees could be made regarding the use of the constructor). And that was my point, that you still end up with dynamic checks on the values which is where pre/post conditions step in to cover what static typing cannot (or, again, cannot easily in mainstream languages, which would not be Haskell).

Re: Why static languages suffer from complexity

#139
post #73

This entire article can be summarised as "compile time stuff should use the same language as run time". I guess the author just hasn't encountered Nim before, where anything becomes compile time by just assigning to a const, and macros have access to the real AST without substitution. Macros also allow compile time type inspection, as they are a first class citizen rather than tacked on. The compile time print, AFAIC…

> This entire article can be summarised as "compile time stuff should use the same language as run time". I think the message is more nuanced than that (otherwise wouldn't lisp with its homoiconicity and compile time macros fit the bill perfectly?). Idris uses the same language, but is still too complex. And Zig not general purpose enough. I don't want to put words in the author's mouth but I think the implication is…

> I think the message is more nuanced

I thought it was more nuanced too as they were explaining how integer types can be derived, until I finished the article, and they really did just seem to be complaining that there's a mismatch between compile time and run time.

Dynamic types don't really solve the problems they mention as far as I can tell either (perhaps I am misunderstanding), they just don't provide any guarantees at all and so "work" in the loosest sense.

> otherwise wouldn't lisp with its homoiconicity and compile time macros fit the bill perfectly?

That's a good point, I do wonder why they didn't mention Lisp at all.

> we don't have a solution yet

What they want to do with print can, as far as I can see, be implemented in Nim easily in a standard, imperative form, without any declarative shenanigans. Indeed, it is implemented as part of the stdlib here: https://github.com/nim-lang/Nim/blob/ce44cf03cc4a78741c423b2...

Of course, that implementation is more complex than the one in the article because it handles a lot more (e.g., formatting and so on).

At the end of the day, it's really a capability mismatch at the language level and the author even states this:

> Programming languages ought to be rethought.

I'd argue that Nim has been 'rethought' specifically to address the issues they mention. The language was built with extension in mind, and whilst the author states that macros are a bad thing, I get the impression this is because most languages implement them as tacked on substitution mechanisms (C/C++/Rust/D), and/or are declarative rather than "simple" imperative processes. IMHO, most people want to write general code for compile time work (like Zig), not learn a new sub-language. The author states this as well.

Nim has a VM for running the language at compile time so you can do whatever you want, including the recursive type decomposition (this lib isn't implementing Peano arithmetic but multiprecision stack based bignums): https://github.com/status-im/nim-stint and specifically here: https://github.com/status-im/nim-stint/blob/ddfa6c608a6c2a84...

    func zero*[bits: static[int]](T: typedesc[Stuint[bits] or Stint[bits]]): T {.inline.} =
      ## Returns the zero of the input type
      discard

    func one*[bits: static[int]](T: typedesc[Stuint[bits]]): T {.inline.} =
      ## Returns the one of the input type
      result.data = one(type result.data)
It also has 'real' macros that aren't substitutions but work on the core AST directly, can inspect types at compile time, and is a system language but also high level. It seems to solve their problems, but of course, they simply might not have used or even heard of it.

Re: Why static languages suffer from complexity

#140

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. > ... > The Rust borrow checker is an invariant enforcer. [...] This is real progress in programming language design, and is Rust's main contribution. I'm so confused by your stance here. You essentially say "type systems are not useful" and then "oh but this most recent advance in type systems — that one is useful." Do you find type sys…

I'm so confused by your stance here. You essentially say "type systems are not useful" and then "oh but this most recent advance in type systems — that one is useful." Do you find type systems useful or not?

Not the original author but it seems like they're saying that type-systems are non-specific invariant enforcers and so have costs without necessarily having benefits whereas a user-specifiable invariant enforcer is more guaranteed to have the benefits.

Post reply on HN