5 ms·
Example from the article: f = drop dup dup × swap abs rot3 dup × swap − +
by galaxyLogic 6y ago
Example from the article:
f = drop dup dup × swap abs rot3 dup × swap − +
- JadeNB 6y agoI don't know if you're just mentioning an example that's in the article or making an implicit comment on it, but, like with any other programming paradigm, it's going to be hard to read until you get used to it, and becomes easier once you wrap your mind around it. The question isn't whether it looks funny at first, but whether the effort to make it look familiar is worth it.
- Jtsummers 6y agoThe author could've made it somewhat easier, though. Keeping the unused variable (so still keeping the drop) it can be reduced by 1 operation, but the logic of what's on the stack and managing it is simplified: drop dup dup * swap abs - swap dup * + operation : stack (init) : x y z drop : x y dup : x y y dup : x y y y * : x y (y^2) swap : x (y^2) y abs : x (y^2) |y| - : x (y^2 - |y|) swap : (y^2 - |y|) x dup : " x x * : " (x^2) + : y^2-|y|+x^2 The author's version requires rot_3 in order to deal with performing the computation in an awkward order. This version deals with each variable in order and in a more natural way. And replacing `dup * ` with `square` simplifies it a bit more (which is what you'd do in a language like Forth, you factor common operations into new words): : square dup *; drop dup square swap abs - swap square + operation : stack (init) : x y z drop : x y dup : x y y square : x y (y^2) swap : x (y^2) y abs : x (y^2) |y| - : x (y^2 - |y|) swap : (y^2 - |y|) x square : " (x^2) + : y^2-|y|+x^2 Down to 9 ops, and reasonably clear at this point.
- galaxyLogic 6y agoReading the article I got quite enthusiastic about it in the beginning and started to think I should try this out. But when I saw drop dup dup × swap abs rot3 dup × swap − + I thought "maybe later". It is great that the author brings the issue up, even saying "every kind of language has its strengths and weaknesses, but most language designers will lie to you about the latter" I do believe that point-free-form holds much promise. Maybe there could be more support for it in more standard languages and programming support tools. I think the problem with "drop dup dup × swap abs rot3 dup × swap − +" is that it gets too abstract. Even though it is very elegant and succinct, it takes effort to understand it. And if something is hard to understand it is also hard to find the errors it may have.
- JadeNB 6y ago> I think the problem with "drop dup dup × swap abs rot3 dup × swap − +" is that it gets too abstract. Even though it is very elegant and succinct, it takes effort to understand it. And if something is hard to understand it is also hard to find the errors it may have. But this is my point—the effort it takes to understand it is, in some sense, a one-time effort. If you invest the up-front effort to learn how to read concatenative programs, then you gain a fluency that makes it easier to read other programs. (Our more familiar programming paradigms are just as opaque to a beginning programmer; recursion, which is so fundamentally intelligible to us, is a major obstacle to people first learning to program, but I think there are few who would say it's not worth it.) One of the big goals of concatenative programming is refactorability, which Jtsummers beautifully showed at work in your sibling post: https://news.ycombinator.com/item?id=25261911 https://news.ycombinator.com/item?id=25261911 . If you can understand enough to refactor, then you can simplify it to the point where errors must be apparent.
- remexre 6y agoThe article literally continues, Well…that sucked. A Lighter Note You’ve just seen one of the major problems with concatenative programming—hey, every kind of language has its strengths and weaknesses, but most language designers will lie to you about the latter.
- Byamarro 6y agoI see no problem if more paradigms would be pushed into mainstream. Not so long ago, functional paradigm had its comeback and it improved quality of the code in i.e. JavaScript world. The thing is to not be a purist, and mix paradigms in the code to have the best possible solution.
- carapace 6y ago?- E = "pop dup dup * swap abs rollup dup * swap - +", joy(E, Si, So). E = "pop dup dup * swap abs ro...p - +", Si = [_56410, int(_56422), int(_56432)|_56428], So = [int(_56454)|_56428], _56422 in 0..sup, _56500+_56422#=_56496, _56422+1#=_56520, _56422^2#=_56544, _56500+_56544#=_56454, _56544 in 0..sup, _56496 in 0..sup, _56432^2#=_56496, _56520 in 1..sup ; E = "pop dup dup * swap abs ro...p - +", Si = [_57392, int(_57404), int(_57414)|_57410], So = [int(_57436)|_57410], _57404 in inf.. -1, _57482+_57404#=0, _57404+1#=_57502, _57404^2#=_57526, _57482 in 1..sup, _57578+_57482#=_57574, _57578+_57526#=_57436, _57526 in 1..sup, _57574 in 0..sup, _57414^2#=_57574, _57502 in inf..0 ; false. It's a Prolog query with two solutions (because the input to abs could be positive or negative) showing the input and output stack effects (the type signature) and the CLP(FD) constraints between the input and output integers. It's a little hard to read, I know, but the code that performs the type inference and constraint generation/recording is very brief and elegant. ( It's a work-in-progress: https://git.sr.ht/~sforman/Thun/tree/master/source/thun.pl https://git.sr.ht/~sforman/Thun/tree/master/source/thun.pl ) - - - - FWIW I messed about with a Python implementation of Joy (another concatinative language) and I have some notebooks that might be interesting: https://joypy.osdn.io/notebooks/index.html https://joypy.osdn.io/notebooks/index.html