Comments on: Should all functions return values?

Carl Sassenrath, CTO
REBOL Technologies
8-May-2006 23:27 GMT

Article #0024
Main page || Index || Prior Article [0023] || Next Article [0025] || 22 Comments || Send feedback

The suggestion has been made: should all functions return values? It is interesting to consider, and I am looking for your comments on this topic.

Actually, it turns out that all functions actually do return values internally in existing versions of REBOL. But, some functions return the unset value, which makes it appear as if the function returned no result.

The argument in favor of making all functions return arguments is primarily from usage cases such as:

if error? err: try [write %file data] [...]

The problem here is that write does not return a result, so err variable cannot be set, and most of the time an error will result.

** Script Error: err needs a value
** Near: error? err: try [write %file data]

A small number of other cases exist, such as when using print (which does not return a result).

It would be a simple matter to allow such functions to return a value, probably one of their arguments.

So, what do you think?



Gregg Irwin
8-May-2006 19:59
We can safely ignore values, and I have a lot of places where I have to use set/any (exactly the scenario you mention), or where I synthesize a result for a func, rather than passing back the result of a func that returns unset!. So, I'm all for it.

Was there a particular reason you returned unset! in the current design?

Is there any downside, aside from blurring the distinction between PRINT and PROBE?

Gregg Irwin
8-May-2006 20:00
I think the only reason I could come up with before was for output purposes in the console, which works nicely with PRINT the way it is.
Carl Sassenrath
8-May-2006 20:22
The original reason was to prevent accidents like:

name: age: date: city: print something

But, in retrospect, such a "catch" is not really that beneficial.

8-May-2006 23:33
I vote for returning values for everything. That would be true to functional programming, no? As a beginner with REBOL, I don't know the difference between what returns values and what doesn't, and consistency is always a plus.
9-May-2006 1:01
Hi Carl,

there are only very few functions where the catch, would, well, catch. So I value consistency higher, and all in all those functions not returning a real value often lead to more complicated code (like in your example).

'print on the console is nice the way it is now, but I it wouldn't be a problem if it returned a value.

Brian Hawley
9-May-2006 1:38
I'm OK with it either way, really. The main advantage of it would be to make unset! more of an exceptional value, useful for debugging uninitialized variables.

Would EXIT become a shortcut for RETURN NONE ?

Mark Ingram
9-May-2006 4:05
I use functions that return unset! all the time. A call to such a function can be inserted into a script at ANY word-break, even (indeed especially) in between consecutive arguments to another function. This is a real treasure, and even though I use it mainly for debugging no IDE or debugging hooks will really be as convenient IMHO.

Please do not remove this capability.

9-May-2006 4:41
:) Mark, I'm not sure what you mean by placing a function that returns UNSET! between arguments of another function. Can you provide an example?
9-May-2006 4:41
:) I'm OK if most of the function return a value, but I would like to still be able to create and use function that doesn't return a value.

For example, in the prolog.r script, I use that to distinguish bound or free variable.

Ryan Cole
9-May-2006 4:41
:) Its important for built in functions and modules to return something useful, if even rarely useful, as its better than work arounds for unset values.

Oust unset altogether? not a big issue here.

9-May-2006 10:29
The existing work-around for this problem is adequate:

if error? err: try [write %file data true] [...]

It seems simpler to document that in the case of the few functions that return unset! than it would be to add an extra refinement (or whatever) to each of them

Mark Ingram
9-May-2006 12:22
My apologies, Gabriele (and everybody). What was I thinking?

Upon more careful review, what I thought was the parser swallowing unset! values in some special fashion was simply the normal REBOL discarding of (arbitrary) values during execution. My unset! functions work just fine when they return actual values (which are then discarded). I still like the unset! value and its special treatment because it catches many beginner mistakes, but I suppose I could live without it now.

Here's hoping Marco's reason is good enough ...

PS I promise never to post at 4 am again.

9-May-2006 14:04
:) I don't understand : a function which returns no values is not a function, it is a command or a procedure ?

I come from LOGO where "procedures" are commands (-> they return no value) or operations (= function -> they return a value) ... the difference is shown by the command "output" which returns explicitly something. Nevertheless Logo is still a functionnal language [as Rebol].

9-May-2006 14:20
My vote would be to add a return value to all the built in functions, but to keep the ability to write functions that return unset.
Gregg Irwin
9-May-2006 17:41
So, we like the way PRINT works, and we want the ability to use this feature ourselvesm, leaving the issue of functions that return unset!, but cause more work because they do (e.g. WRITE).

Do we have a list of all functions that return unset!? Should we address them on a case-by-case basis, rather than changing the underlying rules?

9-May-2006 18:52
Bertrand -- REBOL doesn't really distinguish procedures from commands.

A function cam return a value, or it can return no value (ie it returns unset!)

Try this: t: func [n] [if n = 3 [return n * 2] exit] type? t 3 type? t 1

You'll see the function can return an integer! or unset! depending on its argument.

Of course, in this case I've used 'exit which explicitly returns unset!

The main thrust of the blog entry is whether a function show implicitly be allowed to return an unset!

As always, there are reasons for and reasons against.

Anton Rolls
10-May-2006 2:05
Well, I would miss unset! I've written a number of console commands that wouldn't work so well if there was a forced return value, which would be molded and printed into the console. I like things the way they are with respect to that. Imagine if print was like probe ?

>> print 123 123

>> probe 123 123 == 123

10-May-2006 3:08
My typical problem this error-case. Could that be addressed differently? Maybe 'try could return none on unset? You could revisit error-catching anyway, I usually want to log an error, and maybe have a default value. 'attempt dont give me an error, 'try looks ugly. Maybe Ladislavs 'default inbuild?
10-May-2006 3:08
:) Even if print return the value, print and probe are different, because print reform the value but probe mold it.
11-May-2006 13:52
with the exception to print, I'd favor returning unset in as little core commands as default.

unset! is usefull but its more of an advanced feature used by the few rather than the many.

12-May-2006 9:25
Agreed. The first time one must figure out what happens here, without real benefit.

How about 'true as default-return? Works well inside attempt, and i use it rarely for other things.

Philippe Oehler
30-May-2006 2:39
:) We got with 'func the option to ask the 'user of the function to respect the precontract with [string!][block!] in the definition of the function... so could it be a line i.e. /return out [string!] (like /local) in the func definition, specifying the returned type that the function must return.. (post-contract) ?

Post a Comment:

You can post a comment here. Keep it on-topic.


Blog id:



 Note: HTML tags allowed for: b i u li ol ul font span div a p br pre tt blockquote

This is a technical blog related to the above topic. We reserve the right to remove comments that are off-topic, irrelevant links, advertisements, spams, personal attacks, politics, religion, etc.

Updated 25-Jun-2024 - Edit - Copyright REBOL Technologies -