4 ms·
> objectively more readable Certainly not "objectively" in the literal sense, because there's no measure of "readability". But you can define one if you want,
by astrobe_ 2y ago
> objectively more readable
Certainly not "objectively" in the literal sense, because there's no measure of "readability". But you can define one if you want, so that we can argue about its biases and relevance ;-)
But Forth programmers sometimes use double spaces to separate sub-expressions:
(d (c b) a) <=> a b c d
... or something like that. But in reality what one writes is (hopefully this is close enough to your abstract example):
(square-root (+ (square a) (square b)))
<=>
a square b square + square-root
Or if we stick to real-forthers-do-not-use-local variables:
square swap square + square-root
Newbies will probably use "training wheels comments":
( a ) square swap ( b ) square + square-root
I know the usual objections that one needs to keep the number of inputs/outputs of each word/function. It's actually not as difficult as it seems with good naming and when you keep things simple. Actually, the former is a well-known hard problem and the latter is a perhaps lesser-known hard problem. But I would say that's good problems to solve.
- James_K 2y ago> But you can define one if you want Something is harder to read if it takes more effort to read it. Reading code is converting it from the format it is written down in to the tree of invocations in your mind. Forth is more complicated to read because you must use the definition of each function to determine how many arguments it takes, and hold that information on a stack in your head. All you have to do in lisp is count the number of parenthesis. Reading Forth is O(stack depth) memory, where reading lisp is O(1). Imagine you wrote some code and it produced an error because you didn't give enough arguments to a function. In lisp, you can look at the function and trivially see how many augments it has. In Forth you will have to scan the entire piece of code to locate the error. Purely practically, I can almost guarantee that someone with no experience in either will learn lisp faster, and they certainly wouldn't need to write "training wheels comments" to figure out how the functions are called. In fact, the person reading the lisp code would likely understand instantly how it works, where the person reading the Forth code would spend a long time staring ant it and having to write stuff down to figure that out. It's just transparently obvious that reading Forth code takes more effort than reading lisp code for anyone who has spent equal time doing both.
- astrobe_ 2y ago> Something is harder to read if it takes more effort to read it. I think the smiley was a sufficient warning not to go there. Define harder. For whom ? etc. > hold that information on a stack in your head. I have proactively addressed that point, it is a matter of coding style and "good practices". But since you can only believe me on that, the discussion can only go in circles if you don't agree. > It's just transparently obvious that reading Forth code takes more effort than reading lisp code for anyone who has spent equal time doing both. It depends by whom this code was written. I can certainly craft Lisp code which is a nightmare to read. I've seen many times Forth code that was not designed and written in the best style. "Readability" is a relationship between the reader and the writer, it's something that becomes clear when you do code reviews. I think people would generally agree that C++ is "more readable" than both Forth and Lisp, yet if you use lesser-known C++ features - or just omit parens around expressions because you assume that the priorities are obvious - you can easily lose intermediate level reviewers. Anyway, after reading many online threads about "readability", I came to the conclusion that it is a non-argument, and that discussions about it are most often pointless. But I wanted to use that to show how Forth solves this apparently huge problem, and introduce a bit of its philosophy.
- James_K 2y ago> It depends by whom this code was written This is really just a hand-wave. You are saying "maybe there's some difficult to read lisp code out there, so lisp might not always be easier", whereas I am talking about objective measures. That is the exact same program translated between the two representations. This can be accomplished by taking the lisp code, reversing it, and removing the brackets. Note the opposite direction is much harder because information is lost. The lisp source code encodes more information, and what is added is highly relevant to the process of reading it. When, as in Forth, this information is not given, it must be computed which is more mentally taxing hence making Forth code harder to read. > Define harder The human mind is a computer. Operations on this computer require energy, as much has been verified scientifically. Reading a program can be seen as an operation in this computer, as I have previously defined. Reading a Forth program requires a greater use of working memory to store items of the stack, and hence is more difficult as this is an extremely scarce resource. Using more working memory also implies an increased number of operations, so a higher time complexity as well as space. Forth code also requires more accesses to long term memory for arities. The human mind is not nearly as subjective as you take it to be, many aspects of it have been measured and observed. In the long term, pattern recognition kicks in and the problem begins to lessen but this is analogous to function memoisation. That a function can be memoised does not prove it is easy to compute, just that after putting enough work in you don't have to do the work again. > how Forth solves this apparently huge problem It partially solves the problem by writing expressions in a format closer to lisp. To fully solve the problem, you end up writing lisp.
- trealira 2y agoWow, I just learned that Forth programmers do something similar to the "point free" style in Haskell (which is discouraged in excess). For example, if you have a function like this: -- f: returns the second argument minus the first f :: Int -> Int -> Int f x y = y - x You could technically rewrite it like this: f = flip (-) In practice, I think the flip function is rarely used, except by bots online that rewrite your functions from ones that use variable names into ones that don't, e.g. the website "pointfree.io".
- astrobe_ 2y agoYes, Forth is point-free at its core, the only named variables that exist are global variables. The standard defines local variables as an optional extension.