TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Puzzle Languages (2009)

88 pointsby Ivoahover 1 year ago

15 comments

bradrnover 1 year ago
Since first reading it, I’ve come to disagree with this post. For personal projects, my main language is Haskell, which Hague counts as a ‘puzzle language’. But that doesn’t match my experience: if I know the problem domain, I can write a solution very fluently in Haskell. (If I don’t know the problem domain, of course, it’s difficult in <i>any</i> language.) I find Haskell as easy to write programs in as Python, if not more so.<p>On the other hand, there are some other languages I find baffling. For instance, C++. Whenever I have to use C++, I find it horribly confusing. It takes me considerable effort to figure out how to structure my program in such a way that the compiler won’t, for instance, insert a destructor call before I’ve used an object. Or that I won’t run into any one of the considerable number of footguns C++ contains. This is a language I find truly puzzling.<p>For this reason, I suspect that what is a ‘puzzle language’ is mostly to do with what you’re familiar with and the way you think. For me, C++ is a puzzle language. For Hague, Haskell is a puzzle language. For both of us, J is a puzzle language — but I can easily imagine someone who can write programs easily in J.
评论 #37762327 未加载
评论 #37762211 未加载
评论 #37762904 未加载
评论 #37773898 未加载
评论 #37770130 未加载
评论 #37763229 未加载
评论 #37775062 未加载
评论 #37762736 未加载
评论 #37765681 未加载
评论 #37770004 未加载
评论 #37774063 未加载
ndrover 1 year ago
This is tangentially related to Puzzles-vs-Problems in Rich Hickey&#x27;s Effective Programs<p>&gt; Eventually I got back to scheduling and again wrote a new kind of scheduling system in Common Lisp, which again they did not want to run in production. And then I rewrote it in C++. Now at this point I was an expert C++ user and really loved C++, for some value of love. But as we&#x27;ll see later I love the puzzle of C++. So I had to rewrite it in C++ and it took, you know, four times as long to rewrite it as it took to write it in the first place, it yielded five times as much code and it was no faster. And that&#x27;s when I knew I was doing it wrong.<p>[...]<p>&gt; So I mean for young programmers, if everybody&#x27;s tired and old, this doesn&#x27;t matter any more. But when I was young, when I was young, I really, you know, when you&#x27;re young you&#x27;ve got lots of free space. I used to say &quot;an empty head&quot;, but that&#x27;s not right. You&#x27;ve got a lot of free space available and you can fill it with whatever you like. And these type systems they&#x27;re quite fun, because from an endorphin standpoint solving puzzles and solving problems is the same, it gives you the same rush. Puzzle solving is really cool. But that&#x27;s not what it should be about.<p>Talk: <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=2V1FtfBDsLU">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=2V1FtfBDsLU</a><p>Slides and transcript: <a href="https:&#x2F;&#x2F;github.com&#x2F;matthiasn&#x2F;talk-transcripts&#x2F;blob&#x2F;master&#x2F;Hickey_Rich&#x2F;EffectivePrograms.md">https:&#x2F;&#x2F;github.com&#x2F;matthiasn&#x2F;talk-transcripts&#x2F;blob&#x2F;master&#x2F;Hi...</a>
rtpgover 1 year ago
I definitely feel this effect, in that some languages are definitely about playing with the language. This can be helpful and make things more productive, but is definitely felt more in some languages than others. It&#x27;s almost whimsy.<p>Haskell has this, Rust has this (where you&#x27;re enticed to imagine everything as moving in and out of memory with a certain flow), C++ has this (trying to imagine how you can take advantage of as many features as possible to get beyond C&#x27;s expressive ceiling).<p>Scala definitely has this, if only by making it impossible to write more than 2 lines of Scala without having to make 4 decisions around language feature usage.<p>You can see attraction to this kind of whimsy in the community.<p>I would definitely place Ruby in the whimsical language category though. There&#x27;s way too much fun being had with mixins in that ecosystem for it to be considered a &quot;straightforward&quot; language.
roetlichover 1 year ago
I think the &quot;puzzle&quot; is just translating from your current mental model into one that fits the language. That&#x27;s why the author sees roughly Algol-like languages as non-puzzle languages, and all other styles are puzzle languages to them. People with different experiences probably think differently.
mchermover 1 year ago
I haven&#x27;t heard this concept before, but it is an interesting one.<p>I immediately recognized that for me, Rust (which I am teaching myself) is a &quot;puzzle language&quot; centered around pleasing the borrow checker. Most of my time I find myself pleasantly enjoying the elegant design of the language and of the libraries written for it. But there is a solid chunk of my time spent knowing exactly what I want to happen and trying to figure out how to express that in a language that prohibits aliasing.
评论 #37774638 未加载
mjburgessover 1 year ago
Rather than &#x27;puzzles&#x27;, I think the issue is that these are &#x27;big idea languages&#x27;. (Eg., haskell = pure lazy). These ideas permeate all levels of program design, making programming often converting the naive interpretation of the problem into their Big Idea.<p>Phrased this way, it seems like they won&#x27;t be puzzles in certain domain-specific areas; ie., when the naive problem suits their big idea.<p>So I&#x27;d say the &#x27;puzzle issue&#x27; arises because big-idea langs are just not good for many problems.
mslaover 1 year ago
It seems a puzzle language is one where you haven&#x27;t fully grasped some conceptual foundation of the language.<p>For example:<p>&gt; In Haskell and Erlang, the puzzle is how to manage with single assignment and without being able to reach up and out of the current environment.<p>You can say the same thing about Python: &quot;Stupid language. I just want a block of RAM and a pointer. Pointer? Parlez vous memory access? Wo ist das Void-Pointeren? Where&#x27;s that blasted phrasebook... &quot; [1] Python has abstraction over direct memory access, Haskell has referential transparency and a type system that&#x27;s both stronger and less confining than most type systems that get called &#x27;strict&#x27; in the procedural world. Neither allow you to reach out of their environments, at least by default, and it makes both of them simpler and more regular.<p>[1] Non-English languages intentionally a bit misused. That&#x27;s the point.<p>Obviously, the solution is to learn how the language <i>wants</i> to do things, and speak it like a native. This isn&#x27;t about purity, really, just learning how to use tools as they&#x27;re intended to be used.
评论 #37763500 未加载
kewpover 1 year ago
This is how I felt when trying to learn Elm: the program had to be correct, exactly correct, or it wouldn&#x27;t work. You had to make every piece, every function, fit precisely, to define it&#x27;s shape, it&#x27;s exact inputs and outputs and effects ... in the end I found it very restrictive. I like the idea of loose-ness by default and adding contraints gradually (like javascript -&gt; typescript).
pmontraover 1 year ago
My two cents<p>&gt; I can usually bang out a solution to just about anything in Python. I update locals and add globals and modify arrays and get working code<p>Globals in Python? They do exist but why ever use them? Not using them in Python invalidates most of the puzzliness attributed to Erlang and Haskell.<p>&gt; Each [Erlang] process captures a bit of relevant data in a small, endlessly recursive loop. Imagine dozens or hundreds of these processes, each spinning away, holding onto important state data. Erlang string theory, if you will.<p>Calling an Erlang process to store state is equivalent to calling a method of an object. There are hundreds of important objects in any medium sized OO program, plus hundreds of thousands invisible ones, just because everything is an object. Nobody complains about creating the few important objects in Python and nobody complains about creating the few necessary processes in Erlang.<p>My complaint with Erlang and Elixir is that I have to define handle_cast and handle_call functions with the actual method name passed as argument instead of being able to define and use the real method names (or function names, it doesn&#x27;t matter) as in any sensible language. It feels so low level, like OO programming in C around 1990. Erlang is excused because it&#x27;s from that age. Elixir is not.
thornover 1 year ago
Go is not a puzzle language. I wonder what about Rust? Can we apply &quot;puzzle language&quot; to it? Maybe it depends on the level, how well you know the language?
评论 #37769374 未加载
评论 #37766977 未加载
评论 #37762531 未加载
评论 #37762617 未加载
dangover 1 year ago
Discussed at the time:<p><i>Prog21: Puzzle Languages</i> - <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=472327">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=472327</a> - Feb 2009 (8 comments)
mikhailfrancoover 1 year ago
(2009)
Tweyover 1 year ago
The ‘puzzle’ of imperative languages is often ‘how do I keep less state?’. Because they&#x27;re so verbose, figuring out what the code _does_ (in terms of actual transformations to the data) usually involves imperatively running the program in your head, and so it&#x27;s important to keep the amount of state that could be touched in any particular part of the code to a minimum, since humans only have so much working memory.<p>When I write code in an imperative language, I often spend a lot of time trying to find the optimal balance between complexity in the data and complexity in the control flow. As a dumb example, if you have a loop over some data that does one thing up to a certain point then another thing for the rest of the data, you can a) keep a Boolean that indicates whether the switch-over condition has been reached, or b) break the loop up into two loops, and fall through to the second loop once you hit the condition in the first loop. Without additional constraints I often prefer the latter (keep as much state in the control-flow as possible), but it can be very puzzling to figure out how to map your problem into a linear state machine, or to try to group lines of code into blocks that share invariants without accidentally overwriting some important data.<p>C is particularly designed around this kind of puzzling, and has features carefully built in to enable and encourage it, such as the pre- and post-increment operators, or assignment returning its RHS. C code considered elegant has usually been thoroughly optimized in this way. A prime example is this argument-parsing code from K&amp;R [1]. When reading, I find it interesting to bear in mind that this is pedagogical code intended to teach people how to write the language, written by the authors of the language itself. Python tried to take away the ability to optimize for this sort of elegance by removing the syntactic features that support it, but the core puzzle still remains — you can carefully organize your code to ascribe meaning to things like loop breaks (especially with `except`!) or function returns. At its core this is because procedural code gives you a particular active data structure to work with (a stack of function calls each consisting of a set of mutable variables and a list of statements that mutate those variables, possibly with loops in) that is insufficient for encoding the natural structure of many programming problems, and you so have to make choices about which bits of the problem to map to it and which to code up manually with explicit additional data structures. This is not specifically a criticism of procedural languages: all other paradigms also limit you to one data structure or another, FORTH being the one that is most up-front about it.<p>In general, I think it is a fallacy of perspective to think that the difficulty of programming is broken down into ‘understanding what the code should do’ and ‘explaining that thing in your programming language of choice’. Rather, the problem of programming is precisely ‘understanding what the code should do in the computational model used by your programming language of choice’. If there is a universal model of computation in which we (as human programmers working on commercial timescales) can understand the meaning of programs in a way that is completely independent of the target language (such that mapping it to any target language is a purely mechanical process) I don&#x27;t think we&#x27;ve found it yet. Someone steeped in a particular programming model will tend to consider their model effectively universal, and translating their mental model (expressed in terms of that programming model) into a different model of computation to be a puzzle; but in fact even encoding the ‘understood’ behaviour into a real-world programming language based on the same model usually involves making non-trivial decisions, which implies that our mental models of computational models are usually low-fidelity and&#x2F;or may disagree with reality.<p>[1]: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=16249936">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=16249936</a>
avgcorrectionover 1 year ago
File this under Didn&#x27;t Age Well.
jonahxover 1 year ago
TLDR:<p>These are languages I&#x27;m familiar with:<p>...<p>These are languages I&#x27;m not:<p>...