Live data from Hacker News

Why static languages suffer from complexity

hirrolot.github.io

221–230 of 306 posts

Re: Why static languages suffer from complexity

#221
post #180

Earlier quoted context omitted.

In Prolog :- is the if operator.

Its use is kind of a code smell, and I believe it was a relatively (prolog is old) late addition. In any case, I wrote "doesn't need", though perhaps you consider that hair splitting.

I think you misinterpreted that. Prolog does has an if operator -> as in ( P -> If ; Else ) yes, but oldsecondhand said :-

"predicateA is true" if "clauseB is true" and "clauseC is true".

or in prolog

  predicateA :-
    clauseB,
    clauseC.
so :- is if, just in it's own, Prolog-y way.

Re: Why static languages suffer from complexity

#222

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…

Highly expressive type systems can lead people to as much design hell as does deep OOP. I have seen and experienced this in at least a couple of projects.

The only difference is: instead of brittle hierarchies, we get ossified compositions (depending on how much nominal vs structural typing happens).

We, of course, agree that we are quite some distance from having advanced type systems brought to day-to-day industrial programming.

Re: Why static languages suffer from complexity

#223

Earlier quoted context omitted.

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.

I was a mild advocate of static type systems. Then I spent about two years working on dynamic languages, mostly Python, on two jobs with otherwise very different code bases. I am now fully converted: after that experience, I strongly, strongly, strongly advocate static typing, so much that I will leave any job that requires me to use languages that lack them. I don't know if I was just unlucky, but I found that exper…

For me it all depends on the size of the project. For personal projects below a certain size dynamic typing is 50x faster than static. But that benefit drops off sharply once the project gets over a certain size or once there are more than a couple of people involved.

That's why I liked JavaScript -> TypeScript. I can bang out a prototype of some small piece in JavaScript and then add the types once I'm sure it worked. I save tons of time getting to MVP / proof of concept first and then filling in the constraints later.

Re: Why static languages suffer from complexity

#224
post #211

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…

> 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. Which is exactly what a type error is! > The Rust borrow checker is an invariant enforcer. It explicitly does automatic global analysis, and reports explicitly that what's going on at point B is inconsistent w…

Rust has affine types, and uses them extensively: types that own memory, as opposed to borrowing it, are generally affine.

In principle you could implement a form of borrow check with linear types (I don’t think affine is good enough), but the ergonomics would be horrible.

Re: Why static languages suffer from complexity

#225

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.

I’m not sure this is true. John Brant and Don Roberts did the some of the original refactoring work in Smalltalk under Ralph Johnson at UUIC.

I remember sitting with them at OOPSLA and discussing just this at length. Java was in full momentum ascendancy. Eclipse was the new will-solve-everyones-problems IDE. There was a LOT of interest in doing for typed Java in Eclipse what John and Don had both done in Smalltalk during their advanced degrees. They too thought typing would make it easier.

And what they shared with me is that it actually made it harder. Type systems are complicated to model. It gets combinatorial complex to model transformations across all the edge cases.

It may be argued that this was/is more a statement about the Java type system in particular, which is not generally extolled anyway.

But the basic take away was that refactoring becomes easier and easier as the language syntax and model gets simpler. A more complicated language like Ruby, without types, was also harder.

Or put another way… refactoring engines work with AST models. The more complicated your AST, the harder refactoring gets. I think type systems generally add, rather than remove, complexity from language models.

But perhaps there is a way to make it so. Just sharing some thoughts of yore from some guys that spent a lot of time studying refactoring.

Re: Why static languages suffer from complexity

#226

Earlier quoted context omitted.

Type systems are useful, but not nearly as useful as many people believe they are.

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

I can see this kinda. It would be interesting to experiment with how black and white this is.

Historically, most cases have been either compile time (static) or run time (dynamic) type checking. And left between one or the other, and experiences like the above, people make their binary choice.

More and more in my Python code, I do some type annotations I can. My feeling is that the annotation coverage ROI is non linear. I get a lot of mileage out of the types I can add easily. When it gets complicated (interesting unions or deep containment) it gets harder and harder. Enough so that sometimes it influences my design decisions just to make the typing job easier.

I’m left to wonder how this scales as the code base/team size scales. If the pain of 0 types is 100 in a large project, and 100% types cuts it to 10, what happens if we all do the easier 80% annotations. Is the pain 80% less too? Or is my personal experience mirrored and it actually is quite a bit better than just 80% reduction?

Re: Why static languages suffer from complexity

#227

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…

It's not a fascination, it's just easier and better to have good static analysis when programming. That doesn't have to be a type system, but I think there is a lot of reason to think that a type system is the lowest hanging fruit for useful static analyses.

Re: Why static languages suffer from complexity

#228
post #192

Earlier quoted context omitted.

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.

What you appear to be saying is that people who like type systems must be ignorant because with experience you suspect they would think differently. This seems to me to be extremely uncharitable point of view. But let's roll with it. I advocate type systems. I've also worked in several non-trivial projects in lua. Several non-trivial projects in python. Several trivial projects in common lisp. Several trivial project…

[deleted]

Re: Why static languages suffer from complexity

#229

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.

I spent about a decade pretty much solely in dynamic languages (ruby and javascript mostly) before switching to pretty much entirely working in a fairly lame statically typed language (java). Languages with static type systems are enormously, glaringly, better. Really where the benefit comes from is static analysis; it's just that languages with static type systems have better static analysis capabilities. This may not strictly be the case in theory but it definitely is in practice.

Re: Why static languages suffer from complexity

#230

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…

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.

How powerful is this, really?

As soon as you try to do anything useful to foo it's not arbitrary anymore. You have to make some kind of an assumption on the underlying type, check for keys, nulls, maybe it's a number (the right number?), maybe it's a list. So now you have to scatter some boilerplate checks everywhere you touch a part of foo.

If you could parse it into a typed structure up front, you'd only have to deal with this in one spot, and have guarantees for everything else that follows.

Bonus: if your typed language has good support for records, you can even do this in a way that only provides structure to the parts you care about, and is robust to changes to any other parts of the json.

Post reply on HN