Detecting Multiple Events (was: Case Statements...) 
Author Message
 Detecting Multiple Events (was: Case Statements...)



Quote:
> This reminds me of a set of unusual control structur words I have
> written to simplify the detection of multiple (possibly subsequent)
> events.  As COND and THENS they are just shorthands for something
> you could write in ordinary Forth as well, but are much handier to
> describe the problem.
> An example. Keystrokes have to be analyzed and a sequencs of three
> 'A's pressed in a row has to be detected. I finally came up with
> the following:
> : demo ( -- )
>     ." Press 3 times 'A' to exit!" cr
>     detect
>     BEGIN
>       key dup emit  ascii A =
>       IF  ."  Again! " CR 3 times? IF ." Yesss! "   EXIT THEN
>       ELSE  restart ."  3 times 'A' in a sequence" cr THEN
>     AGAIN ;
> I use 4 words for detecting mutiple events: DETECT, GIVEUP, TIMES?,
> and RESTART; they manage an event counter on top of the return stack.
> ----------------------------------------------------------------------
> Here is the implementation in ANS-Forth. I use EVALUATE to
> implement them as macros. EVALUATE is not called at runtime of the
> words which use the macros. I usually have a macro defining word this,
> but that's a completly different story...

BUT  macros  will compile incorrectly  if any word they use is
redefined later!  I used to have a word { which POSTPONED  every
following word until it met } , but I don't see how to implement it portably.  

One word I do use a lot is : RETURN { EXIT THEN } ; IMMEDIATE , which
might have saved Wil and JET their confusion over counting THENs. ;-)

In fact, there is a better, though non-Standard solution if you have
a Forth that allows you to exit a counted loop with WHILE.  This
works with Pygmy (I know because I tested it!)

   BEGIN times FOR test WHILE  NEXT succeed ELSE  POP DROP  fail REPEAT

or in more normal Forth

   BEGIN times 0 DO test WHILE LOOP succeed ELSE UNLOOP fail REPEAT

It may be unstructured, but it sounds more like what should happen if
you say it aloud (my first test for good definitions)!

--
Jack Brien  Ballinamallard  Co Fermanagh  N Ireland



Fri, 25 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)


Quote:
>  BUT  macros  will compile incorrectly  if any word they use is
>  redefined later!  

No, not incorrectly, but _differently_.  If you have had a reason to change
the Standard words or non-Standard words in a macro you usually want the
macros to reflect this.  Otherwise you will have provided a non-macro
definition.  Your non-standard with words in a macro will tend to be stable
like the Standard words.

Look at your example.  I'd write it MACRO RETURN " EXIT THEN "
Any change you make to EXIT or THEN you want maintained.

Quote:
>                    I used to have a word { which POSTPONED  every
>  following word until it met } , but I don't see how to implement it portably.  

JET has done this function -- I hope he'll report.

Quote:
>  One word I do use a lot is : RETURN { EXIT THEN } ; IMMEDIATE , which
>  might have saved Wil and JET their confusion over counting THENs. ;-)

Hiding THEN is not going help me count them.

Quote:
>  In fact, there is a better, though non-Standard solution if you have
>  a Forth that allows you to exit a counted loop with WHILE.  

This was proposed to the Standards committee and rejected.  

Quote:
>  This works with Pygmy (I know because I tested it!)

>     BEGIN times FOR test WHILE  NEXT succeed ELSE  POP DROP  fail REPEAT

>  or in more normal Forth

>     BEGIN times 0 DO test WHILE LOOP succeed ELSE UNLOOP fail REPEAT

Shouldn't there be THEN after `fail`?  In fact, how do you get out of the
BEGIN ... REPEAT loop?  Would you test again, please?

Quote:
>  It may be unstructured, but it sounds more like what should happen if
>  you say it aloud (my first test for good definitions)!

WHILE to get out of a DO...LOOP should just happen to work on a lot
of implementations.


Fri, 25 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)

Quote:



> >  BUT  macros  will compile incorrectly  if any word they use is
> >  redefined later!  

Ah, just as if it came out of my keyboard:-)

