I once had a programming contest with someone else, while I was in college in 1981, to see who could write the fastest routine to clear the screen using Forth. Defeat was conceded when the routine started producing interference lines on the screen because I was clearing the screen faster than it was being updated. What I did may be considered a bit of a cheat though, because the version we were using included the ability to include in line assembler code. So, by initializing a processor register as a memory location counter, and another instruction which wrote either 00 or FF out to consecutive memory locations based on an increment counter, I was able to decrease the time to update the screen considerably. The processor we were using was the LSI 11. A simplified version of the PDP 11. The computer was produced by Terak. I hope you enjoy my little walk down memory lane. If you are a computer programmer, either as a professional, or a hobbyist, "Happy programming."
a few months ago I prepped a forth demo showing how stack-based programming works, and then showed how you can use javap to get the bytecodes of a java program and show the pushing and popping of variables onto the same concept of a stack. Glad to see us reaching back to our roots and sharing concepts!
Final recommendation: once you've read and understood "Starting Forth" find a copy of Leo's second Forth book, "Thinking Forth"... it will be well worth your time, even if you program in other languages.
@Simon Read the reason people make the statement that "FORTH is a stack based language" is BECAUSE it has two stacks, and one is used specifically for parameter passing, and almost exclusively by the user or the user's programs, and is accessible TO the user. In those other languages you mentioned that have stacks, they are nearly always "off limits" to the user... trying to put numbers on the "stack" in any of those other cases will almost certainly cause a program crash, just as it would in FORTH if one uses the "Return Stack" without following the rules of using the "Return Stack" In other languages, the "Return Stack" is "hidden" (as in "information hiding") from the user. It's a "Black Box", and in FORTH, the "Return Stack" is usually a black box as well, except for very advanced users. The beginning programmer in FORTH who treats the Return Stack like the Parameter Stack will have serious problems. That's why FORTH is referred to a "Stack based" and most FORTH programmers talk about "The Stack" as if there were only one. Anyone who knows FORTH knows there are two stacks, and how to use both,. but it's still a "Stack Based Language" in ways that none of the others you mention qualify as.
@Simon Read no, I was not contradicting you, nor did I think I was. I was simply trying to explain why FORTH is called a Stack Based language, It has nothing really to do with how many stacks. It is because in FORTH the user typically uses the Parameter Stack, while I know of no other language (except those that are variants of FORTH) where that is the case. Certainly, one COULD use the return stack or an arithmetic stack in some other languages, but the language is NOT made to do things that way. I am simply trying to clarify, for those who may not be as familiar with FORTH who might be reading this, why and how FORTH is different. I was just trying to clarify the "English Language" to make it a bit more easily understood by someone who was unfamiliar with FORTH and it's use of a Stack, which is fairly unique among languages. But whatevs dude... you are right about everything and I'm just copying you while pretending to contradict you... am SOOOOOOO sorry. I bow to your superior wisdom in all things.
the most propabale reason you're getting a weird error message instead of "Empty Stack" is because Forth normally uses disk blocks (from old timey floppy disks) and stored error messages in Block 15 (If I remember right) Since you're preobably working on a modern PC with a hard drive, it's likely there's a file that emulates the old "blocks" system, but it's quite likely they didn't bother to include the standard error messages in block 15 of their file. Also, to illustrate the booleans, you should have switched to binary notation (if your implementation has a "bin" word... and if not, just store a 2 in BASE (then FALSE would be printed as 00000000 and TRUE as 11111111)
I did a lot of Machine center automation in Forth back in the 80's for the Lumber processing industry. We were able to bring up projects very quickly. The development tools were embedded in the application, makes it easy to make changes and diagnostics to a system when it is running. Yes it is possible to have pre-compiled modules in Forth but this requires extensive knowledge of the target system memory model, and execution model. But of course if you know what you are doing, it isn't hard as Forth is an extensible language. This kind of thing is often avoided in other languages where it is more important to have processor independent code. Most languages are more fundamentally machine independent by design (except possibly C for embedded applications)
To make your mind blow off.... This is factor code too: USING: imperative.if imperative.yield imperative.let imperative.invoke imperative.while :: myswap ( x y -- y x ) YIELD y ; YIELD x ; ; :: factorial ( x -- x! ) drop f ; ! hackz to predefine a words to override :: factorial ( x -- x! ) IF x = 0 THEN{ YIELD 1 ; } ELSE{ IF x = 1 THEN{ YIELD 1 ; } ELSE{ YIELD x * factorial(x-1) ; } ; } ; ; So you can basically make a "dictionary" that defines the word "IF" or "YIELD" and from that on they are macro-expanded in a simple and elegant way when the compiler reads those words. It is not like other languages macro's, but small "scripts" written in factor itself and are much more than simple text substitutions... Download "imperative.zip" and see examples on this page: nyelvek.inf.elte.hu/leirasok/factor/index.php?chapter=15#section_3 (it is a factor tutorial I wrote in Hungarian - sorry guys it was for a university assignment I choose to make the tutorial, but the code examples are readable)
And there is the "locals" vocabulary as well that provides lexically scoped local variables. It is especially useful for equations and whatnot. So instead of stack shuffling, you could just write: USING: locals math math.functions kernel ; IN: scratchpad :: quadratic-roots ( a b c -- x y ) b sq 4 a c * * - sqrt :> disc b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@ ; The stack-based version is not too readable. :D A simple example: :: my-3array ( x y z -- array ) { x y z } ; 1 "two" 3.0 my-3array --- Data stack: { 1 "two" 3.0 }
I actually implemented a structural programming language that resembles basic in a Factor-dictionary. nyelvek.inf.elte.hu/leirasok/factor/index.php?chapter=15#section_3 ^^The descriptions about Factor is in Hungarian (which I made too) but the source code you can easily see here with usage examples. If you import my dictionary you can use IFs, LOOPs, expressions in their usual form (not in a reverse polish notation, but in a "normal" one), variables and mutating the state of variables just like in "normal" languages and all the stuff like that. This is made accomplishable because one can literally "script" the compiler / interpreter itself in Forth when it reach a word of your choice and "exchange" it with other words that were already defined. This is like a controlled macro.
Hi, Nice! Regarding Forth, are you aware of a forth command which displays word definitions? I know there is a command called “words” which displays all the dictionary words, but is there a command to display the code behind each word?
a much faster version of your absolute example would be to simply ABS whatever number you have on the stack, whether it's negative or not... comparisons are one of the slowest things a computer has to do, eliminating comparison operations is a great way to speed up your code. (again, assuming you have an ABS word defined on your system, and assuming it was coded in assembler, rather than just being a copy of your high level Forth function)
I once had a programming contest with someone else, while I was in college in 1981, to see who could write the fastest routine to clear the screen using Forth. Defeat was conceded when the routine started producing interference lines on the screen because I was clearing the screen faster than it was being updated. What I did may be considered a bit of a cheat though, because the version we were using included the ability to include in line assembler code. So, by initializing a processor register as a memory location counter, and another instruction which wrote either 00 or FF out to consecutive memory locations based on an increment counter, I was able to decrease the time to update the screen considerably. The processor we were using was the LSI 11. A simplified version of the PDP 11. The computer was produced by Terak. I hope you enjoy my little walk down memory lane. If you are a computer programmer, either as a professional, or a hobbyist, "Happy programming."
a few months ago I prepped a forth demo showing how stack-based programming works, and then showed how you can use javap to get the bytecodes of a java program and show the pushing and popping of variables onto the same concept of a stack. Glad to see us reaching back to our roots and sharing concepts!
Final recommendation: once you've read and understood "Starting Forth" find a copy of Leo's second Forth book, "Thinking Forth"... it will be well worth your time, even if you program in other languages.
@Simon Read the reason people make the statement that "FORTH is a stack based language" is BECAUSE it has two stacks, and one is used specifically for parameter passing, and almost exclusively by the user or the user's programs, and is accessible TO the user.
In those other languages you mentioned that have stacks, they are nearly always "off limits" to the user... trying to put numbers on the "stack" in any of those other cases will almost certainly cause a program crash, just as it would in FORTH if one uses the "Return Stack" without following the rules of using the "Return Stack"
In other languages, the "Return Stack" is "hidden" (as in "information hiding") from the user. It's a "Black Box", and in FORTH, the "Return Stack" is usually a black box as well, except for very advanced users. The beginning programmer in FORTH who treats the Return Stack like the Parameter Stack will have serious problems.
That's why FORTH is referred to a "Stack based" and most FORTH programmers talk about "The Stack" as if there were only one. Anyone who knows FORTH knows there are two stacks, and how to use both,. but it's still a "Stack Based Language" in ways that none of the others you mention qualify as.
@Simon Read no, I was not contradicting you, nor did I think I was. I was simply trying to explain why FORTH is called a Stack Based language,
It has nothing really to do with how many stacks. It is because in FORTH the user typically uses the Parameter Stack, while I know of no other language (except those that are variants of FORTH) where that is the case. Certainly, one COULD use the return stack or an arithmetic stack in some other languages, but the language is NOT made to do things that way.
I am simply trying to clarify, for those who may not be as familiar with FORTH who might be reading this, why and how FORTH is different.
I was just trying to clarify the "English Language" to make it a bit more easily understood by someone who was unfamiliar with FORTH and it's use of a Stack, which is fairly unique among languages.
But whatevs dude... you are right about everything and I'm just copying you while pretending to contradict you... am SOOOOOOO sorry. I bow to your superior wisdom in all things.
thanks for linking to Factor and pointing me to this implementation I enjoyed
the most propabale reason you're getting a weird error message instead of "Empty Stack" is because Forth normally uses disk blocks (from old timey floppy disks) and stored error messages in Block 15 (If I remember right)
Since you're preobably working on a modern PC with a hard drive, it's likely there's a file that emulates the old "blocks" system, but it's quite likely they didn't bother to include the standard error messages in block 15 of their file.
Also, to illustrate the booleans, you should have switched to binary notation (if your implementation has a "bin" word... and if not, just store a 2 in BASE (then FALSE would be printed as 00000000 and TRUE as 11111111)
I did a lot of Machine center automation in Forth back in the 80's for the Lumber processing industry. We were able to bring up projects very quickly. The development tools were embedded in the application, makes it easy to make changes and diagnostics to a system when it is running. Yes it is possible to have pre-compiled modules in Forth but this requires extensive knowledge of the target system memory model, and execution model. But of course if you know what you are doing, it isn't hard as Forth is an extensible language. This kind of thing is often avoided in other languages where it is more important to have processor independent code. Most languages are more fundamentally machine independent by design (except possibly C for embedded applications)
I wish there were more SBC or microcontrollers ( like Arduino or 8051 ) that had FORTH as default. Also PLCs ...
Me too. It is such an elegant solution it could have changed the whole paradigm.
To make your mind blow off.... This is factor code too:
USING: imperative.if
imperative.yield
imperative.let
imperative.invoke
imperative.while
:: myswap ( x y -- y x )
YIELD y ;
YIELD x ;
;
:: factorial ( x -- x! ) drop f ; ! hackz to predefine a words to override
:: factorial ( x -- x! )
IF x = 0 THEN{
YIELD 1 ;
} ELSE{
IF x = 1 THEN{
YIELD 1 ;
} ELSE{
YIELD x * factorial(x-1) ;
} ;
} ;
;
So you can basically make a "dictionary" that defines the word "IF" or "YIELD" and from that on they are macro-expanded in a simple and elegant way when the compiler reads those words. It is not like other languages macro's, but small "scripts" written in factor itself and are much more than simple text substitutions...
Download "imperative.zip" and see examples on this page:
nyelvek.inf.elte.hu/leirasok/factor/index.php?chapter=15#section_3
(it is a factor tutorial I wrote in Hungarian - sorry guys it was for a university assignment I choose to make the tutorial, but the code examples are readable)
And there is the "locals" vocabulary as well that provides lexically scoped local variables.
It is especially useful for equations and whatnot. So instead of stack shuffling, you could just write:
USING: locals math math.functions kernel ;
IN: scratchpad
:: quadratic-roots ( a b c -- x y )
b sq 4 a c * * - sqrt :> disc
b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@ ;
The stack-based version is not too readable. :D
A simple example:
:: my-3array ( x y z -- array ) { x y z } ;
1 "two" 3.0 my-3array
--- Data stack:
{ 1 "two" 3.0 }
@@imzoltan The "imperative" dictionary however is my own work ;-)
@@u9vata I know. I mentioned it for people who may not know about it. :)
great.... next lesson?
wharg; it is 2:32 AM and I am watching this video via a tweet you promoted on Twitter.
6:32 not sure why it gave you the wrong answer 47 * 23 = 1081 (not 985)
Factor is really cool.
I actually implemented a structural programming language that resembles basic in a Factor-dictionary.
nyelvek.inf.elte.hu/leirasok/factor/index.php?chapter=15#section_3
^^The descriptions about Factor is in Hungarian (which I made too) but the source code you can easily see here with usage examples.
If you import my dictionary you can use IFs, LOOPs, expressions in their usual form (not in a reverse polish notation, but in a "normal" one), variables and mutating the state of variables just like in "normal" languages and all the stuff like that.
This is made accomplishable because one can literally "script" the compiler / interpreter itself in Forth when it reach a word of your choice and "exchange" it with other words that were already defined. This is like a controlled macro.
Oh wow, thank you for bringing Factor to Hungary, so to speak. :) If you would like to collaborate, let me know!
Here's a more detailed explanation and is a little more practical:-
www.physics.wisc.edu/~lmaurer/projects/FloatingAway/FloatingAway.html
Hi, Nice! Regarding Forth, are you aware of a forth command which displays word definitions? I know there is a command called “words” which displays all the dictionary words, but is there a command to display the code behind each word?
Rijesh Panicker thanks! SEE seems to show the address location, pretty cool.
Brodie is god.
a much faster version of your absolute example would be to simply ABS whatever number you have on the stack, whether it's negative or not... comparisons are one of the slowest things a computer has to do, eliminating comparison operations is a great way to speed up your code.
(again, assuming you have an ABS word defined on your system, and assuming it was coded in assembler, rather than just being a copy of your high level Forth function)
Heh, you almost got it right. It is just `true hex.`. :)
tytyty
ywywyw 😀