Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>I've found that "powerful" languages allow me to do clever things(TM) and I hate clever things(TM) retroactively when I come back to them.

They also allow you to do sensible things(TM) like use the one and single, battle tested, standard library's generic sort, btree, etc implementation, instead of having to roll (and then read) 1000s of your own over the span of a year...

And it's a false dichotomy that you can't have the sensible things(TM) without the too-clever-for-their-own-good-things (TM) you allude too.



The problem with "too clever" isn't just about cleverness that is actually in the code. It's also very much about cleverness that could potentially lurk behind any particular syntactical expression.

When you look at a line of code, what can you tell about its semantics without considering non-local information? What is invariant and what could potentially be redefined?

I think the answer to this question is extremely important for readability when you're not already familiar with a codebase.


That's a great call out, though I see this in most languages, Haskell and go equally have implicit non local behaviours, but I find the functional paradigm tend to have less, because of side effect free functions.


I find laziness (coming from more imperative, non-lazy languages) to be a huge source of implicit non-local behavior. Trying to figure out how efficient my code is without specific knowledge of how certain functions in the standard library work/how the compiler interprets my code is a impossible.


You're right, the execution context is non local. I'm actually not a big fan of laziness as the default myself. I love the option of lazy evaluation, because sometimes, it makes things really easy, like for infinite sequences, but most of the time, it does add complexity in reasoning about the code.

There's functional alternatives to Haskell which adopt the non-lazy as default, such as Elm, Rust, SML, Lisps, Fantom, Elixir, Scala, etc.

I have to admit though, this is a bit of a trade off situation. Working with pure functions is very simple, but to map those to unpure behavior, like IO, you need something that isolate that, and without laziness, I'm not sure how you can get that to be practical.


I'm not yet familiar enough with Haskell to be honest, but languages like Scala, C++ (to the extreme) and to a lesser degree C# and Swift have a lot more support for non local redefinition of syntactic expressions than Go.

I totally agree with you about pure functions. They can be a real simplification, but only if any deviation from purity requires special syntax at the call site. Otherwise you're back in the guessing game.


but only if any deviation from purity requires special syntax at the call site.

Haskell makes it easy to write data and function types that enforce purity at the call site, throwing a type error if you make a mistake. Not just purity though, you can restrict these types to any arbitrary set of methods of your choosing. This lets you do things like parsing a blob of JSON and having all functions that depend on the result be guaranteed not to have to deal with a failed parse or otherwise invalid data. The fact that the data is good has been encoded in the types, preventing you from passing bad data by throwing a type error.


> special syntax at the call site

Definitely Haskell's game then


No one is arguing to roll your own when there a generic sort in the standard library. The issue with clever things is that people try to make a all purpose solution for what could be a simple one off solution. The all purpose is only used for 2-3 uses and it never battle tested.


Clever things like a sort function that can sort both ints and floats and any new type that implements a comparison function?



I am not arguing for Go. I am arguing that there is an issue with some complex languages. Go is trying to avoid that issue. I agree that the issue is real but also think go takes it a little too far.


Or a quicksort in constant memory.


Haskell, if that's where the sneer is addressed to, absolutely gives you that.

It's just toy first-timer Haskell examples of quicksort (that still work, mind you) that don't.

But then again, take a language like C, and consider how many things (like proper error handling) are missing from 99% of the toy tutorial examples available.


I feel like you are arguing against Java, not against Haskell.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: