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.
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.
> 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.
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.
> The lisp source code encodes more information, and what is added is highly relevant to the process of reading it
Lisp isn't that easy when you don't have supporting tools, mainly a coding editor that auto-indents, re-indents, and shows matching parenthesis. I think you're being a bit over-optimistic there.
Forth, OTOH, has been used with dumb terminals over serial lines. Old Forth systems even often featured an integrated code editor for this purpose, on systems with very limited memory. This was possible because Forth doesn't need a complex editor to be comfortable... When you don't neglect factoring, naming, etc.
> The human mind is a computer
Right. Can your human mind compute 358729358 x 5648759845 in less than 10 ns ? False premise, invalid conclusion.
Anyway, you're so right, you're so right. Have a nice day with Lisp.
So "the human mind is a computer" is a false premise, but "a computer must be able to compute 358729358 x 5648759845 in less than 10 ns" isn't? Do you know what a computer is? The human mind has a very different architecture than the Turing machines you are used to, so its performance characteristics are also different.
> invalid conclusion
My conclusion doesn't require the premise that the human mind is a computer. That is just an analogy to help you to understand my actual argument, which is as follows: there are certain things that happen in the brain which take time and energy (scientifically proven), reading Forth requires you to do more of those things than reading lisp (trivially true). Therefore it is harder, if hardness is a metric of how much effort (time and engery) something takes.
> mainly a coding editor that auto-indents, re-indents, and shows matching parenthesis. I think you're being a bit over-optimistic there.
Even Nano does this. Far from being optimistic, I struggle to think of a situation where you wouldn't have this. Unless your computer is hooked up to a teletype printer, you will have these features. People have edited lisp code on deep space missions and had these features. How? Because you can write the forms in an editor and then send them over the wire afterwards. This is a technical problem that was solved before it even existed, and it is just a sad coincidence that many people decide to edit and run code through a dumb terminal connected to a REPL instead of in an actual editor connected to that same REPL session.
> Forth doesn't need a complex editor to be comfortable
Neither does lisp. Matching brackets and auto-indenting lisp code is so simple its braindead. It would be the simplest feature of any editor that supports it. Quite frankly, this is a stupid argument anyway. Even if text editors as "advanced" and "complex" as GNU Nano were a total rarity, I would rather code in a language that's easier for my editor installed on my computer than one which caters to someone else doing everything on an embedded device which only connects to a physical printer. That's like saying we should all use Fortran because it works much better on punch-cards.
We have no idea what is the structure of the expression. We do know w7 is the last word. The last word is the main one. Beyond that we cannot tell which are the children: are they w3 and w6? Or whatever.
Lisp:
(w7 (w4 (w3 w2)) (w6 w5 (w1)))
You know what the structure is, and if the compiler doesn't tell you that something is misused, the run-time will. E.g. that w5 needs at least 3 arguments, but two are given.
I have addressed that point twice already. This is tiring.
I discovered Forth a long time ago and thought, there's no way this language is viable, and yet it was used in prestigious projects. It made me curious so I tried it, dropped it, picked it again and tried harder. I was young and open minded. A couple decades later Forth is my go-to language.
I have no interest in convincing people with immutable opinions who cannot listen.
But the topic is readability not viability. Pretty much all programming languages have some readability issues, dealing with them via coding conventions.
Nowadays we want our text editors to handle those conventions automatically, and be able to recover them even if we delete extra white space or line breaks.
I also discovered Forth 40 years ago. It looked viable to me. I recognized then that while it's interactive like BASIC, it's way faster. Also cleaner, because Forth functions are reentrant, usually not relying on global variables.
> But the topic is readability not viability. Pretty much all programming languages have some readability issues, dealing with them via coding conventions.
Thank you, that's part of what I was saying.
> Nowadays we want our text editors to handle those conventions automatically
But you can't always have what you want. The other guy I was talking to apparently has no idea what it means to deal with an embedded system, hopefully you do.
> I also discovered Forth 40 years ago
And did you write Forth during these 40 decades? I'm apparently a bit younger than you but I did picked and dropped Forth a couple of times for other "nicer" interpreted languages. All in all I think I have a solid 2 decades of practice in Forth. During this time I have constantly changed my idioms, so it's not just doing the same thing for decades and getting used to it.
And I'm saying that readability became less and less of an issue as your writing skills improve. That's also something the other guy refuses to understand.
The arity issue that is often pointed out is not a bigger deal than stumbling on some unknown Javascript, Lua, Lisp or whatever function call and figuring out what each parameter does, especially when it's just a boolean (a bad practice, yet a common practice). I have programs that are made of hundreds of Forth definitions. Arity and expression structure are sometimes an issue, true. When it happens, I just use the search function of my editor.
But why do you specifically forbid yourself to mfk*g split your editor window and go look to the definition of a function when it's Forth, when you do that every day in any other language?
I don't want to look up the semantic definition of an identifier just to understand which chunks in the syntax are its arguments and which are not.
The tide is flowing the other way now. Kids are using editors that integrate deeply with compilers (via Microsoft's Language Server Protocol). The editors are providing code formatting and completion based on communicating with a compiler. That seems like it could work with Forth.
> The other guy I was talking to apparently has no idea what it means to deal with an embedded system
I would love to see you justify this. Sadly you will not, because I understand it quite well. It's a pretty basic principal that if a system is capable of handling user input interactively, you can instead connect a more powerful computer and have it receive input from that device. Hence all devices with REPLs can benefit from editors hosted on my own computer. In an embedded system, it is much more likely for you to have to hook your own computer up to something than it is for that thing to be able to accept user input independently. Most embedded devices do not have a USB slot for you to plug your keyboard in.
> That's also something the other guy refuses to understand.
It is a point which I addressed in my other post.
This manner of response is stupid and infantile. I hope you can talk to me directly next time.
> This manner of response is stupid and infantile. I hope you can talk to me directly next time.
I made it pretty clear I didn't wish to continue that conversation, so I wasn't responding to you. There will probably be no next time, as there's a clear gap in practical experience - on that particular topic - between you and me; it would take far too much energy for me to explain things step by step and I'd gain nothing from it.
Then why did you continue the conversation? I'm not forcing you to make snide jabs at me in a public space, and you can hardly blame me for responding to them.
> it would take far too much energy for me to explain things step by step and I'd gain nothing from it
If you cannot explain it simply, you don't understand it well enough.
> I'm not forcing you to make snide jabs at me in a public space,
Ok, sorry. That was a poor way to invite that person to read the parallel thread. It's a bit frustrating to deal with claims based on nothing but theory when I have at least two decades of practical experience on these topics.
> If you cannot explain it simply, you don't understand it well enough.
First, that answers something I didn't write (of course I can explain those things simply, the problem is that it would easily make a whole article) and secondly, what you wrote ignore the fact that teaching is a skill, so not all experts are good teachers.
Okay, that's well and good, but you are sat there saying that you can manually input data into an embedded device, but for some reason can't connect a computer to it. Unless it has a built-in keyboard, that simply isn't true. If it was true, it would be trivial to prove. You could just name the device and situation.
Wow, 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".
Yes, 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.
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:
... or something like that. But in reality what one writes is (hopefully this is close enough to your abstract example): Or if we stick to real-forthers-do-not-use-local variables: Newbies will probably use "training wheels comments": 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.