Quote:
> No, not incorrectly, but _differently_.  If you have had a reason to change
> the Standard words or non-Standard words in a macro you usually want the
> macros to reflect this.

If I really want to reflect the changes, I want the change to have
effect even after using the macros. EVALUATE won't give me that, DEFER
will (at least for words with default compilation semantics).

Quote:
> Otherwise you will have provided a non-macro
> definition.

Call them what you will, Humpty-Dumpty, the fact remains, that I don't
want my macros to change their meaning when I add words or change the
search order. And most others probably don't want that either. And
when I want such changes, other means work better and are safer than
compile-time (or run-time) EVALUATE.

And if you really like that change-effect, take a look at
postscript. You can emulate it's behaviour with run-time EVALUATE;
compile-time EVALUATE is a half-assed solution.

Quote:
>  Your non-standard with words in a macro will tend to be stable
> like the Standard words.

Not necessarily. If I use a private helper word in a macro, and the
user of my macro happens to use the same name for one of his words, a
macro using EVALUATE breaks. A macro using POSTPONE continues working.

You can remind yourself that we had this discussion some time ago by
looking at

http://www.complang.tuwien.ac.at/forth/why-evaluate-is-bad

- anton
--
M. Anton Ertl                    Some things have to be seen to be believed

http://www.complang.tuwien.ac.at/anton/home.html



Sat, 26 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)


Quote:
(Anton Ertl) writes:
>> >  BUT  macros  will compile incorrectly  if any word they use is
>> >  redefined later!  
>> No, not incorrectly, but _differently_.  If you have had a reason to
>> change the Standard words or non-Standard words in a macro you
>> usually want the macros to reflect this.
>If I really want to reflect the changes, I want the change to have
>effect even after using the macros. EVALUATE won't give me that, DEFER
>will (at least for words with default compilation semantics).

I tend to agree with you on this.  But we have both tools, we can each
use the one we think is best for the task, for each task.

Quote:
>> Otherwise you will have provided a non-macro
>> definition.

Sometimes the names are vaguer than other times.  I'd be perfectly
happy using "macro" for things built with POSTPONE , things built with
EVALUATE , and even things built with a cut-and-paste buffer.  When
it's necessary to clarify what kind of macro we mean, we should use
more specific language.

Quote:
>And if you really like that change-effect, take a look at
>Postscript. You can emulate it's behaviour with run-time EVALUATE;
>compile-time EVALUATE is a half-assed solution.

It can be the right tool for the job, sometimes.  If you always see
something better then don't use it.  I guess it makes sense for you to
argue with Wil about it if you think you might someday have to maintain
his code.


Sat, 26 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)

: You can remind yourself that we had this discussion some time ago by
: looking at

: http://www.complang.tuwien.ac.at/forth/why-evaluate-is-bad

Hi Anton,

Because of your advice I've looked at my macros and in all of them
I would welcome changes.  Macros are patterns of code that I want
observed.  If the factors in that pattern change I want the pattern
to follow.

It depends on how you're going to use macros.
--
Wil



Sat, 26 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)



Quote:


> >  BUT  macros  will compile incorrectly  if any word they use is
> >  redefined later!  
> No, not incorrectly, but _differently_.  If you have had a reason to change
> the Standard words or non-Standard words in a macro you usually want the
> macros to reflect this.  Otherwise you will have provided a non-macro
> definition.  Your non-standard with words in a macro will tend to be stable
> like the Standard words.
> Look at your example.  I'd write it MACRO RETURN " EXIT THEN "
> Any change you make to EXIT or THEN you want maintained.

Ok, 'incorrectly' might be a bit strong, but this is a difference I
can do without.  Generally, once a word is defined, I don't want to
worry what words are used in its definition.  Otherwise I might
forget that EXIT had been used in this fashion, and write an EXIT
that did something completely different in an obscure wordlist.  The
danger in accidentally changing a word IMO, outweighs the extra
inconvenience of changing it deliberately.
 .    

Quote:
> >                    I used to have a word { which POSTPONED  every
> >  following word until it met } , but I don't see how to implement

