It is because when-zero preserves the value on the stack if it isn't
zero. I think it is easier to see the mistake if you forego using the
when-* combinators:

: check0 ( n -- ) 0 = [ call-fail ] [ ] if ;

: check0 ( n -- ) [ call-fail ] [ ] if-zero ;

Both quotations supplied to if-zero has effect ( -- ), but that is not
right. The second quotation should lift one extra item from the stack.
As in:

: check0 ( n -- ) [ call-fail ] [ drop ] if-zero ;

When I write Factor code, I always start with the "easy" branch
combinators like `if` and `?`. Then after I have ensured that the code
does what I want and that the stack effects balance, I look for
opportunities to refactor using "fancier" combinators like `when`,
`?if`, `unless-empty` and so on.


2017-03-01 20:18 GMT+01:00 Alexander Ilin <ajs...@yandex.ru>:
> Continuing with this example, here's what I stumbled upon (again), and found
> confusing (once more):
>
> This works as expected:
>
> ```
> : check0 ( n -- ) 0 = [ call-fail ] when ;
> ```
>
> This fails to compile:
>
> ```
> : check0 ( n -- ) [ call-fail ] when-zero ;
> ```
>
> But according to the documented stack effect (at least the way I read it,
> please correct me if I'm wrong) it should compile: n and quotation should be
> dropped from the stack by when-zero.
>
> 01.03.2017, 22:13, "Alexander Ilin" <ajs...@yandex.ru>:
>
> Here's a slightly better stack effect documentation:
>
> `when-zero ( ..a n quot: ( ..a -- ..b ) -- ..b )`
>
> But IIUC the actual stack effect is one of these:
>
> `when-zero ( ..a 0 quot: ( ..a -- ..b ) -- ..b )`
> `when-zero ( ..a n#0 quot: ( ..a -- ..b ) -- ..a n )`
>
> where # denotes inequality.
>
> Am I right? How does the compiler handle such ambiguity in the stack effect?
> 01.03.2017, 19:28, "John Benediktsson" <mrj...@gmail.com>:
>
> A stack effect of ( seq quot -- ) doesn't say what the quot is expected to
> do...
>
> You can play around with it and see how it works:
>
>     IN: scratchpad "abc" [ "empty" ] when-empty .
>     "abc"
>
>     IN: scratchpad "" [ "empty" ] when-empty .
>     "empty"
>
> We should improve the docs here because they are a little hard to follow,
> since it refers to ``when-empty`` taking the "first quot" of an
> ``if-empty``, with an empty second quot.
>
>
>
>
> On Wed, Mar 1, 2017 at 8:18 AM, Alexander Ilin <ajs...@yandex.ru> wrote:
>
> Hello!
>
>   I'm struggling with some of the Factor's words. Mostly with `when-empty`,
> `if-zero` and similar. It's difficult for me to understand why they don't
> work sometimes, while their simpler counterparts (while, if) do work exactly
> as expected.
>
>   Here's the latest installment of my struggle:
>
> IN: scratchpad USE: crypto.xor [ [ empty-xor-key ] when-empty ]  infer.
> ( x -- x )
>
>   Why is the stack effect as shown here? The documentation for `when-empty`
> says it takes `( seq quot -- )`. Therefore, I expect `[ [ empty-xor-key ]
> when-empty ]  infer.` to output `( x -- )`.
>
>   When I modify the quotation passed to `when-empty` to be a no-op, I get a
> compilation error:
> IN: scratchpad [ [ 1 drop ] when-empty ]  infer.
> Error
> The input quotations to “if-empty” don't match their expected effects
> Input      Expected           Got
> [ 1 drop ] ( ..a -- ..b )     ( -- )
> [ ]        ( ..a seq -- ..b ) ( -- )
>
>   That's completely weird to me. Is the stack effect in the documentation
> incorrect? Should it be `( seq quot -- seq )`?
>   And why does it refuse to compile the second example with `1 drop`?
>
> ---=====---
>  Александр
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> Factor-talk mailing list
> Factor-talk@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/factor-talk
>
> ,
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
>
> ,
>
> _______________________________________________
> Factor-talk mailing list
> Factor-talk@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/factor-talk
>
>
>
> ---=====---
> Александр
>
> ,
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
>
> ,
>
> _______________________________________________
> Factor-talk mailing list
> Factor-talk@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/factor-talk
>
>
>
> ---=====---
> Александр
>
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> Factor-talk mailing list
> Factor-talk@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/factor-talk
>



-- 
mvh/best regards Björn Lindqvist

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Factor-talk mailing list
Factor-talk@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to