- How much of this is true, and in what way and/or to what extent?
- Is it possible to compile native code, and how would one go about
it?
- Is the source code included (to study)?
- Which package is worth learning from the ground up? (and where can I
get it?)
> After reading quite a bit about Forth, my interest is definitely
> piqued! I have read that it is possible to hold the entire language
> in your head at once! I've read that a Forth system comes with a
> compiler, the editor, the runtime library, and the very operating
> system itself! I've also read that all of this only takes up a few k
> of memory!
>
> - How much of this is true, and in what way and/or to what extent?
Not a "few". It depends a lot on what you're including into the system.
> - Is it possible to compile native code, and how would one go about
> it?
It is possible. The second part depends on the system.
> - Is the source code included (to study)?
It depends on the system, Forth isn't single-implementation language.
> - Which package is worth learning from the ground up? (and where can I
> get it?)
Prepare to get many different controversial responses.
To make things more interesting, I propose FIG Forth, eForth, and Pygmy.
--
CE3OH...
No. Write applications, not virtual machines.
Solve real problems, not virtual ones.
--
CE3OH...
The best way to learn Forth is to use it to write programs. The best
way to learn to write better programs is to look at your programs and
figure out how to make them better (smaller, faster, more readable,
whatever your goal is).
In my advanced Forth courses we have a "course project" which is a
simple application that everyone has 3 days to write and test (between
lectures and specific problem set assignments). There's a prize for the
smallest compiled working program and for the most readable program
(class members get to vote). Students learn the "economics" of various
programming choices (what makes programs smaller, faster, more readable,
etc.) along with what it takes to write readable code (readable by their
classmates).
I'm not sure that learning how the virtual machine works helps, although
it's certainly interesting. Does knowing how an automobile engine works
make you a better driver?
Cheers,
Elizabeth
--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com
"Forth-based products and Services for real-time
applications since 1973."
==================================================
True, but on the contrary! Having the VM down-pat (from an API
perspective, not implementation) really helps, I think. Personally, I
made the mistake of trying to understand the VM from "under the hood"
so that I could understand Forth's "essence". And now I think I would
have rather understood only a third of what I know! I think that all
the mysticism around Forth puts it on a really unnecessary pedestal
which makes you think there must be some "magic" to it, but there's
not. It's just a really useful tool and its true essence is keeping it
simple and to do that don't bury yourself in technical details!!!
It's a waste of time!
With the VM, you want to be a good stack juggler (know when you are
using too much of the stack! but at the same time get good at
visualizing what's currently on it and what the different stack words'
effect will be.) and, I think you want to "feature the stack", because
it reduces variable usage and can simplify your API's syntax. And also
its good to understand the special uses of the return stack such as R>
DROP, or R> EXECUTE ( or CALL ) because it lets you do some
potentially useful syntactical "tricks".
Same goes with the A register which is part of a "non-standard"
version of the Forth VM, something I love to use for simplifying some
routines. See the SeaForth chip's programming manual for these words:
A! @+ !+ ... very easy-to-add words.
Forth is the stacks, the dictionary, cells, and words. Beyond that
it's the programmer's to create.
> On Jul 28, 3:50 pm, Aleksej Saushev <a...@inbox.ru> wrote:
>> ilikemachi...@cox.net writes:
>> > Thanks! I found source for eForth written in forth. Once I get forth
>> > learned better, I'd like to comprehend the virtual machine as well as
>> > I can. Is this a good tactic to becoming a good Forth programmer?
>>
>> No. Write applications, not virtual machines.
>> Solve real problems, not virtual ones.
>
> With the VM, you want to be a good stack juggler (know when you are
> using too much of the stack! but at the same time get good at
> visualizing what's currently on it and what the different stack words'
> effect will be.) and, I think you want to "feature the stack", because
> it reduces variable usage and can simplify your API's syntax. And also
> its good to understand the special uses of the return stack such as R>
> DROP, or R> EXECUTE ( or CALL ) because it lets you do some
> potentially useful syntactical "tricks".
It is way better to learn using some better "tricks", like "catch"
and "throw", or even more high-level constructions, like "try" &
"recover", this is more productive and save you the time
someone spent in past doing that syntactic work for you.
> Forth is the stacks, the dictionary, cells, and words. Beyond that
> it's the programmer's to create.
Forth is a bit more than just stacks, storage, and dictionary.
Of course, you can start from ground level, but that is just a
waste of time.
--
CE3OH...
Oh come on you don't think I meant Forth literally is nothing but
that. Clearly each system has lots of stuff. I meant to point those
out as the essential conceptual tools you manipulate with when you
program in Forth; everything else is tools built with those. Yes even
the edit, compile, test times and fluency and create does>, all these
nice things are just Forth's higher level tools that have become
mainstays. I meant to be encouraging by keeping it simple.
I'm not sure what you mean. I only use CATCH and THROW to manage
errors. And they're not tricks at all, they're formalized ANS.
With R> you can say : VECTOR> R> 'VECTOR ! ; and voila, one-word
callback definer. ( so you can say : DEFINE-VECTOR VECTOR>
CODE ; ) It's a trick that relies on the workings of the stack but
that's Forth. And if your system doesn't have R> for some reason you
can always write it...
I say definitely start from the ground level and slowly accrete high-
level knowledge. As the saying goes ... you have to learn to walk
before you can learn to run ... so don't use tricks until you have
the basics!!! I just meant to show what is possible when you know the
VM...
<snip>
> With R> you can say : VECTOR> R> 'VECTOR ! ; and voila, one-word
> callback definer. ( so you can say : DEFINE-VECTOR VECTOR>
> CODE ; ) It's a trick that relies on the workings of the stack but
> that's Forth. And if your system doesn't have R> for some reason you
> can always write it...
I can't think of any Forth that doesn't have >R and R>. Every Forth has at
least two stacks ;-)
But the word VECTOR> is not portable. I.e. some implementations might have
a different width for the data and return stacks. A portable use of >R and
R> is storing temporary values, not execution tokens.
I have an implementation (not my 16 bit CHForth) that inlines the code and
will not compile DEFINE-VECTOR correctly.
Use insted DEFER as is proposed in http://www.forth200x.org/deferred.html
--
Coos
CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html
I've done a FORTH that compiles to microcode for an Am2910/29116 based
controller. The only access the processor has to the return stack is
calling and returning. For that FORTH, I did two types of :-definitions:
normal :-definitions and ::-definitions. The latter type is executing
using a branch rather than a call.
--
roger ivie
ri...@ridgenet.net
> The best way to learn Forth is to use it to write programs. The best
> way to learn to write better programs is to look at your programs and
> figure out how to make them better (smaller, faster, more readable,
> whatever your goal is).
Also study existing Forth code, like the examples that come with the
evaluation versions of commercial Forth packages. They are usually
pretty good. You can find good Forth on the net but there is bad Forth
too.
Having implemented a few Forths, I can say that implementing a Forth
does very little to enhance your Forth skills (other that learning
word semantics). Unless you implement the Forth in Forth, but then
that's not a good beginner activity.
-Brad
That could be a method to protect the user from misusing >R and R>, of
course. In this case, if you have room for it, you might make a third stack
for use with >R and R>. The true returnstack would be still hidden.
If ANS doesn't require the data and return stacks to be the same
width, then that is a ridiculous policy and can be safely ignored. At
least when you are just trying to write simple code, rather than
portable code...
To the newbie: I think you'd do best to just ignore the return stack,
ignore people trying to convince you that you must write portable
code, and ignore the more complicated aspects of ANS. The point of
Forth, and I *hope* everyone can agree on this, is to keep programming
fun and by extension more productive. Even if everyone's definition
of fun and productivity differs... at least let's try to SAY the same
thing. That way people will have the right goal when they approach
it.
Just start playing around putting words together, make some
applications... Elizabeth Rather's advice was best.
Don't get too clever too early on. XD
On Jul 29, 11:30 am, Coos Haak <chfo...@hccnet.nl> wrote:
> Op Tue, 29 Jul 2008 15:16:16 GMT schreef Roger Ivie:
>
ANS doesn't require the return stack to consist of stackable elements...
What ANS specifies is that, for each activation context, there is a
stack-like storage area in which you may write celle values with >R, and
get them back with R>. But these values are accessible only from the
word itself, not from the caller and neither from the callees. Moreover,
you are supposed to clean that stack before exiting from the word.
These provisions are meant to allow the Forth VM to use the same
area for other call-related usages, such as implenting the call-return
mechanism of words.
Hence ANS _mandates_ that there is a return stack where cells have the
same size than cells in the data stack. But ANS _allows_ the VM to push
arbitrary things on that stack when a word calls another word, and pop
them upon return; hence, ANS _mandates_ that code which uses the return
stack be "well behaved" as explained above. This does not prevent a
given Forth VM to actually use a third, hidden stack-like structure for
word calls, in which case the return stack (the one accessed with >R and
R>) may be a perfectly ordinary memory area somewhere.
> ignore people trying to convince you that you must write portable
> code
99% of writing portable code is writing clean code which avoids
""clever"" tricks. Writing clean and readable code is a premium,
and it has the added benefit of enhancing portability.
--Thomas Pornin
Exactly. A standard system must have a Return Stack whose entries are
the same size as cells and data stack items. And it must respond to >R,
R@, and R>. What the standard *doesn't* require is that the system must
use it for return addresses.
And a Standard Program may *only* use R@ and R> for stuff *it* put there
with >R, following the usage rules given. Any assumption about what the
system puts or keeps on the Return Stack introduces a dependency on that
particular implementation.
The reality is that, although *most* systems put return addresses on the
Return Stack, there are a number of platforms on which return info is
somewhere else, and has a different size and/or structure from "vanilla"
addresses.
>> ignore people trying to convince you that you must write portable
>> code
>
> 99% of writing portable code is writing clean code which avoids
> ""clever"" tricks. Writing clean and readable code is a premium,
> and it has the added benefit of enhancing portability.
IMO it is perfectly ok to do something non-portable providing you
*consciously* make the decision that the benefit (size, speed, whatever)
outweighs the cost in terms of potential porting issues, and assume
responsibility for making whatever porting adaptations are necessary in
the future.
Cheers,
Elizabeth
> --Thomas Pornin
> Is there a Forth that has a 32-bit data stack and a 16-bit return
> stack? Or vice versa? The idea that the stacks must be mutually
> exclusive for the sake of some principle of portability not only makes
> the existence of >R R> almost useless, it also locks out a large
> amount of Forth's power. Not only that but I can't think of a case
> where you'd expect code written for a 32-bit Forth to also work on an
> embedded 12-bit Forth, simply because it's "ANS". (Of course, in that
> case, the smart thing to do would be just to not USE the return
> stack... right??? :)
I just checked F-PC, a 16 bit Forth that was extensive used some ten years
ago. It is not ISO/ANSI standard (it could not be, as it was older than
1995). The data stack was 16 bit, but colon definitions used 32 bit
pointers on the return stack. If one used balanced pairs of >R and R> in
the same definition, it worked nice. To manipulate return addresses, the
responsible programmers might use 2R> and 2>R.
Frankly, I am shocked. ANS defines Forth's return stack that way?
That's odd to me.
Forth's RETURN stack, NOT being used for RETURN call addresses? Is
there a Forth that does that? That seems like a really confusing
feature. And programmers are encouraged to read the standard, aren't
they? Isn't it a bit complicated for them to have the return stack
described to them that way?
Ok, there are some tricks you could do in a Forth program that would
be totally wrong to do.
R> 1 + >R would be dumb. Everyone knows that Forths today can be
subroutine threaded.
But R> should get you whatever you expect to be on the return stack,
and that should be clearly defined. Everyone knows that in Forth the
return stack stores RETURN addresses. And sometimes loop counters.
And sometimes whatever you put there yourself. Not only do I think
ANS has it wrong, I don't think it's defining things clearly enough,
and that makes me sad.
Hmmm, this makes me want to try to think of more bad tricks....
Oooh. I know one. And I'm actually guilty of it. Storing a low-
order byte directly into a cell. Not only is it unclear what the
effect will be, but it depends on endian-ness. I should probably not
do it directly and instead encapsulate it into a clearer word.
Does anyone know some more bad tricks to avoid they'd like to share
with the group? I'd really be interested in talking more about the
subject!
Well, yes. Earlier I mentioned a FORTH I've done that compiles to
microcode for an Am2910/29116 bit-slice based controller. In that
system, the only access to the return stack *at all* is call and return;
the processor simply has no other access to that stack. Among other
things, that also means I can't EXIT.
Of course, it's not ANS...
--
roger ivie
ri...@ridgenet.net
My first impulse was to tell you to grow up. I suppress it. The return
stack is called that for historic reasons, just like Lisp's CAR and CDR.
Although it is possible in some systems to use R> DROP to return to the
word that called the word that contains it, that is a system-specific
oddity, The return stack (rack, for short) defined in the ANSI standard
offers all the permissions and requires all the limitations traditional
in earlier Forths. Why is it important to you that something normally
hidden under the hood should behave in the way that you imagine?
Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
>> Exactly. A standard system must have a Return Stack whose entries are
>> the same size as cells and data stack items. And it must respond to >R,
>> R@, and R>. What the standard *doesn't* require is that the system must
>> use it for return addresses.
> Frankly, I am shocked. ANS defines Forth's return stack that way?
> That's odd to me.
Think about what a 'standard' means.
You seem to think that a standard should prescribe exactly how a language
works, on a theoretically ideal level. The standard committee should not
look at existing implementations (which are all more or less wrong anyway),
and enforce the 'right' way to do things, without any practical
considerations (cpu's without a hardware floating point stack, mainframes
having 71 bit cells and 6 bit bytes, 1-complement hardware, slow floored
arithmetic) or political considerations ('this Harris firm has a very
promissing Forth CPU that is not really Forth, but their chip will be
dead slow if it has to comply with the way 99% of the existing Forths
are doing things, so ...').
Instead, the standard committee tried to find the best possible
compromises. The result is / was that *everyone* was more or less angry
and upset.
In retrospect, ANS Forth has worked great. It is currently possible
to get Forth source from anywhere and understand and use it without
problem. The quality of the implementations has greatly improved.
And tricks like "R> DROP" are *still* possible, but not on every
Forth that claims to be ANS. You sometimes need to do some digging around
to find ways to make it work. That is exactly the same situation as
before :-)
-marcel
Roger Ivie has described one platform on which it's inauspicious to have
a traditional Return Stack. Another is the 8051, where the subroutine
calls use on-chip 8-bit registers -- using those yields much better
performance on a chip that needs all it can get. Chuck Moore's
Intellasys chips have a limited-size circular stack for return addresses.
The purpose of the standard is to define an interface between systems
and programs: what can program writers depend on all systems providing?
By keeping the specification to that interface, the standard has freed
implementors to seek and find ways of delivering far better performance
than systems in the past. I think that is a good thing.
> Ok, there are some tricks you could do in a Forth program that would
> be totally wrong to do.
No, not wrong, just not universally portable. If you're willing to
accept some limitations on portability, you can make a lot of
assumptions. If, for example, you are willing to avoid the
implementations I mentioned above (and maybe a few more) you could
describe your program as having a dependency on a traditional return
stack. It wouldn't limit your portability at all, if all the Forths you
use work that way.
Many programs are dependent on 2's complement arithmetic, and assume
that a 'char' = 8 bits = 1 byte = 1 address unit. They can run just
fine on most Forths, since most Forths work that way. They still have a
dependency, but it isn't a very serious limitation.
The important thing is to be aware of what's portable and what isn't.
It's a practical issue, not a moral imperative.
Cheers,
Elizabeth
This is for abominations like F-PC. F-PC actually used the return stack for
return addresses, but it was a segmented 16 bit system, and the return
addresses were segment and offset (32 bits). So the return stack tricks
didn't work on F-PC. On all actual ANS Forth systems I know (F-PC isn't ANS
Forth), return stack manipulations work as expected.
--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/
> Is there a Forth that has a 32-bit data stack and a 16-bit return
> stack? Or vice versa?
Yes, definitely. For example, an x86 "medium model" Forth has 32-bit
return stack and 16-bit data stack.
> If ANS doesn't require the data and return stacks to be the same
> width, then that is a ridiculous policy and can be safely ignored.
Huh? Why should it matter? All that is really important is that >R
and R> work.
Confused,
Andrew.
> roger...@gmail.com wrote:
>> Frankly, I am shocked. ANS defines Forth's return stack that way?
>> That's odd to me.
> This is for abominations like F-PC. F-PC actually used the return stack for
> return addresses, but it was a segmented 16 bit system, and the return
> addresses were segment and offset (32 bits). So the return stack tricks
> didn't work on F-PC. On all actual ANS Forth systems I know (F-PC isn't ANS
> Forth), return stack manipulations work as expected.
Tut, tut, "abominations" ... F-PC was ground-breaking but made some infortunate
design decisions it couldn't back out of (because of its popularity).
Even though all current Forths use the R-stack what it is meant for,
this doesn't mean "R> DROP" will work (everywhere right away): think
tail-call removal. That's a VERY popular implementation option.
-marcel
> > Exactly. A standard system must have a Return Stack whose entries
> > are the same size as cells and data stack items. And it must
> > respond to >R, R@, and R>. What the standard *doesn't* require is
> > that the system must use it for return addresses.
>
> Frankly, I am shocked. ANS defines Forth's return stack that way?
> That's odd to me.
>
> Forth's RETURN stack, NOT being used for RETURN call addresses? Is
> there a Forth that does that? That seems like a really confusing
> feature. And programmers are encouraged to read the standard, aren't
> they? Isn't it a bit complicated for them to have the return stack
> described to them that way?
Yes.
But look at the history. Forth-83 was defined to be 16-bit. It was
defined in a way that didn't allow subroutine-threading. Etc.
Forth-94 tried to avoid that mistake. The ideal was to let people who
design Forth systems do it however they want, whatever works best, and
still have Forth code that would be portable from one Forth system to
another.
So on the one side implementors are supposed to provide a standard set
of "sockets" that are guaranteed to give the expected results. And on
the other side application developers who use only the standard "plugs"
that fit those sockets can expect their code to work correctly. The
standard defines that interface. You can go around the standard
interface and plug into anything you want on the other side, but the
standard doesn't guarantee it will work for other Forths.
There were trade-offs. How much should implementors have to provide in a
standard way? And they decided that return addresses are outside the
standard. Implementors can implement calls and returns however they want
and you can't depend on, for example. : LATER 2R> swap 2>R ; to work.
But people use the return stack for their own stuff, it's useful to have
a second stack. And what implementors have to provide is a sort of
crippled second stack. You can put stuff on it and take your stuff off,
and you have to clean up all your stuff before the definition ends. You
can't portably depend on the Forth system to do anything useful with
anything you leave on the return stack for it to deal with.
Also anything you put on the return stack before you start a DO loop is
unavailable until the loop is complete, because some Forth systems use
the return stack to store loop data and you can't depend on how much of
the return stack they will use. So you can't do anything like
... DO 2R> R@ -ROT 2>R ...
to get something that's under the loop data. No portable way to do that.
The first little crippling thing is no problem at all -- it's confusing
to pass data on multiple stacks. It might be more efficient to have
words that expect their data on multiple stacks, but it wouldn't be
Forth. The second one is an inconvenience, but it's one that Forth
programmers have always had and so we don't object. It would be easy for
most Forth systems to provide loops without blocking the return stack --
they do it with locals all the time -- but it just isn't the custom.
So anyway, if you want to build a secure Forth system, one that could
run untrusted code and clean up if there are problems -- you could
provide a dummy return stack for users and hide the real return stack,
and still provide all the standard features. This is potentially a
benefit.
> But R> should get you whatever you expect to be on the return stack,
> and that should be clearly defined. Everyone knows that in Forth the
> return stack stores RETURN addresses. And sometimes loop counters.
> And sometimes whatever you put there yourself. Not only do I think
> ANS has it wrong, I don't think it's defining things clearly enough,
> and that makes me sad.
The lack of clarity is a problem. It helps some if you remember that
the intention is to provide a sort of "portability porthole", like a
bunch of cables come through the porthole and it defines what can come
through and how you can use it, but it tries not to say *anything* about
what's on the other side. As far as the standard is concerned, the Forth
system is a black box, and all that's defined is inputs and outputs.
Forth implementors can build the box however they want but if it's
standard it will give you the standard outputs when you give it
standard inputs. You are told *nothing* about how the dictionary works.
All you know is what CREATE : VARIABLE CONSTANT 2VARIABLE 2CONSTANT
FVARIABLE FCONSTANT and VALUE provide on the one side, and what ' [']
FIND SEARCH-WORDLIST and the interpreter provide on the other side.
If you can define a word with CREATE and SEARCH-WORDLIST gives you an
execution token when you give it the string, a system implementor who
finds a way to do that with magic fairy dust can build a standard
system. Standard code just uses the results and doesn't ask where they
came from.
> Hmmm, this makes me want to try to think of more bad tricks....
>
> Oooh. I know one. And I'm actually guilty of it. Storing a low-
> order byte directly into a cell. Not only is it unclear what the
> effect will be, but it depends on endian-ness. I should probably not
> do it directly and instead encapsulate it into a clearer word.
>
> Does anyone know some more bad tricks to avoid they'd like to share
> with the group? I'd really be interested in talking more about the
> subject!
There are lots of them. How about:
: my-structure CREATE C, , ;
my-structure CHAR+ @
On a system where @ addresses ae aligned, you can't do that. One of the
first things I ever posted on clf was about a problem I had where I
tested the speed of some code and found that the obvious way to do it
was nearly twice as slow as a less-obvious way. Other people replied
that it didn't work that way for them, and when I did it again it was no
longer true for me. Very frustrating. It turned out that my PC was
slower to handle unaligned addresses though it could do it. The first
way I tested it, the addresses weren't aligned. but when I added extra
test code, by accident they got aligned.
One standard way to handle this is to do
: my-structure CREATE C, ALIGN , ;
my-structure CHAR+ ALIGNED @
and if your system works just as well with unaligned addresses it will
probably not compile anything for ALIGN and ALIGNED . Another way is to
do
: my-structure CREATE SWAP , C, ;
my-structure @
If you can put all your aligned data in front of all your unaligned
data, the problem will disappear.
Note that if your system does not require aligned data, you won't get
any feedback at all about alignment until your code gets ported to a
system that does require alignment. If you care about portability you
might want an addition to your compiler that warns you when you create
and use analigned addresses. But if you just wanted to get something
working now, it would be an annoyance.
> Earlier I mentioned a FORTH I've done that compiles to
> microcode for an Am2910/29116 bit-slice based controller. In that
> system, the only access to the return stack *at all* is call and
> return; the processor simply has no other access to that stack. Among
> other things, that also means I can't EXIT.
Could you compile a return for EXIT ? It wouldn't work when you're
interpreting, but I'm not sure what an interpreted EXIT ought to do.
Probably about the same as QUIT ?
> > Exactly. A standard system must have a Return Stack whose entries are
> > the same size as cells and data stack items. And it must respond to >R,
> > R@, and R>. What the standard *doesn't* require is that the system must
> > use it for return addresses.
>
> Frankly, I am shocked. ANS defines Forth's return stack that way?
> That's odd to me.
>
> Forth's RETURN stack, NOT being used for RETURN call addresses? Is
> there a Forth that does that? That seems like a really confusing
> feature.
Henry Baker suggested implementing a Forth in which there would be no
returns, with calls being like run time macros going onto an execution
stack that would consume instructions as it went. I don't know if this
was ever implemented, though. P.M.Lawrence.
Well, they might not be there under those names. Pygmy Forth has PUSH
and POP instead. P.M.Lawrence.
>Forth's RETURN stack, NOT being used for RETURN call addresses? Is
>there a Forth that does that? That seems like a really confusing
>feature.
Here are two real-world examples.
Many Forths for 8051s use the machine stack for call/return
addresses, and a simulated stack for the Forth R-stack.
Michael Gassanenko wrote a 32 bit Forth for real-mode x86
systems in which the addresses on the return stack did not
naturally fit what @ and ! required. This Forth became the
MPE x8632 system which was used for large safety-critical
applications.
Nowadays, the requirement for oddball addressing and 3.5
address space CPUs is minimal. The move to native code
compilation has further reduced the desirability of such
CPUs.
Stephen
--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads
Oh, I remember where my idea of how EXIT works came from. In several
FORTHs I've done, EXIT winds up being : EXIT R> DROP ; in other words,
it drops its own return address and returns to its caller's caller.
Can't do *that*, but implementing EXIT as an immediate that compiles a
return (i.e., a synonym for ; that doesn't exit compile mode) would work.
But, then, I'm strange; I've even once done a FORTH that defined + as
: + 0 SWAP - - ; just for fun (especially since it also defined 0
as : 0 DUP - ; (ah, the joys of thinking about minimal wordlists))...
--
roger ivie
ri...@ridgenet.net
...
> The important thing is to be aware of what's portable and what isn't.
> It's a practical issue, not a moral imperative.
I find it frustrating that you always say what I meant better than I
said them myself. :-)
Since EXIT is defined as returning to a calling definition and has no
defined behavior when interpreted, it isn't *supposed* to "work" when
interpreted. Compiling a return is exactly appropriate. This is
exactly the situation we all face when dealing with processors that have
a funky subroutine call/return that doesn't mesh nicely with a Forth
return stack. Use your processor's native behavior for calls and
returns, and make a separate user-accessible "return stack" for >R and
R> & friends.
Cheers,
Elizabeth
If I made a mistake in promoting the joys of using the return stack to
ilikemachi, I'm sorry.
I only think that it is rather stupid to go around with the intent of
silencing different ways of thinking, just because they are not your
own. We can all talk to each other even if we have different ways of
thinking. Surely you realize that there are better things to do than
argue over the value of the standard. I am aware of it.
To everyone else that provided constructive insight, Thanks.
Jonah:
It seems to me, that what remains essential is the ability to know
your platform so that you know what you can do, and so room should be
left for that.
It doesn't have to be a portability issue because instead of having
hundreds of these trick-like constructions around your source code
that rely on data alignment or char width... you could localize these
instances into a few simple words so that the entire app can be ported
without pain.
> I will continue to use the return stack, based on the assumption that
> it will be more or less portable on all the planned target platforms.
There you go. You've planned what target platforms you're interested in,
and it works on them. You're set.
I want to suggest that whatever you want to do, there *is* a way to do
it without using the return stack to change flow-of-control. If you were
to get interested in that topic, you might notice what other methods are
available and whether they're significantly harder to use or less
efficient in execution time or memory space, or readability of source
code.
Also you might get interested in looking at just what control-flow
results you want from the return stack. If you can put a good abstract
name to each effect you want -- something that says what it does more
than how it does it -- then you can hide the actual return stack antics
from most of your code. Then if sometime later you do choose to port to
some platform with a weird return stack, maybe all you need is to find a
way to implement those commands. Whether the method uses the return
stack or not.
None of this is necessary since your goals only require that you find
something that works on your target platforms. But if you get interested
in it, you might discover something valuable.
> To be honest I think it's harmless, and I don't think that it's wrong
> to suggest things that have worked for you, or to try things out that
> people with a compatible vibe suggest.
>
> If I made a mistake in promoting the joys of using the return stack to
> ilikemachi, I'm sorry.
No mistake. People like to point out about abstract portability issues,
that's all. It took a lot of thought to figure out what's maximally
portable, and the result was unfortunately not that easy to understand
either. So people like to review it when opportunity arises.
> Jonah:
>
> It seems to me, that what remains essential is the ability to know
> your platform so that you know what you can do, and so room should be
> left for that.
If you try, you can write lots of little routines that work pretty much
anywhere, and they can become a library you can use pretty much
anywhere.
Then if you need extreme efficiency on some system and your profiling
shows some routines that should be improved, you can write new versions
of the offending routines to improve performance on that system.
Or you can rewrite everything from scratch and maybe you'll write it
better each time.
If you can do things that don't require you to know your platform, then
it's easier to switch platforms. A lot of the time you can program in
Forth and not have to think about how you're programming in VFX Forth
for the 8051 or whatever. That's a plus. On the other hand. if you have
the leisure to think in detail about each of your platform's quirks and
you can keep all that in your head at the same time, you might create
something very very good for your platform.
> It doesn't have to be a portability issue because instead of having
> hundreds of these trick-like constructions around your source code
> that rely on data alignment or char width... you could localize these
> instances into a few simple words so that the entire app can be ported
> without pain.
I suggest as far as practical that you avoid data structures that have
character or string data followed by cell data. Whenever you have the
cell data first your alignment problems disappear. Or split up the data
structure. You could have all the cell data in one place and all the
string data somewhere else. The standard demands that if alignment is an
issue CREATE should always give you an aligned address, along with
VARIABLE etc. If I remember right HERE is supposed to be aligned unless
you unalign it. After you compile a definition HERE should be aligned.
But all that doesn't stop you from creating alignment problems.
I think it would be better if the hardware guys would avoid creating
alignment issues. ;) But since we sometimes have them, code written on
unaligned systems isn't always portable to systems that require
alignment. And even some systems that accept unaligned addresses slow
down when using them.
You or someone were asking about stupid Forth tricks, like R> 1+ >R .
Creating unaligned addresses is one of them.
It's possible as you suggest to create some semantic sugar to avoid
alignment problems. You might have words like CHAR: CELL: STRING: etc
that can be used to create data structures, and that handle alignment
invisibly. There's nothing wrong with that. I haven't heard that any
such thing has been standardised but I may have not paid attention.
Decisions made on sound technical grounds tend to be eventually
accepted/proven, even though it may cause initial issues for some.
It's the political compromises and/or dodgy justifications that lead
to discontent.
> In retrospect, ANS Forth has worked great.
Not all think so, as C.M.'s recent interview shows (which BTW got
zero comment on c.l.f.)
Standards can and do make mistakes. Forth standards in particular
have not fared well, alternating between mistake and subsequent
work-around. Sadly, there's now a trend denying that any mistakes
exist. Compromises once intended to be phased out or better dealt
with in the future have simply become enshrined.
> "Marcel Hendrix" <m...@iae.nl> wrote in message news:9915142...@frunobulax.edu...
>> Instead, the standard committee tried to find the best possible
>> compromises. The result is / was that *everyone* was more or less angry
>> and upset.
> Decisions made on sound technical grounds tend to be eventually
> accepted/proven, even though it may cause initial issues for some.
I am not sure the "sound technical grounds" are really necessary. Any
decision is OK (in the end the engineers will make it work, right Scotty?).
> It's the political compromises and/or dodgy justifications that lead
> to discontent.
Look at world politics. They get away with far bigger issues :-)
>> In retrospect, ANS Forth has worked great.
[..]
> Standards can and do make mistakes. Forth standards in particular
> have not fared well, alternating between mistake and subsequent
> work-around. Sadly, there's now a trend denying that any mistakes
> exist. Compromises once intended to be phased out or better dealt
> with in the future have simply become enshrined.
Apparently these compromises don't cause trouble in actual practice.
In the Netherlands it is forbidden to smoke in a cafe. Unless it is a
very small cafe. Or unless you call the cafe a church (I am not kidding).
-marcel
> "Marcel Hendrix" <m...@iae.nl> wrote in message
news:9915142...@frunobulax.edu...
> > In retrospect, ANS Forth has worked great.
> Not all think so, as C.M.'s recent interview shows (which BTW got
> zero comment on c.l.f.)
> Standards can and do make mistakes. Forth standards in particular
> have not fared well, alternating between mistake and subsequent
> work-around. Sadly, there's now a trend denying that any mistakes
> exist. Compromises once intended to be phased out or better dealt
> with in the future have simply become enshrined.
Oh wow, that seems a bit extreme! As you said, Forth-94 was quite
conservative, which is what a standard has to be. Sure, earlier
standards made some mistakes when they were innovative -- the
83-Standard DO...LOOP is the best example -- but this was an
exception. To characterize the whole stanardization process as
alternating between mistake and subsequent work-around is an enormous
exaggeration, given that most of the standards were uncontroversial.
Andrew.
Well, the decision in question (not requiring systems to keep return
addresses on the Return Stack) was based on (IMO) very solid technical
grounds, in that it enabled significantly faster implementation on some
very slow parts (e.g. 8051) that need all the performance they can get.
It has never been possible for programs to use Return Stack addresses
portably, since there have always been differing implementations (such
as 2-cell items on some x86 systems, which several people here have
mentioned). So, really what ANS did was to clarify the issue in terms
of what's portable and what isn't, rather than actually change anything.
>> In retrospect, ANS Forth has worked great.
>
> Not all think so, as C.M.'s recent interview shows (which BTW got
> zero comment on c.l.f.)
Chuck is an innovator, and a brilliant one. Innovators always work out
in front of the pack. It is the mission of a Standard, on the other
hand, to document and codify common practice. This is a very different
mission. To the extent that innovations get picked up by implementors
and become popular with users, they will be reflected in future standards.
> Standards can and do make mistakes. Forth standards in particular
> have not fared well, alternating between mistake and subsequent
> work-around. Sadly, there's now a trend denying that any mistakes
> exist. Compromises once intended to be phased out or better dealt
> with in the future have simply become enshrined.
ANSI actually requires standards to be re-evaluated every 5 years, so
that they can fix anything that is recognized as a mistake and
incorporate innovations that have come into common use. The Forth 200x
committee is tackling this challenge right now. Anything you consider a
"mistake" or an innovation that you think should be adopted should be
pointed out to them. They will accept proposals from anyone.
Which interview is this? Could you provide a link?
Was it this TechWorld interview from the end of June?
http://www.techworld.com.au/article/250530/a-z_programming_languages_forth
It was amusing to see many of the interview questions coming verbatim
from Wikipedia Forth history paragraphs I wrote. :)
Ian
A reasonable behaviour for EXIT while interpreting would be
abandon current buffer.
S" 1 2 3 EXIT 4 5 6 " EVALUATE
would leave 1 2 3 on the stack.
This agrees with the intuitive meaning of "unnest".
On some Forth's it just happens to happen this way, but as
you point out, don't count on it. I find it a convenience
during debugging to shut out a non-tested part of a source file.
QUIT on the other hand is a jump to the interpreter, abandoning
everything, specifically nesting.
>
>Cheers,
>Elizabeth
>
>--
>==================================================
>Elizabeth D. Rather (US & Canada) 800-55-FORTH
>FORTH Inc. +1 310.999.6784
>5959 West Century Blvd. Suite 700
>Los Angeles, CA 90045
>http://www.forth.com
>
>"Forth-based products and Services for real-time
>applications since 1973."
>==================================================
--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- like all pyramid schemes -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
If you mean with 16 bit return stack a stack where 16 bit
addresses are stored, the answer is: you misunderstood the ISO standard.
If you have a Forth with 32 bit data and 16 bit addresses,
within the ans framework you only have to define >R as putting
the 32 bit data on the return stack in two chunks.
The R> EXECUTE trick won't work, but you could easily define
a R/2> EXECUTE that will. Note that R> EXECUTE is non-portable
according to ISO.
Groetjes Albert
Not to worry ;)
> It comes from so many different directions,
That's the key to reading this group. As you read you'll recognize that
wide variety of perspectives are represented. Eventually you'll pick up
on who writes from a point of view similar to your outlook.
When threads get long, I'll first read what what a few particular
individuals say to give me guideposts when the threads get convoluted.
I read any post by Ms. Rather or Mr. Pelc probably because:
1. they have taught and/or written teaching materials for Forth.
2. they represent commercial Forth's ( I happen to be a FORTH Inc.
customer, but that may have had more to do with on which side of "Pond"
they are located ;)
I read Mr. Avins as he is of similar generation (chronological and
training) and we have some common interests.
There are (unnamed others;) who I ignore for mode of expression or for
being interested in aspects for which I could care less.
> and I feel overwhelmed by
> the sheer volume of information that this subject seems to embody.
Welcome to "real world".
> Is it rude for me to ask what everyone's education is here?
It's not rude. I'm not sure it's relevant though.
I'm in my 60's and have 3 years towards a BSEE.
And I'll gladly harass any reader's son/daughter/niece/nephew who thinks
it's bright to drop out of school *AT _ANY_ LEVEL* {RANT FADES;}
> How
> many degrees and how many self-taught? How long does it take to
> become this lucid?
Lucidity has little to do with education and only slightly more to do
with experience.
> Is it true that Forth encompasses every aspect of computing?
Probably the wrong question. Forth is "Turing complete."
Welcome to the world of Forth where everyone has an opinion and is
happy to share it!
One of the things about Forth is that it makes it not only possible,
but straight forward to do things in your own way and vastly different
from others. The result is that there are numerous splinters of
thought and it is hard to get any sort of consensus on pretty much
*any* topic.
I suggest that you don't try to nail it to the wall, since Forth is
jello and you'll just make a mess. Just take in what you can about it
and work with it to gain your own experience.
Rick