Chuck Moore, Extreme Programmer
cs.uni.edu
cs.uni.edu
The link is from the CS department at the University of Northern Iowa in Cedar Falls, IA. It sounds obscure, but that's my hometown. I grew up a couple blocks away from it. I sat in on classes there. I even know the author's family. That's small town Iowa, for ya.
I never thought I would see anything related to that on here. This is truly a place for all.
I do the same. :)
I am addicted to be very honest. I learn so much, it's worth it.
I ran a few meetups while in Iowa, and one of the common themes myself and the other organizers tried to help everyone feel is that these days, location really is less important than ever before.
It may help to know people face to face in the Bay Area or other major metropolitan for some opportunities, but now is the best time ever to find people with technological interests in your neighborhood, even if you’re not in a tech hub.
In fact, all the better if you’re not in a tech hub - you can become a local subject matter expert more easily in a growing community.
I guess this is to say how you view this depends on whether you interested in being a local subject matter expert or a global subject matter expert.
“I wish I knew what to tell you that would lead you to write good Forth. I can demonstrate. I have demonstrated in the past, ad nauseam, applications where I can reduce the amount of code by 90% percent and in some cases 99%. It can be done, but in a case by case basis. The general principle still eludes me.”
I would expect that, if you took five of these rewrite projects of Moore's, and compare-and-contrasted their source with the source of the originals, principles would leap out at you.
(Why don't we programmers, as a culture, read code this way? It really seems like the only way to deduce novel facts about programming for yourself. Is it just that a rewrite where both the old and new codebases are shared-source is rare?)
Much of Chuck's code reduction comes from simply not implementing parts of the problem that most people would not think of eliminating. Other parts he will eliminate that most people would think inconceivable to eliminate.
Other "secrets" of Chuck's ways are that he uses the CLI as a front end, or, spends a great deal of time working on an algorithm and finds a simpler way that is good enough in the application he's working on today. So instead of spending time optimizing for speed or modularity he's willing to specialize his subroutines per application to optimize for concision or simplicity. Somewhat like Woz's optimization to save chips.
I bet most people who investigate Chuck's methods will feel disappointed that the methods don't seem as clever as the end product. What I think most people can take away from Chuck is skepticism about the utility of most programming technologies, which do automate tedium but tend to substitute their own architecture and complexity, for a net loss.
You can't just wander up to management and say, "I need X to make an optimal solution". They will negotiate you down. That's their job -- to negotiate into a position of advantage. When you need protection from the chaos that surrounds the rest of the organisation, you can count your lucky stars when you have an expert negotiator on your team. But when you go up to that expert negotiator and say, "I want X", the first thing that's going to go through their minds is, "I wonder if I can get that cheaper".
So programming has to be a balancing act of constantly delivering functionality while at the same time ruthlessly refining your vision of how it's going to work. If you are delivering quickly, regularly and constantly nobody will touch you for fear of screwing it all up. But knowing how to do that while still marching inevitably closer to simpler and simpler solutions is hard. A normal person needs to practice (and get it wrong) a long time before they get good at it.
Chuck describes a lot of his techniques in his books, but it's fluency that you need -- and it's fluency while things are hitting the proverbial fan that makes all the difference. You need great judgement to look at what you need and to prioritise it appropriately. If I deliver X quickly, I'll show progress. Do I need to show progress now? How fast? Can I refactor Y while I'm here? Is all of this necessary? And so on and so on.
It's tempting to think, "If only I was given lots of time.", "If only I didn't have incompetent coworkers", "If only people would listen to my advice", "If only management could look past tomorrow"... But that's not useful. Anybody can be a great programmer if we remove every problem before they start. The measure of your worth is how many of these complicating factors you can deal with while still producing great code. That's what's rare.
But this in my opinion explains well both why people are seduced by forth and why forth is not widely used.
EDIT: also gives opinion why Chuck Moore can be successful using forth.
The other side of this coin is NIH Syndrome. I've seen that go wrong in all sorts of ways.
One of the key skills of being a great engineer in the real world is exercising good judgment whether to "build or buy".
Beginner: Learn the basics, be proud of getting something done that works, even though it might not be a useful result.
Experienced: Learn the systems. Figure out which system is more helpful than others. But don't worry too much before you start learning a new system. Even a "bad" system will teach you something valuable. In the end you need to learn far more than one system anyways to progress.
Expert: Learn that no system is perfect and use them freely according to context, maybe create a few yourself. See that even these "bad" systems come in handy once in a while.
Master: Don't bother to get here. Even most freaks won't get here and from those who do most will tell you that they had no choice to do something else and they were just lucky that at least in this area they had talent. You're probably better off than them in general terms. If you want, learn here that <anything> is just one system. Welcome to the next abstraction level as Experienced.
(This system about learning is developed by yours truly.)
It may have been because that person is then 1/1000th as responsive to their specific needs. It also may have been because that person wasn't cleared, and paranoia requires their code to be vetted before allowing it within breathing distance of our network. Or it may have been because buying a third-party tool requires approval of the manager's manager's manager, while rolling your own is the manager's call.
I have never seen a company that makes it easy to buy a third-party license, and never a company that makes it easier to use a gratis licensed software than a paid one. They're all afraid that GPL will infect the code, and it will dance out of our source control onto the Internet like children following the Pied Piper.
And on the other side of that coin, I have also seen licensed third-party software become vastly more trouble than it was worth, especially when it came time to upgrade it to a newer version. In general, though, if a third-party tool already does exactly what you need it to do, and you never need it to do anything else, it is always better to license it, configure it correctly once, and then never touch it again (aside from security-related patches).
Meeting anecdote with anecdote, I've never worked at a company that made paying for licensed software easier than using gratis.
My app specific logger is aware of the context it is running in, it will store all the context but only write it on an exception or error and discard it otherwise, so I get all the information I need without the noise from the 99.9% of the time I don't need it.
I do use logging libraries, but they are for the low level stuff like file truncation, rollover, etc and I wish there were "logging" libraries that did just those tricky little parts on let me write the 50 or so LOC that the high level interface needs.
I haven't read any of his work, what is impressive about his development environment?
This is even understating it -- it's not like he used existing software to lay out the chip, and then ran tests using PSPICE to verify the functionality. He wrote his own chip design software and analog simulator, and designed the chip in his own environment, and created the CPU, the GA144: a working 144-core processor designed to run "ArrayForth", a parallel version of Forth that he designed and authored, just as he designed ColorForth, and just as he designed, once upon a time, the language known as Forth.
Any of the tasks above seem like it would be a reasonable accomplishment for a good programmer. Combined, they make me question whether I even qualify as a developer by this standard, and make me wonder whether I should take a year off of development and just really learn Forth.
I'm going to need a citation for that. I browsed through the website and wasn't able to find anything at all mentioning the development of a full EDA software suite. There are only a handful of companies in the world that can build and maintain a full HDL + synthesis + P&R + layout + verification toolchain...
Also, I would be interested to know what kind of process the GA144 is fabbed with.
-----
So it seems like OKAD is basically a layout editor, simulator, DRC checker, and GDSII compiler. The simulator uses a very simplistic transistor model that would only work at very old process nodes (>350nm?) due to the low impact of parsitics and leakage.
Not even a moderately complex digital chip from the mid-90s could be designed and verified using such a simplistic toolchain.
To provide a software analogy, Chuck wrote an assembler for a custom assembly dialect targeting e.g. x86, and then directly used that assembler to build an operating system kernel. Given the absence of "higher-level" constructs, the resulting OS will never be as complex as something like an NT kernel, especially due to the difficulty of testing and verification.
Going back to circuit design, OKAD will never be able to design a complex digital chip on a state-of-the-art process. It's really nothing more than a simplistic EDA toolchain that would only work on simplistic circuits and fabrication processes.
A modern EDA toolchain from e.g. Cadence is many orders of magnitude more complex.
This kind of minimalism and stripping things down to their essence is a powerful tool to allow you to focus on what matters rather than at all those things that don't really matter. If you don't actually need 4 GHz chips and billions of transistors to get the job done then why would you?
Reliability and simplicity go hand-in-hand.
I agree entirely. I just wanted to point out that it's not accurate to equate what Chuck designed (i.e., OKAD) to a modern EDA toolchain and technology node.
If it works for him, then great!
I think you subconsciously added the 'modern' in there somewhere and then argued against that.
> He wrote his own chip design software and analog simulator
I immediately thought of a modern toolchain. Had I known that this was done decades ago, I might have reacted differently.
Nonetheless, even decades ago, both Cadence and Synopsys likely had pretty advanced tools under development. I may be mistaken though.
Forth is a language in which it's realistic for each programmer to have his own custom editor. That's even more awesome.
| RetroForth Block Editor (http://www.retroforth.org)
| * Released into the public domain *
|
| This is the block editor from RetroForth Release 9.2.1
| It splits the normal 1k block into two smaller 512-byte blocks,
| the one on the left for code, and the one on the right for
| documentation/comments. Both are displayed side by side.
|
| It makes use of some features specific to RetroForth, so it
| will not work on an ANS FORTH system without changes.
tib 1024 + constant <buffer>
128 variable: <#blocks>
<buffer> variable: b0
variable current-block
: there b0 @ ;
: #-of-blocks <#blocks> @ ;
: new there #-of-blocks 512 * 32 fill 0 current-block ! ; new
: (block) @current-block : block 512 * there + ;
: (line) 32 * (block) + ;
: p 2 current-block -! ;
: n 2 current-block +! ;
: d (line) 32 32 fill ;
: x (block) 512 32 fill ;
: eb (block) 512 eval ;
: el (line) 32 eval ;
: e 16 for 16 r - el next ;
: s !current-block ;
: i 0 swap : ia (line) + lnparse rot swap move ;
: \ 1 s e ;
loc:
: | '| emit ;
: row dup 32 type 32 + ;
: left# -16 + negate dup @base <if space then . ;
: right# negate 32 + . ;
: code|shadow row | swap row swap space ;
: rows 16 for r left# code|shadow r right# cr next ;
: x--- 2 for ." +---:---+---:---" next ;
: --- space space space x--- | x--- cr ;
: blocks @current-block 1+ block @current-block block ;
here ] --- blocks rows 2drop --- ;
;loc is v
: edit [[ clear v ]] { is ui } ;This is an example of "ugly" Forth code. It's ok here to make the code as short as possible.
In reality I would write (educational) Forth code this way. The texts in parentheses are comments.
( compute Hypotenuse sqrt[a²+b²] )
: hypo ( a b )
swap ( b a )
dup * ( b a² )
swap ( a² b )
dup * ( a² b² )
+ ( a²+b² )
sqrt ( result )
;
( Application: 1.2 3.4 hypo )I collaborate on a team, so we use one documentation standard and one coding style. We've stripped down our coding and commenting styles to the bare essential--one style that works across the whole team, across the lifespan of the project.
The business that pays our team pays for what customers want. Every once in a while a new guy on the team will write something no one wanted, and we end up chucking it. We're stripping down the project code to the bare essentials necessary to make money.
I think what Chuck Moore brings is not so much a plain ol' minimalism, but a nostalgia for a wild west "one man in a garage" tech scene that never really existed, at least not the way we like to imagine it did, because we live in a world driven as much by money as by love of cool new things.
Not to say he doesn't do cool things, but I could do cool things if I didn't have to answer to business constraints, my fellow team members, and so on.
Moore considers that a mangitude of bugs not features.
http://yosefk.com/blog/my-history-with-forth-stack-machines....
Has some good quotes on it if you scroll down to the end
i wonder whether you've worked with Forth - in my view of Forth (spent 1987-89 mostly in Forth running on 8088 clone based terminal of USSR clone of IBM 360, so Forth is my second language after mandatory Pascal and the first true "computer" love really) what you said is a huge advantage and natural characteristic of Forth, not a deficiency. Everything in the Forth world is like Salvador Dali's clock face plates - flexible/pliable/flowing and you build whatever "higher-level" constructs and complexity levels you need right now and leave them behind the moment you don't need them anymore, create and destroy worlds as you go... In comparison to that the static monstrosity like NT kernel is just dead dusty world of an ancient complex tech civilization who died off under the weight of its own complex tech.
To Cyph0n below: man, as an enterprise programmer for 25 years i completely understand and agree with you. As that Forth programmer enjoying it 3 decades ago i can only say to you - you just don't get it :)
The goal of the analogy was to demonstrate that OKAD is not suitable for designing large circuits, just like using assembly to write a modern kernel is not practical.
Maybe he didn't want to design a moderately complex chip to begin with? His 144 core chip is likely very simple. OKAD may have been sufficient.
"My VLSI tools take a chip from conception through testing. Perhaps 500 lines of source code. Cadence, Mentor Graphics do the same, more or less. With how much source/object code?
– Chuck Moore, the inventor of Forth
Source: http://yosefk.com/blog/my-history-with-forth-stack-machines....
500 lines are actually possible since Forth words are threaded. That means, any new defined word w can take advantage of all available predefined words. Follwing words can take advantage of w, etc. Forth words are not just simple procedures but they can also comprise new syntax structures. Forth words can be "procedures" or "macros", and both can be mixed freely.
Threaded code was the main reason why Forth was so successful in the first years when memory costs were a real issue.
I got really excited about it, and when I finally started learning it, I had very high expectations and really wanted to love it. Unfortunately, overall those expectations were not met. I did find the experience enlightening, as it was a pretty different way of programming, and I love to gain new perspectives. That said, I was disappointed to find Forth was mostly an obfuscated, write-only language.
Many in the Forth community preach that one should write only very short, well-documented "words" (ie. functions) that are clear and easy to understand. But the reality in the Forth code that I've seen was a lot of long, poorly documented, convoluted words which were a nightmare to read or debug. Granted, this was in the open source community. I've heard that the code in commercial Forths is in a much better state, but I don't have any experience with that.
One also seemed to have to write a lot of one's own code in Forth, because there just really weren't that many libraries you could lean on. I guess I prefer the more batteries included approach. I've also heard even Forth fans admit to me that writing Forth was painful and that the point of using Forth was to write yourself a higher level language as quickly as possible, so you don't have to work in Forth.
Well, I'm personally not all that interested in writing languages myself, and am quite content to use a pre-written language where all the hard and boring work was already done for me by someone else, and I can just use the nice higher-level features that already exist in these high level languages.
I guess if you're on a resource-starved system like some tiny microcontroller, using Forth over assembly might make sense. But as I usually work on relatively powerful desktops or servers, I don't really see the point of using Forth there at all. I'd just rather save myself the pain and hassle, and use any of number of existing high level languages to begin with.
As for Moore's work, I kind of see it like the work of someone building the Eiffel Tower out of toothpicks. It's certainly an impressive accomplishment. But how practical is it?
I'm also not sure how much Moore subscribes to what have become well-accepted software engineering practices such as having good documentation, clarity of code, and testing. It seems like he prefers to sacrifice all at the altar of size and performance. That's great as far as it goes -- if that's all that's important to you and you can make it work for you (and he certainly made it work for him). But looking around at the mountains of poorly documented hacky spaghetti code in the rest of the world, it just seems like following that path leads to an unmaintainable, buggy mess.. unless maybe you are Chuck Moore and can make it work anyway.
Taking a step down like that when coming from a modern environment is really hard. But when looked at from the other direction, as a step up from assembler and a way to become much more productive while at the same time reducing the amount of space bugs have to hide in it makes a lot more sense.
But in the present day it's no longer very useful unless you are doing something embedded or if you want to entertain yourself with an eternal match of code golf.
In some cases it doesn't matter which parameters are going to which functions, and the reader can get a sense or enough of a sense, from the choices of names the programmer made. You can get by without knowing.
But in many cases it is vital to know which parameters are being passed to which subroutine, in order to understand an algorithm. For most people, having to puzzle and re-puzzle this out while the program is being studied is too much extra work or extra ambiguity, or, they just don't buy having to put up with it, given the ready alternatives.
Those specific markings -- parentheses around function calls -- makes a big difference in readability overall.
I don't know if it would work for forth - too low level - but for something like Factor I could see it being really useful.
Moore, from my perspective, decided to bootstrap a computing architecture from as primitive and restrictive of a starting place as he could come up with. Forth makes sense as a language if you imagine yourself as a time-traveller stranded in the 1970s (or even earlier!), trying to get a "foothold" into your futuristic programming environment using the wimpy computers of the era, so that you could design and build the hardware on which would run the software that you actually wanted to write. (Which would, in turn, fix your time machine or whatever.)
Learning Forth isn't really a step on that path. Rather, designing your own minimalistic language under the constraint that it'd have to 1. run on the wimpiest hardware you can imagine, but 2. allow you to be productive in the rest of the bootstrapping process — that's the first step on the path to being Chuck Moore.
I think that's understating it. I would consider any of those accomplishments to be a monumental undertaking. Combined, it is legendary.
If there is ever any doubt as to the existence of the 100x programmer - I would think this guy is proof. Somebody who creates their own chip design software as a means to creating their own multicore processor to run their own language, faster, is a motivated genius.
One of my favourite blog post by Moore is where he builds up to generate the vga signal needed to drive his monitor from the ga-144. Sadly the code links are dead, even at archive.org - but the text remains:
https://colorforth.github.io/video.htm
https://web.archive.org/web/20160310112830/http://colorforth...
He was on a PC, and thought that my Mac GUI was neat. So he wrote a portable GUI framework from scratch in Forth that had dialogs, buttons, pull down menus, text inputs, graphics, mini Mac clone. It was magic. I think it was way under 100K.
After that, I really wanted to become a Forth wizard. I tried, but it never clicked, my code was very clumsy, write only. I admired my coworker as an almost alien intelligence.
I think it really works well for coders spiritually close to hardware.
I really like that Lua doesn't ship much in the standard lib, but what it does ship can be used to build the world.
You've got just one data structure, the table, and from that you can implement just about anything else... efficiently.
Thinking Forth is a pretty good starting point and in general a great programming book http://thinking-forth.sourceforge.net/
The Tcl shell is really great for doing this. Since everything can be represented as a string-type, you're able to introspect your defined procedures and dump them to disk.
Whats up with mocking everyone you reply to on this thread?
The programmer knows in their heart that moves, swaps, dupes, drops, etc. - any stack manipulation that doesn't involve a functional change to the data itself - is an inefficiency to be minimized, but this effort isn't in any way related to the problem at hand (writing a program to do something) so it's unwelcome mental overhead.
I like puzzles as much as the next person, but not so much when they seriously impede the solving of a bigger more serious puzzle, nor when the sub puzzle solving is an exercise in the minimization of something bad rather than the elimination of it.
Edit: Be aware however, variables dramatically reduce composability (in any language actually, most just aren't very composable to begin with). By using local variables you essentially turn a procedure into a monolithic block
I guess I'm just trying to counter all the mythos and happy talk surrounding Forth and stack processing in general. In the end Forth is a highly (too?) simplistic language, a product of its time, and nothing all that special or powerful. It does a lot of stuff poorly and the code tends to write-only. The syntax is so loose that the entire dictionary has to be searched to know you're dealing with a number. It's no mystery that we aren't all coding on it now.
It reminds me of when, e.g., a 1990s-2000s Windows user needed a small program that does one thing, and in order to get it, the download from Microsoft was an installer with hundreds of megabytes of unneeded binary files. It was not possible to download only the single program, which was no more than 1-2MB in size.
It reminds me of this quote: "The problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." - Joe Armstrong
It reminds me of bloat, of giving users things they do not need. A problem that continues to this day.
Instead of bloated, complex UEFI, I wish something like OpenBIOS/OpenFirmware/SmartFirmware/OpenBOOT would be available for today's hardware. I have played around with fgen on i386 and read some of the history. They even provided courses on how to write drivers. Besides OLPC, why did this not catch on?
IMO, Forth is the most elegant and flexible language for initializing hardware.
That might have been more to do with how hard publishing code to the web was back then, an internal process problem, which discouraged tiny stand alone exes from being put online.
The problem is corporate policy. In the yee old days, publishing content to MSDN was not easy. Bill Gate's rant[0] on this topic gives some insight.
Grabbing small EXEs is now a lot easier. See: https://docs.microsoft.com/en-us/sysinternals/
[0]http://blog.seattlepi.com/microsoft/2008/06/24/full-text-an-...
What Joe Armstrong (who I admire) complains about is actually what I love about OO languages. And for me that's the true essence of what OO is, and how it differs from non-OO. People keep trying to frame OO in terms of mutability (completely orthogonal) or C++/Java coding practices (C++ doesn't define OO because it has objects, anymore than it defines FP because it has lambdas).
The real difference, the real paradigm shift is in data + functions vs objects. And I maintain that objects are more powerful and better idea than data + functions. The banana can't be peeled without the gorillas opposable thumbs.
I guess in my mind FP and OO are orthogonal. If I write an immutable object and I send it messages that are referentially transparent, am I not doing both? Would it help FP people if they thought of such objects as "a record of partially applied functions"? So I hope both. I'd love if there was a statically typed, high level pure OO language without all the cruft of Scala or C#. Maybe I have to wait for the next programming fashion cycle for that to happen.
> Thanks for posting your feeling on OO. In some ways I've always felt very restricted writing OO (even in Python), but learning Smalltalk is making me see it from an entirely different perspective.
I often wonder if I need to coin a better term for "OO" for what I am talking about. Alan Kays whole schtick was that objects contained both data and procedures, but by combining them they became something new, and more than just the sum of their parts. That's the powerful idea to me. But language changes, and OO in 2017 just means "Java".
Or the QNX demo disk back in the day. OS, GUI, web browser (with javascript), full clustering support, and more, on a single 1.44MB floppy.
My personal theory why Rebol/Red didn't succeed in the mainstream is steep learning curve, it's hard to discover how to do things if you haven't already done some substantial programming work in it. While built-in help is good you need to know what you're looking for. (Delphi had better help in this matter, with examples etc.).
By the way I wonder why Pecan's post is [dead], it doesn't seem to be violating any rule.
The worst-case scenario is when you open the account in question and every single comment is grey... it hurts to see. (In that case, the account itself has been flagged. Not quite the same as reddit's shadowbanning, but only technically not the same.)
It's bittersweet that the moderation here is paid: there are AFAIK only two people (but don't quote me on that). There were some hazy plans to give some users fractionally elevated capabilities at some point, but it just hasn't happened yet.
Is that true of Red? I was playing with it the other day and it looked really promising, and I was under the impression that it’s still quite new and hasn’t reached 1.0 (my point is that it might not be at a stage where we can write it off).
According to the main page [0] the project was unveiled 6 years ago. For comparison Rust (a random example) started 7 years ago [1] but compare results for "Rust" and "Red/Rebol" on Algolia [2] (sorry no deep links). It's clear Red is niche.
I'm not writing it off. It's definitely one of most interesting languages and runtimes but it's super hard to capture people's attention nowadays when you don't have support of large companies (Go, Rust, .NET).
[0]: http://www.red-lang.org/search?updated-max=2011-03-29T15:38:...
[1]: https://en.m.wikipedia.org/wiki/Rust_(programming_language)
I am not 100% sure but I think Q is actually K plus a standard library of "Q words" so you can write K directly if you want.
I think the reason for Q is as a more familiar interface for people with SQL experience.
It's interesting because Rebol and K have almost totally opposite philosophies about how software should be structured. K emphasizes flat namespaces and leans heavily on the primitives and only a handful of functions. Rebol encourages writing DSLs to fit the language to the problem.
But despite different philosophies, they both allow incredible programmer productivity. I think a lot of this productivity comes from adherence to "Do not speculate!" and therefore not having a bunch of non-useful functionality or boilerplate for the end-user programmer to have to manage.
https://news.ycombinator.com/item?id=13797797
See also the top comment by Dang, with a link to the original thread.
Yes, I'm mad that the subject of the above URL is still, to quote the article, "dark."
Ignore the occasional statements in forum threads about how Forth is so powerful.
Forth is not powerful. It is ugly, stupid and mean.
Because of this, you simplify, simplify and simplify again, up to the project's specs if you can.
That's a statement of someone who doesn't understand Forth. Of course, one can write ugly code easily. Any language with raw power (Asm, C, Forth, Ada) needs a disciplined developer to get beautiful and maintainable code. Forth code can be really beautiful if the vocabulary is well thought out.
I consider Forth the best choice for tiny iOT devices, Firmware, and other essential things which can be kept simple and stupid, following the KISS principle which works very well in many cases.
Our vastly proliferated software security problems come from complexity which developed by despising the KISS principle. Many developers didn't choose the simplest way, they chose the most convenient way. Now, we realize that keeping things simple and stupid is not that bad after all.
"ugly, stupid and mean" is actually intended to the beginners or to those who want to try it. That's what most systems are out-of-the box, especially for the minimal ones (bigger systems like gForth might be a bit better).
That's their starting point. R> and R> are hideous so at one point they'll want to replace them with "pop" and "push". Stack juggling looks bad so they'll have to learn to minimize them. And they'll have to get used to RPN. There's no GC and not even heap allocation (unless ANSI-Forth added it as an extension since the last time I checked?), so they'll have to deal with the lack of memory management that are in every other high-level language. There's neither static nor dynamic type checking so they won't get any warning if they dereference a character. Instead, it will crash again and again without any stack trace.
So they'll have to deal with all this ugliness, stupidity and hostility that they won't expect "enough" because Forth fans praise it often without a warning about the fact that it takes a really long time to fully tame such a rabid language.
Why did I stick with Forth for so long? I made it progressively more beautiful for me; I learned to fight complexity and factor, which indirectly prevents mistakes; I implemented warnings in my system for mistakes that are hard to find (e.g. a redefinition) and are easy to check for.
When I encountered Forth first (6502 figForth) I felt it quite convenient. At that time there were only two other options - Basic and Assembler. Maybe that most developers today are too pampared by all the available IDEs for other languages. It's the same attitude why so many people stick with Windows instead of learning OSX or Linux, despite all the flaws of the Windows ecosystem.
> lack of memory management that are in every other high-level language
As already mentioned, I consider Forth suitable for tiny systems, iOT, Firmware etc. I would never use Forth for big software. I would not use even C++ for that. In that area Ada, Rust or Nim works much better for me.