World: r4wp
[Rebol School] REBOL School
older newer | first last |
MarcS 3-Oct-2012 [1019] | as the title suggests, it's a fudge |
Ladislav 3-Oct-2012 [1020] | One immediate note: the RFUNC function as it is written actually modifies its SPEC and CODE arguments (that may be OK, but should be mentioned) |
MarcS 3-Oct-2012 [1021x2] | spec isn't modified |
re: body, is "Function body to be augmented w/ recursion context" not clear? [if not, will add clarification] | |
Ladislav 3-Oct-2012 [1023x2] | Actually, the SPEC block *is* modified, but in a way that may not matter often |
It might be better, though, to not modify it at all. | |
MarcS 3-Oct-2012 [1025] | what are you referring to? |
Ladislav 3-Oct-2012 [1026] | the USE function modifies its argument. |
MarcS 3-Oct-2012 [1027x2] | are you referring to shadowed bindings? |
like, rfunc [ _recur_ ] [ _recur_ ] won't do what i expect? | |
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. |
older newer | first last |