Hi Jon,

On Fri, 2011-05-06 at 22:14 +0000, Jon Harper wrote:
> Hi Matt,
> first of all, just in case you didn't know, the words you are trying
> to write already exist in the library in the "sets" vocabulary.
> Also, instead of reducing your sequence and pushing it to a vector,
> you can just use map.

I didn't know about the "sets" vocab (thanks, factor kind of takes
"batteries included" to another level), but this was actually a trivial
example of the problem I was having in a more complicated piece of code.

As for mapping instead of reducing, the issue I ran into was that map
seems to try to wrap the result in the same sequence type that the input
was. That works great for vectors, but when the sequence is a string:
"abcd" [ '[ _ = ] ] map
then you have a problem.

After thinking about it, it seemed to me to be semantically incorrect to
require that the sequence type of the argument should be able to hold
quots so I switched it to a reduce that always produces a vector.

> Regarding your question on call:
> 
> .The reason for the difference between the listener and a compiled
> source file is that factor has 2 compilers. Compiling a source file is
> done with the optimizing compiler which enforces static stack effects,
> while code in the listener is compiled with the non-optimizing
> compiler which doesn't.
> 
> .Using inline only works for case where the input is also a literal at
> the call site or that the inlined function is called by another
> inlined function that satisfies this condition. For example:
> : bar ( quot -- ) call ; inline
> : foo ( -- ) [ "hello" print ] bar ;
> Here you have to declare bar as inline.
> 
> The thing is that you are not the one calling "call", so you might
> think you can't use all the combinators that expect a quotation and
> call "call" in various ways on this quotation (for example map or
> reduce). The way to solve this is to encapsulate your dynamic
> quotation into a quotation that has a static stack effect. To do this,
> the encapsulating quotation calls the dynamic quotation with call(.
> In the following example, dyn-quot is not inline, so its result is
> only know at runtime in dyn-quot-combinator*. (Using inline here would
> make dyn-quot-combinator2 work since the quotation would a literal in
> dyn-quot-combinator):
> : dyn-quot ( -- quot ) [ "Hello!" print ] ;
> : dyn-quot-combinator1 ( -- ) 2 [ dyn-quot call( -- ) ] times ;
> : dyn-quot-combinator2 ( -- ) 2 dyn-quot times ;

So is a dynamic quotation just any quotation that has been
"returned" (so to speak) by a non-inline function?

I tried
: nop1 ( q -- q ) ;
: hw1 ( -- ) [ "Hello world" print ] nop1 call ;
and hw1 will produce the error. I assume adding the quot to a vector has
the same effect.

> However, when using sequences of quotations (like in your case), input
> to the words that calls "call" will always be a runtime value (unless
> you use macros, but that only works for litterals). The way to go is
> to encapsulate the whole call in a statically quotation:
> ! Does seq contain any of the elements of elts
> : contains-any? ( seq elts -- ? ) seq>contain-seq 1|| ; inline
> : correct-contains-any? ( seq elts -- ? ) [ seq>contain-seq 1|| ]
> call( seq elts -- ? )  ; inline

Your correct version didn't work.  I think that makes sense because
seq>contain-seq is still producing the vector of quots inside the same
quot as 1||.

: contains-any? ( seq elts -- ? ) seq>contain-seq [ 1|| ] 
                                  call( seq -- ? ) ;

worked though.

> Using macro is a better alternative when your quotations are litterals
> in a sequence. That's what n|| does for example. It only works for
> litterals though.
> 
> Finally, you might wonder why 1||, which is a regular word defined in
> the short-circuit.combinators, works. That's because the compiler
> special-cases it (see
> basis/stack-checker/transforms/transforms.factor) and transforms it
> into a macro call (and that's why it works only for litteral
> quotations in sequences)

This part I think is still a bit beyond me. The "define-transform" page
says it will only apply the transform if the argument is a literal, but
the normal 1|| calls "call" which also requires the argument to be a
literal.

If that was the case, then the only time when the normal definition of
1|| is called is when "call" is guaranteed to fail.

What am I missing?

> I hope this answers some questions :)

It did, thank you very much for taking the time to answer them :).
 
> cheers,
> Jon
> 
> On Fri, May 6, 2011 at 8:45 PM, Matt Edlefsen <[email protected]> wrote:
> > Hello!
> >
> > I'm pretty new to factor and have run into an issue related to the
> > "call" word that I'm hoping one of you can help me understand.
> >
> > Basically what it comes down to is I'm trying to use the 1|| word (which
> > runs "call") and a vector of fry'd quots:
> >
> > -----------------------------------
> >
> > ! Copyright (C) 2011 Matt Edlefsen.
> > ! See http://factorcode.org/license.txt for BSD license.
> > USING: kernel fry sequences vectors math
> >       combinators.short-circuit ;
> > IN: contains
> >
> > ! Is elt in seq?
> > : contains? ( seq elt -- ? ) '[ _ = ] count 0 > ; inline
> >
> > <PRIVATE
> >
> > ! Take elt, convert it into a closure that checks for it
> > ! and pushes the closure onto seq
> > : push-contains ( seq elt -- seq )
> >    '[ _ contains? ] over push ; inline
> >
> > ! Takes a sequence and generates a vector of closures, one
> > ! for each element, that checks for that elt in a given seq
> > : seq>contain-seq ( seq -- seq ) V{ } clone
> >                              [ push-contains ]
> >                              reduce ; inline
> > PRIVATE>
> >
> > ! Does seq contain any of the elements of elts
> > : contains-any? ( seq elts -- ? ) seq>contain-seq 1|| ; inline
> >
> > -----------------------------------
> >
> > Everything works except for contains-any? which gives me a "Cannot apply
> > “1||” to a run-time computed value" error.
> >
> > If I just put the contents of contains-any? directly into the listener
> > it works fine, but if it's compiled into a word, then it doesn't.
> >
> > Reading the documentation of "call" it says that if it is run on inputs,
> > the function is inline, but even when I make all of the words inline (as
> > I have above), it still doesn't work.
> >
> > I'm less interested in getting this particular piece of code working
> > than I am in understanding how to use inline, ||, and call correctly.
> >
> > Thanks,
> >
> > Matt Edlefsen
> >

Matt Edlefsen


------------------------------------------------------------------------------
WhatsUp Gold - Download Free Network Management Software
The most intuitive, comprehensive, and cost-effective network 
management toolset available today.  Delivers lowest initial 
acquisition cost and overall TCO of any competing solution.
http://p.sf.net/sfu/whatsupgold-sd
_______________________________________________
Factor-talk mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to