• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r4wp

[Rebol School] REBOL School

Ladislav
3-Oct-2012
[1029x2]
it would do what you expect, but:

spec: [...]
body: [....]
rfunc [spec] [body]

would cause some modifications that may be unwanted.
sorry, I meant

rfunc spec body
MarcS
3-Oct-2012
[1031]
hmm, i haven't considered that case
Ladislav
3-Oct-2012
[1032]
However, the USE function still (in R2) does not contain any warning 
it is modifying its BODY argument...
MarcS
3-Oct-2012
[1033]
i just thought i was setting up a new lexical scope
Ladislav
3-Oct-2012
[1034]
You are OK, most probably, but not due to the fact that USE is not 
modifying, rather due to the fact that it most frequently does not 
matter.
MarcS
3-Oct-2012
[1035]
i'm afraid i'm not clear on what's being mutated
Ladislav
3-Oct-2012
[1036x2]
THat is a complicated issue, but the principle is easy. USE modifies 
it BODY and should be treated as modifying. However, you can easily 
define a non-modifying version:

    USE words copy/deep body
...and, in most cases the difference does not matter (but still, 
I prefer to be warned)
MarcS
3-Oct-2012
[1038x6]
aha, thanks
i just looked at the r2 and r3 docs, i see the issue now
so: conceptually, it shouldn't matter as you're supposed to be recursing 
rfuncs with 'recur'
but semantically it would be better to address this
updated: http://0branch.com/highlight/snippets/rfunc2.r
so, if i haven't overlooked anything else: think anyone would find 
this useful?
Ladislav
3-Oct-2012
[1044]
one more style-related:

I do not know why you used the

    do [func spec wrapped]

I guess that

    func spec wrapped

should suffice.
Steeve
3-Oct-2012
[1045]
Marcs, It only works if the word 'recur appears at the end of your 
function (like in safe).
The code flow is never interrupted anywhere else.

You should have used the throw/catch technique instead of simply 
setting a state (true/false) to control the iterations.

Besides that, I think your code is a little convoluted (basically, 
you're just inserting the body of a function in a while loop.
MarcS
3-Oct-2012
[1046x4]
ladislav: oh, d'oh -- thanks
steeve: right, the call has to be in tail position; thought i'd mentioned 
that in the docs but evidently not
[a] why would thow/catch be better here?
[b] why is it convoluted to convert to a loop?
Steeve
3-Oct-2012
[1050x2]
because you could use recurse from anywhere in the function not only 
at the tail
[B] it's not by definition, it's just the way you do it ;-)
MarcS
3-Oct-2012
[1052x4]
hmm, okay
i don't follow your point re: recursing from anywhere (i.e., from 
non-tail position)
via the use of throw/catch
if you're not in tail position you'd still have to push stack frames
Ladislav
3-Oct-2012
[1056]
Marc's code is an implementation of tail-recursive function. Such 
implementations have been posted by some people in the past, but 
there are some minor differences between them. For example, the way 
how the arguments were passed differed from Marc's idea.
Steeve
3-Oct-2012
[1057x2]
I thought you wanted to simulate tail/recursion only (it's what youre 
current code do anyway)
in that case you don't need to store the stack frame
To answer to the question: why tail recursion from anywhere ?
What if you want conditionned recursion ? 
Recurse could appear inside a IF block not at at the tail.
MarcS
3-Oct-2012
[1059x4]
aha, misunderstood your point
yes, there's a shortcoming if you're recursing from within a conditional 
-- thanks for spotting that; will rework
fix: http://0branch.com/highlight/snippets/rfunc3.r
though there's still the while loop wrapping the body
Ladislav
3-Oct-2012
[1063]
The WHILE loop is necessary for what you are doing, do not worry 
about it.
MarcS
3-Oct-2012
[1064x2]
damned silly mistakes -- was focused on getting the bindings etc. 
right, overlooked this prob
thanks for the help guys
Gregg
3-Oct-2012
[1066]
The usage comment in the third version is very nice. 


On doc strings, try to keep them short, leaving detailed notes to 
the usage or other comments. e.g.

rfunc: func [

    {Defines a tail-call optimized user function, using RECUR for self-calls.}
    spec [block!] "Function spec (see: func)"
    body [block!] "Function body (modified) (see: func)"
    /local wrapped
] [
    ...
] 

Short doc strings are nicer with HELP.
MarcS
3-Oct-2012
[1067]
thanks for the tip
Gregg
3-Oct-2012
[1068]
Also, I try to use special names for augmentations and such. In this 
case, 'with would conflict with my WITH func.
MarcS
3-Oct-2012
[1069x3]
hmm, yeah -- was wondering about that
that was originally _args_ but i switched it out so that you could 
get a more readable recur call (i.e., cheekily make use of 'with' 
so that it read better)
(for the BIND)
Gregg
3-Oct-2012
[1072x3]
Easy enough to add sigils to make it special. I don't general go 
as far as a gensym approach for things like this.
Yes. Too early for my brain here, but 'is known-word honored in the 
bind? e.g. "set with reduce (args)"
That is, 'with is special no matter what known-word you use, correct?
Ladislav
3-Oct-2012
[1075]
Marc, your "private variables" like 'with, _recur_ can be made more 
private not needing to use the PROtECT function, in fact.
Gregg
3-Oct-2012
[1076]
Ah, no, I think I get it now.
Steeve
3-Oct-2012
[1077]
I don't think you need 'with  at all, you can throw back the new 
parameters as an argument of the throw function, like:
>> throw/name reduce args 'recurse
Ladislav
3-Oct-2012
[1078]
also, there is a problem with the result I think