it portably.  

Quote:
> JET has done this function -- I hope he'll report.

Me too.  I like {..} because it's analogous to [ ..]  

Quote:
> >  One word I do use a lot is : RETURN { EXIT THEN } ; IMMEDIATE , which
> >  might have saved Wil and JET their confusion over counting THENs. ;-)
> Hiding THEN is not going help me count them.

Maybe not, but RETURN is to EXIT as REPEAT is to AGAIN  

Quote:
> >  In fact, there is a better, though non-Standard solution if you have
> >  a Forth that allows you to exit a counted loop with WHILE.  
> This was proposed to the Standards committee and rejected.  
> >  This works with Pygmy (I know because I tested it!)

> >     BEGIN times FOR test WHILE  NEXT succeed ELSE  POP DROP  fail REPEAT

> >  or in more normal Forth

> >     BEGIN times 0 DO test WHILE LOOP succeed ELSE UNLOOP fail REPEAT
> Shouldn't there be THEN after `fail`?  In fact, how do you get out of the
> BEGIN ... REPEAT loop?  Would you test again, please?

OOOOPS!!  Abject apologies!  Thanks for spotting it, Wil.

What I actually tested was:

BEGIN times FOR test ... WHILE   NEXT ... succeed RETURN .... POP
DROP fail AGAIN

which _does_ work.  (I know because I tested it. Honest!)   It just
highlights once again the trickiness of conditionals and the
importance of interactive testing.

Quote:
> WHILE to get out of a DO...LOOP should just happen to work on a lot
> of implementations.

In fact, I'm not sure how you could accidentally design a Forth that
didn't allow it, or _why_ you would do so deliberately.

--
Jack Brien  Ballinamallard  Co Fermanagh  N Ireland



Sat, 26 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)


Quote:
> Thank you for the reminder, but I'm no more convinced now than I was
> then.  EVALUATE should not be used where POSTPONE will do, but using
> the interpreter at run time is such a powerful technique that it's
> unreasonable to refuse to use it because of some potential problems.
> A sealed wordlist helps to prevent {*filter*} surprises, of course.  As far
> as I can tell, none of your objections apply when this is done.
> The best use I've seen for run-time use of the interpreter is in
> factory automation systems where Forth is used to create a programming
> language used to control sequences.  Run-time use of EVALUATE and the
> use of a sealed vocabulary does exactly the right thing.

        Don't the wordlist extensions give the tools to use this safely,
with open wordlists?  That is, retain the current state of the wordlist
stack, put exactly the context we want to use for evaluating a string in
its place, and then restore the state of the wordlist.

Virtually,

Bruce R. McFarling, Newcastle, NSW



Mon, 28 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)

Quote:

> WHILE to get out of a DO...LOOP should just happen to work on a lot
> of implementations.

JB> In fact, I'm not sure how you could accidentally design a Forth
that
JB> didn't allow it, or _why_ you would do so deliberately.

It is easier to waste one branch location after a DO, so LOOP does the
same for DO as for ?DO. Each DO or ?DO incorporates a branch forward
plus a branch backwards then. This may be easily represented by one item
on the compiler stack, but logically it is two. The action of a CS-ROLL
(which implements WHILE) could be broken then for accessing a do-sys.
This is for straight-on implementing.

There seem to be two different kinds of compile-time checks. One checks
for pairs, another checks for valid locations to branch to or from. The
second one has 'won' at far as the redefinition of WHILE by "IF [ 1 ]
CS-ROLL" if logially valid now, which allows as well to take REPEAT as a
AGAIN THEN (now UNTIL THEN is a valid consequence). A check for pairs at
compile time cannot cope with this.

While allowing for a more powerful compiler at one hand, it seems that
more delicate checks for return stack balance, when compiling counted
loops, where preserved so not to become too complex. But for straight-on
implementation, it is just the small difference to have the two branches
associated with a ?DO represented by one item. This is easily done, but
now one may not rely on it.

