5 ms·
I prefer less powerful languages (that have sufficient power to clearly express the domain). I've found that "powerful" languages allow me to do clever things(
by noir_lord 10y ago
I prefer less powerful languages (that have sufficient power to clearly express the domain).
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.
This gets even worse when you have multiple people on the team doing clever things(TM).
- tazjin 10y agoAgreed, but I'd take this into a different direction and argue that code generation - as it is often practiced in Go - is a Clever Thing (TM). A language like Haskell lets me write extremely complicated code, but it also lets me concisely express the constraints I want in the form of types without getting too verbose. Go lets me do neither.
- avisser 10y agoThis is 100% my recollection of my 2 months of Scala.
- coldtea 10y ago>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.
- canes123456 10y agoNo 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.
- unscaled 10y agoClever things like a sort function that can sort both ints and floats and any new type that implements a comparison function?
- daxfohl 10y agoOr a quicksort in constant memory.
- coldtea 10y agoHaskell, 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.
- canes123456 10y agoI 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.
- voutasaurus 10y agohttps://golang.org/pkg/sort/#Slice https://golang.org/pkg/sort/#Slice
- didibus 10y agoI feel like you are arguing against Java, not against Haskell.
- fauigerzigerk 10y agoThe 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.
- didibus 10y agoThat'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.
- fauigerzigerk 10y agoI'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.
- tel 10y ago> special syntax at the call site Definitely Haskell's game then
- chongli 10y agobut 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.
- ajmurmann 10y agoI think it depends what type of "power" we are talking about. Ruby's meta programming stuff certainly falls into the problematic area. A powerful type system might be seen as quite the opposite because it can make code more predictable.
- ruslan_talpa 10y agoIf by clever things you mean "pointfree" all over the place then i agree but if you mean "abstractions" in general then that's a different thing and this says it best. “The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.” ~ Edsger Dijkstra I think i can honestly say i did not fully get that quote until i learned Haskell
- didibus 10y agoGreat quote. I think if people think of level of abstraction it makes more sense. All code is an abstract representation, but to solve a problem, it's easier to work within an abstraction level that fits the problem.
- crimsonalucard 10y agoPowerful languages do clever things under the hood so you don't have to(TM). All programmers use this same abstraction so there is no confusion. Less powerful languages force the programmer to come up with their own clever abstractions so that if you have multiple programmers you'll end up with 20 different clever ways of doing the same thing.
- julian_1 10y agoI hate "clever things" as well, but it's worth being precise about what constitutes cleverness in different languages. Dynamic languages - ruby, python, bash, objective C etc - allow all sorts of cleverness - such as monkey patching, attribute injection, dynamic lookup - because of their dynamic runtime. All the checks about whether the code makes sense is performed at runtime. Languages with more mature/strong/static typesystems are initially restrictive - but the emphasis in cleverness is to be able to know upfront - and at compile time - if the code expressed is consistent in the way data and effects are represented and expressed. Of course - there are other kinds of code complexity -in terms of ease of understanding, and maintainability - that will always involve tradeoffs considering the task at hand and nature of the programming environment (solo, community, commercial, academic etc).