Live data from Hacker News

Why static languages suffer from complexity

hirrolot.github.io

271–280 of 306 posts

Re: Why static languages suffer from complexity

#271

Earlier quoted context omitted.

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 line…

> either compile time (static) or run time (dynamic) type checking

But it is not that black and white, is it? Python is actually somewhat static in that it checks (some) types during runtime. Other dynamically typed languages live completely by the "when it quacks like a duck" playbook.

On the other hand, Haskell is completely statically typed. Still you can write many programs without annotating any types at all, as the compiler is pretty good at inferring types from their context.

Re: Why static languages suffer from complexity

#272

Earlier quoted context omitted.

Expressiveness is not an unambiguous net good -- more expressiveness is not a priori better. Expressiveness carries costs of comprehension and coherence that need to be appropriately weighed in the contexts where the language will be applied. Programming languages are not theoretical things. They're concrete, practical tools that _enable_ other stuff. Engineering, not science.

How would you define expressiveness (as its commonly used, so a definition where Turing complete languages can have different expressiveness) if not as how much something can be simplified and thus aiding comprehension, rather than detracting from it? >Programming languages are not theoretical things. They're concrete, practical tools that _enable_ other stuff. Engineering, not science. You can't escape theory, engin…

I'm not the person you replied to, but here's an analogy: it's easier to learn how to drive a car with an automatic transmission than a manual one, even though the latter is "more expressive".

Re: Why static languages suffer from complexity

#273

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…

It is probably pretty presumptuous to assume, but I think that a lot of programmers that have only every been exposed to C/C++/C#, Java and Python have basically no concept of what a good type system can do for them.

Two examples from the top of my head:

1. Encoding matrix sizes into the data- and function-types, so that you can safely have a function `mat[c,b] mat_mult(mat[a,b] a, mat[c,d] b)` or even `mat[w-2,h-2] convolve(mat[w,h] input, mat[3,3] kernel)` and have the compiler check that you never use a matrix of the wrong size.

2. Actually checking the correctness of your implementation.

There is a very nice online demo of Liquid Haskell [1], where they defined the properties of ordered lists (each element has to be smaller or equal to the one before, line 119). Then they define a function that takes an (unordered) list and spits out a ordered one by applying a simple quicksort.

Now, if you break the algorithm (e.g. flip the Pretty neat.

edit: I just realized that LiquidHaskell is almost 10 years old. Sad to see that basically nothing made it into "production".

[1] http://goto.ucsd.edu:8090/index.html#?demo=Order.hs

Re: Why static languages suffer from complexity

#274

Earlier quoted context omitted.

How would you define expressiveness (as its commonly used, so a definition where Turing complete languages can have different expressiveness) if not as how much something can be simplified and thus aiding comprehension, rather than detracting from it? >Programming languages are not theoretical things. They're concrete, practical tools that _enable_ other stuff. Engineering, not science. You can't escape theory, engin…

I'm not the person you replied to, but here's an analogy: it's easier to learn how to drive a car with an automatic transmission than a manual one, even though the latter is "more expressive".

Heh, I would actually consider automatic transmission to be the more expressive one, since to me expressive means how easy it is to express something. Analogously e.g. C++ (manual) is more efficient and allows finer control, but makes it harder to express the same thing as in a 'higher level' (automatic) language.

Otherwise, since Assembly provides the most control out of all, would you consider it the most expressive? ;-)

Re: Why static languages suffer from complexity

#275

Earlier quoted context omitted.

Is there any reason you didn't address the second link that I shared?

Mostly because, per my reading (as an admitted Haskell dabbler and not fluent), it looks like a variation on a theme rather than a totally different thing. It seems to be a more consistent and refined (har har) way of doing the same thing as the first link, and still has a dynamic check (at least in one form, refine vs refineTH ) just like the smart constructors. But also because we got derailed from my initial point…

Sorry, I should have been clearer. I was referring to the Template Haskell part of that refinement types library, where the construction of values can indeed be statically checked at compile time.

> > Pre/post conditions are complementary to a type system.

> Do you disagree or agree with this statement? Because you never addressed it either.

I agree with it. I write web applications in Haskell for a living, and the very nature of web applications is that most values coming into the system are not known until runtime. It is not a reasonable design goal to want every possible value in the system to be verified at compile time. However, it is valuable to be able to statically verify the relationships between functions and values as those values — once they have been parsed at runtime into a more principled type — move through the system.

Re: Why static languages suffer from complexity

#276
post #268

Earlier quoted context omitted.

Common Lisp has a type system, if I understood your meaning right.

Common lisp is dynamically typed. There are type hints that you can give the compiler, but I believe that's only useful for generating faster assembly. Also you can get compile time warnings from macros, but that's much closer in nature to getting a parse error (something pretty much every language does that I'm aware of static or dynamically typed). I wouldn't be surprised to learn that there exists a common lisp ty…

see here: http://sbcl.org/manual/index.html#Handling-of-Types

Re: Why static languages suffer from complexity

#277

Earlier quoted context omitted.

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 line…

> Enough so that sometimes it influences my design decisions just to make the typing job easier.

This is a very good thing. You definitely want the type system (and tests!) to guide your system design.

Re: Why static languages suffer from complexity

#278
One way to do dynamic macro in static type language is to generate the source code using the host language as separate build process before the compilation of hand-written and generated source code.

For example in Typescript, I use tsc-macro to run "*.macro.ts", they can import any functions and modules just like normal source code. And their evaluated result are saved as "*.ts"

The generated ts are then compiled alone with other hand-written typical source files into js for deployment and execution.

Re: Why static languages suffer from complexity

#279

Earlier quoted context omitted.

I'm not the person you replied to, but here's an analogy: it's easier to learn how to drive a car with an automatic transmission than a manual one, even though the latter is "more expressive".

Heh, I would actually consider automatic transmission to be the more expressive one, since to me expressive means how easy it is to express something. Analogously e.g. C++ (manual) is more efficient and allows finer control, but makes it harder to express the same thing as in a 'higher level' (automatic) language. Otherwise, since Assembly provides the most control out of all, would you consider it the most expressiv…

I guess in my head "expressiveness" is some fuzzy combination of what you are able to do plus how easy it is to do those things. I'd consider a calculator that supports real numbers to be more expressive than one which only supports integers, all else being equal.

Maybe this definition is idiosyncratic, though. It's certainly not objective.

Re: Why static languages suffer from complexity

#280
post #252
post #210

Earlier quoted context omitted.

I think I've said about 3 times in this thread that I'm firmly in the "pro" camp as regards the net positives of static typing, and for precisely the reasons you've detailed. I just don't see its absence (or instances where it less than algebraically perfect) as the crippling dealbreakers that others seem to regard it as. What I was referring to as "not slowing one's work down very frequently" was the corner case sit…

> not slowing one's work Put back into context, your reply makes sense as these popular libraries are pretty battle tested. Having said that, it is a valid point that type hints being voluntary means they can only be relied upon with discipled developers and for code you control. Of course, the same point could be made for any code you can't control, especially if the library is written in a weakly typed language lik…

So why can't Nim infer from

   let b: uint = a
that you're really just saying

   let b: uint = uint(a)
And BTW don't you get tired of typing (and reading) `uint` twice in the latter setting? That's what I mean about "side effects" after all.
Post reply on HN