# askagain == "linrec" explainplease [ linrecexlained ] [ ] [askagain] ifte

## cpcogan — 2004-08-10 22:34:59

    Hi,

    I'm a Joy newbie, implementing Joy in Visual Basic .NET, but I'm

    confused about linrec.

    The help for it says:

    [P] [T] [R1] [R2]

    Executes P. If that yields true, executes T. Else executes R1,

    recurses, executes R2.

    However I can't find an implementation except in tcl (yes, tcl, by

    Salvatore Sanfilippo, at: http://wiki.tcl.tk/10870), and I'm not sure

    it's correct.

    When it recurses, does linrec push the parms back on the stack first?

    Or is R1 supposed to supply a new set of four? I'm guessing that all

    four of the starting quoted programs should be made available to the

    recursion, so I'd further guess that they should be (at least

    virtually) pushed back on the stack for the recursion.

    Is this correct?

    Salvatore seems to be bunching all four parms into a new list before

    doing the recursion. That doesn't seem right to me because they were

    separately stacked quoted programs before the initial call.

    That is, it doesn't seem to fit the description of linrec above (even

    though it looks like a useful function in it's own right).

    By the way, has anyone any comments on Salvatore's (highly) local

    variables? (Actually, they are more like Prolog variables than they

    are like regular variables, because their value doesn't change within

    a scope, unless one re-captures data for them.)

    They look okay to me; he does restrict them so they won't change the

    semantics of a function as far as the outside world is concerned. I'm

    not sure yet how useful they are, but I'd think they would be of some

    use in cases where the stack manipulations become a little hairy. His

    mechanism for capturing them seems especially nice, because of the

    minimal coding overhead.

    He just matches a parenthesized "list" of the variables with the

    stack, so that, for example, ($B $A) captures the top two items on

    the stack ($A gets the first one, $B gets the second). Then, as long

    as they are used at the same level as the code that captures them

    (which excludes nesting them in a list), one is free to use them to

    push the same values back on the stack as needed. This reduces the

    need for all of the stack operations, which I think should make the

    code a little smoother to write and read and get correct.

    Finally, many thanks to whoever (no name is given) made the Win32

    version and uploaded it to the files section. I will be using it a

    lot, I expect, to ensure that my implementation of things is correct

    (I want to stick close to the "official" version, at least initially,

    and unless I find good reasons to change things (for my own use)).

    --Chris C.

## Slava Pestov — 2004-08-10 23:11:20

    cpcogan wrote:

     > Hi,

    > I'm a Joy newbie, implementing Joy in Visual Basic .NET,

     Please post the code when you're done :)

     > The help for it says:

    >

    > [P] [T] [R1] [R2]

    > Executes P. If that yields true, executes T. Else executes R1,

    > recurses, executes R2.

    >

    > However I can't find an implementation except in tcl (yes, tcl, by

    > Salvatore Sanfilippo, at: http://wiki.tcl.tk/10870), and I'm not sure

    > it's correct.

     The C implementation of Joy includes this combinator, coded as a C

    primitive.

    Slava

## phimvt@lurac.latrobe.edu.au — 2004-08-11 07:13:52

    On Tue, 10 Aug 2004, cpcogan wrote:

     > Hi,

    > I'm a Joy newbie, implementing Joy in Visual Basic .NET, but I'm

    > confused about linrec.

    >

    > The help for it says:

    >

    > [P] [T] [R1] [R2]

    > Executes P. If that yields true, executes T. Else executes R1,

    > recurses, executes R2.

    >

    > However I can't find an implementation except in tcl (yes, tcl, by

    > Salvatore Sanfilippo, at: http://wiki.tcl.tk/10870), and I'm not sure

    > it's correct.

    >

    > When it recurses, does linrec push the parms back on the stack first?

     It is as if linrec pushed them back first, but an

    implementation might be able to avoid this.

     > Or is R1 supposed to supply a new set of four? I'm guessing that all

    > four of the starting quoted programs should be made available to the

    > recursion, so I'd further guess that they should be (at least

    > virtually) pushed back on the stack for the recursion.

     Yes, virtually is a good way to express it.

    The C-program which is the implementation has essentially

    two functions to handle this:

    void linrec-aux()              (* "auxiliary" *)

    {

    Do the test P,

    if that yields true, do T,

    else do R1, call linrec-aux, do R2        (* no new params *)

    }

    void linrec()                  (* called when "linrec" is seen *)

    {

    save the top four parameters somewhere where linrec-aux can see them.

    (* they are now no longer on the stack *)

    call linrec-aux

    delete the saved four parameters from where they were saved

    }

    The whole idea of having the two functions, (one to save

    the params, the other to recurse as necessary) is to avoid

    copying the params for every recursive call.

    Hope this helps

      - Manfred

    P.S.  It looks as though I missed an important concatenative

    language in the files section - my apologies. Is the author

    willing to write a section for the joint paper?

    Sorry,I am too tired for today to do any more.

      - M.

## ccogan@cox.net — 2004-08-11 14:35:40

    <snip>

    Manfred says:

     > void linrec-aux()              (* "auxiliary" *)

    > {

    > Do the test P,

    > if that yields true, do T,

    > else do R1, call linrec-aux, do R2        (* no new params *)

    > }

    >

    > void linrec()                  (* called when "linrec" is seen *)

    > {

    > save the top four parameters somewhere where linrec-aux can see them.

    > (* they are now no longer on the stack *)

    > call linrec-aux

    > delete the saved four parameters from where they were saved

    > }

    >

    > The whole idea of having the two functions, (one to save

    > the params, the other to recurse as necessary) is to avoid

    > copying the params for every recursive call.

    >

    > Hope this helps

     Yes. Thanks, that's all I need.

## cpcogan — 2004-08-13 15:16:49

    On linrec:

     > The C implementation of Joy includes this combinator, coded as a C

    > primitive.

    >

    > Slava

     You're right, but I couldn't find it. I must have had my search set

    on "whole word only," so that, without the trailing underbar, it

    wouldn't match.

    Thanks for helping clear that up (I was almost sure it had to be

    there).

    --Chris