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