Value return after computation
There is a simple and general pattern in code that takes this form:
a: do [b: c d b]
We want the value of c (the first expression) returned, not d (the second) so we must use b as a temporary in order to return it.
rev: func [str /local tmp] [ tmp: copy str reverse str tmp ]
This code seems longer than we need. We'd prefer to write:
a: c d
but, of course, that returns d and not c.
Stated in English it is "return the result of the first computation". We want to follow the return value with a function that is not to be computed but not returned.
We could invent a function that evaluates c and d but returns c:
a: follow [c d]
The follow function could be defined as:
follow: func [blk] [first reduce blk]
(Another possible name might be after. But, let's just use follow for right now and think about the name later.)
Now, the above example becomes:
rev: func [str] [ follow [ copy str reverse str ] ]
Of course, there is additional overhead in that approach: an extra function call and a block reduction. An alternative is:
rev: func [str] [ follow copy str reverse str ]
This form can be defined as:
follow: func [a b] [:a]
There has also been a suggestion to add an /after refinement to return. For example:
rev: func [str] [ return/after copy str reverse str ]
This is trivial to implement, but it is only effective for function return cases, not the general pattern. But, maybe the function return case is the most common.
If you have ideas or insights, I welcome you to post a comment.
Updated 9-Jun-2023 - Copyright Carl Sassenrath - WWW.REBOL.COM - Edit - Blogger Source Code