Path: ...!eternal-september.org!feeder3.eternal-september.org!i2pn.org!i2pn2.org!.POSTED!not-for-mail From: melahi_ahmed@yahoo.fr (ahmed) Newsgroups: comp.lang.forth Subject: Re: Back & Forth - Co-routines Date: Sat, 1 Feb 2025 08:22:01 +0000 Organization: novaBBS Message-ID: <6efc4fec918d6d2bc29250159bafb5de@www.novabbs.com> References: <9c16141dfe3c785e316678770e965566@www.novabbs.com> <87plk2y6yf.fsf@nightsong.com> <2025Feb1.082611@mips.complang.tuwien.ac.at> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: i2pn2.org; logging-data="2146944"; mail-complaints-to="usenet@i2pn2.org"; posting-account="t+/9LUKLIiUqIe6reyFE7me/EcA/Gr17dRXgwnADesE"; User-Agent: Rocksolid Light X-Rslight-Site: $2y$10$J8v.KajuUeJsRA60CrXhhes0rVp1Fco5tRgnILWu0mb1pezlyVRKK X-Rslight-Posting-User: 5f6b2e70af503e44dad56966aa15d35bdef29623 X-Spam-Checker-Version: SpamAssassin 4.0.0 Bytes: 3271 Lines: 88 On Sat, 1 Feb 2025 7:26:11 +0000, Anton Ertl wrote: > Paul Rubin writes: >>This seems more in the locals spirit: >> >>: blend { a x b -- n } 100 b x - b a - */ ; >>: tri_mf3.1 { x a b c -- mf } >> a x <= x b < AND IF b x a blend EXIT THEN >> b x <= x c < AND IF b x c blend EXIT THEN >> 0 ; > > Forth has a word WITHIN that should come in handy here: > > : tri_mf3.1 { x a b c -- mf } > x a b within IF b x a blend EXIT THEN > x b c within IF b x c blend EXIT THEN > 0 ; Yes, it works fine. Thanks. > Another alternative, assuming a<=b<=c: > > : tri_mf3.1 { x a b c -- mf } > case > x a < ?of 0 endof > x b < ?of b x a blend endof > x c < ?of b x c blend endof > 0 0 > endcase ; It also works fine without problems. > > The disadvantage in the latter case is that the above and below cases > are separate, needing another branch and possibly increasing the > number of mispredictions. This can be addressed with: > > [undefined] select [if] > : select ( u1 u2 f -- u ) > if swap then nip ; > [then] > > : tri_mf3.1 { x a b c -- mf } > x a c within if > b x x b < a c select blend > else > 0 > then ; This latter gives wrong results: -100 -50 0 50 tri_mf3.1 . 0 ok \ this is true -50 -50 0 50 tri_mf3.1 . -4900 ok \ false, must be 0 -10 -50 0 50 tri_mf3.1 . -900 ok \ false, must be 80 0 -50 0 50 tri_mf3.1 . \ here division by zero *the terminal*:47:12: error: Division by zero 0 -50 0 50 >>>tri_mf3.1<<< . I think it must be: (the true/false flag must on tos for select as you defined it) : tri_mf3.1 { x a b c -- mf } x a c within if b x a c x b < select blend else 0 then ; and this one works fine. -100 -50 0 50 tri_mf3.1 . 0 ok -50 -50 0 50 tri_mf3.1 . 0 ok -10 -50 0 50 tri_mf3.1 . 80 ok 0 -50 0 50 tri_mf3.1 . 100 ok 10 -50 0 50 tri_mf3.1 . 80 ok 50 -50 0 50 tri_mf3.1 . 0 ok 100 -50 0 50 tri_mf3.1 . 0 ok > > In Gforth (development) SELECT is a primitive which hopefully does not > branch; in that case you have only one branch here. > > - anton Ahmed --