Message from discussion Words consuming arguments, was [Re: Is there a better way?]
Received: by 10.68.135.2 with SMTP id po2mr34755pbb.0.1352178447780;
Mon, 05 Nov 2012 21:07:27 -0800 (PST)
Received: by 10.68.242.74 with SMTP id wo10mr5904pbc.9.1352178447764; Mon, 05
Nov 2012 21:07:27 -0800 (PST)
Date: Mon, 5 Nov 2012 21:07:27 -0800 (PST)
Injection-Info: 6g2000pbh.googlegroups.com; posting-host=22.214.171.124; posting-account=hP9USgoAAADyPwMdR5qi1rinwP694_5o
X-HTTP-UserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4
(KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4,gzip(gfe)
Subject: Re: Words consuming arguments, was [Re: Is there a better way?]
From: Hugh Aguilar <hughaguila...@yahoo.com>
Injection-Date: Tue, 06 Nov 2012 05:07:27 +0000
Content-Type: text/plain; charset=ISO-8859-1
On Nov 5, 1:39=A0pm, "Elizabeth D. Rather" <erat...@forth.com> wrote:
> On 11/5/12 9:01 AM, Rod Pemberton wrote:
> > I take it this is to make sure extra arguments aren't left on the stack=
> > primitive form of "error checking". =A0However, I really don't see the =
> > of this. =A0In certain situations, the style that breaks the "rule" may=
> > create more effective coding.
> > As I see it (AISI), the primary effect of this "rule" is to shift the
> > location where parameters are duplicated or copied, and/or dropped. =A0=
> > word preserves arguments, then the copying is internal. =A0If it doesn'=
> > external. =A0While the example below with the DROP has the disadvantage
> > of using a DROP, it has the advantage that it can modify 'addr'. =A0Thi=
> > seems to be very useful for parsing words and linked-lists. =A0Isn't it=
> > : OPR ( addr -- addr ) DUP ... ;
> > ' addr' OPR OPR OPR OPR DROP
> > : OPR ( addr -- ) ... ;
> > 'addr' DUP OPR DUP OPR DUP OPR OPR
> Sure, there are situations when you're coding part of a process that
> needs to pass things right through the process. The classic example
> would be the output number formatting words:
> <# starts the process, taking a double and initializing the string
> output area.
> Then words like # and #s do things to the double, affecting the string
> under construction and passing on the modified double, and the process
> is completed by #> .
> But note that # etc. are *useless* outside of this particular context.
> That is the tradeoff. Most of the time, it's better to code the word
> such that it isn't context-dependent, even though the first time you
> invent it it's within a specific context.
This is what I meant earlier by the word having a "ritualistic" use.
My example was INIT-LIST. This is used in a very specific context and
always in the same way.
Whenever you create a node, the first thing that you do with the
address is initialize it for whatever type it is going to be, and the
datum (the node address) is being carried along. This is similar to
how # is used only inside of <# and #>, and the datum (the double-
precision integer) is being carried along.
Putting the DUP (or 2DUP or whatever) inside the word helps with
efficiency because the ritualistic word is typically so commonly used
that you will likely write in in assembly-language.
If the word isn't used in a ritualistic manner though, then you don't
know if the datum is going to be needed afterward or not. You may
either have a DUP before the word (if it consumes its argument) or a
DROP after the word (if it doesn't). It is best to be consistent and
have the words consume their arguments. This way there is no confusion
about whether you need a DUP or a DROP. Also, it tends to be more
efficient because the code inside of the word consumes the data and
you don't have an explicit DROP.
As an example, here are two ways to write the + word:
: + ( a b -- a+b )
which is used like this:
5 7 + .
: + ( a b -- a b a+b )
which is used like this:
5 7 + . 2drop
Pretty obvious which makes for the most readable code, don't you