(Ok, but return stack balance cannot perfectly be checked at compile
time:

DUP BEGIN ?DUP WHILE ROT >R 1- REPEAT
???
DUP BEGIN ?DUP WHILE R> ROT ROT 1- REPEAT

- the '???' may be replaced by something which makes for a crash or not.
This is bound at runtime, not at compile time - in consequence it looks
a bit more as a matter of taste than of consistency if to vote for
branches out of counted loops or against.)



Mon, 28 Feb 2000 03:00:00 GMT  
 Detecting Multiple Events (was: Case Statements...)


Quote:
> > words which use the macros. I usually have a macro defining word this,
> > but that's a completly different story...
> BUT  macros  will compile incorrectly  if any word they use is
> redefined later!

If there are standard words used in the macros I expect them only
to be extended but not changed in their principle behaviour.

If I expect these changes to propagate to macros, I'll use the
text style macros (Structured compile time EVALUATE).

If I expect my macro definitions to be of completely fixed semantics,
I'll use your style macros. (immediate POSTPONING words).

Quote:
> I used to have a word { which POSTPONED  every
> following word until it met } , but I don't see how
> to implement it portably.  

Is it really that difficult? What about a modified outer interpreter?

: } ;

: { ( -- )
   BEGIN
     BEGIN

     WHILE ( c-addr )
       FIND ?DUP  
       IF SWAP
          DUP ['] } = IF 2DROP EXIT THEN  
          POSTPONE LITERAL
          -1 = IF  POSTPONE COMPILE,  ELSE  POSTPONE EXECUTE  THEN
       ELSE  
         COUNT snumber? ?DUP  
         IF  0< IF  POSTPONE LITERAL  ['] LITERAL COMPILE, THEN  
           POSTPONE LITERAL    ['] LITERAL COMPILE,
         ELSE
           TYPE TRUE ABORT" ?"
         THEN
       THEN
     REPEAT
     DROP
     SOURCE-ID 0= IF CR ." {... " THEN
     REFILL 0=
   UNTIL ; IMMEDIATE

Quote:
> One word I do use a lot is : RETURN { EXIT THEN } ; IMMEDIATE , which
> might have saved Wil and JET their confusion over counting THENs. ;-)

I used to call it BREAK but then started to use it as pattern EXIT THEN,
as you can see above.

Two other nice words are:

   : ?EXIT   {    IF EXIT THEN } ; IMMEDIATE
   : 0=EXIT  { 0= IF EXIT THEN } ; IMMEDIATE

Regards,
      Ulrich

P.S. Here is SNUMBER?

----------------------------------------------------------------------
: ?sign ( ud f -- d )  IF DNEGATE THEN ;

: snumber? ( c-addr u -- n 1 | d -1 | c-addr u 0 )
   2DUP
   DUP 0= IF   2DROP 0  EXIT THEN

   0. 2SWAP  >NUMBER  DUP 0= IF  2DROP 2SWAP 2DROP R> ?sign  DROP  1 EXIT THEN  

   1 /STRING >NUMBER  0= IF  DROP 2SWAP 2DROP R> ?sign  -1 EXIT THEN
   DROP 2DROP  R> DROP 0 ;
----------------------------------------------------------------------

--
Ulrich Hoffmann, Uni Kiel        http://www.informatik.uni-kiel.de/~uho/

Preusserstr 1-9, D-24105 Kiel, Germany  Tel: +49 431 560426  Fax: 566143



Tue, 29 Feb 2000 03:00:00 GMT  
 
 [ 37 post ]  Go to page: [1] [2] [3]

 Relevant Pages 

1. DO..WHILE ..LOOP (was: Detecting Multiple Events )

2. case statement flipflop statement

3. difference if statement with case statement?

4. Event case missing mouse events on active-x component

5. using multiple event structures polling for panel closing event

6. Single Event -> Multiple Event

7. detecting alternate cases in Expect

8. [Fwd: Case statements, decision trees, and good OO design]

9. SUNOS NAWK - TOLOWER - In a print statement convert string to lower case

10. CASE STATEMENT

11. Case statements in parallel

12. Case Statements...

 

 
Powered by phpBB® Forum Software