Return in function

285 views
Skip to first unread message

dh

unread,
Dec 11, 2009, 6:46:17 AM12/11/09
to

Version 7.0.1

Hello,

I am not sure if this is a feature or a bug. If you use Return in an

anonymous function, not only the return value is returned, but also

"Return" itself. Consider:

(If[# == 2, Return[a]; #, #]) & /@ {1, 2, 3}

this gives:

{1, Return[a], 3}

The same thing happens with:

Function[x, If[x == 2, Return[a]; x, x]] /@ {1, 2, 3}

However, the following works as expected:

f[x_] := (If[x == 2, Return[a]; x, x]);

f /@ {1, 2, 3}

Daniel

Bill Rowe

unread,
Dec 12, 2009, 6:57:08 AM12/12/09
to
On 12/11/09 at 6:46 AM, d...@metrohm.com (dh) wrote:

>anonymous function, not only the return value is returned, but also
>"Return" itself. Consider:

>(If[# == 2, Return[a]; #, #]) & /@ {1, 2, 3}

>this gives:

>{1, Return[a], 3}

I get the same result here and this does look like a bug. But
why use this construct at all? It seems to me easier to write:

If[# == 2, a, #]&/@{1, 2, 3}


DrMajorBob

unread,
Dec 12, 2009, 6:58:03 AM12/12/09
to
Return doesn't work as documented, but that's not the best reason to never
use it.

Your three examples should have been written as

If[# == 2, a, #] & /@ {1, 2, 3}

{1, a, 3}

Function[x, If[x == 2, a, x]] /@ {1, 2, 3}

{1, a, 3}

f[x_] := If[x == 2, a, x]


f /@ {1, 2, 3}

{1, a, 3}

Tortured constructions give unpredictable results, as a matter of simple
justice.

Bobby

On Fri, 11 Dec 2009 05:46:49 -0600, dh <d...@metrohm.com> wrote:

>
>
> Version 7.0.1
>
> Hello,
>
> I am not sure if this is a feature or a bug. If you use Return in an
>

> anonymous function, not only the return value is returned, but also
>
> "Return" itself. Consider:
>
>
>
> (If[# == 2, Return[a]; #, #]) & /@ {1, 2, 3}
>
> this gives:
>
> {1, Return[a], 3}
>
>
>

> The same thing happens with:
>
> Function[x, If[x == 2, Return[a]; x, x]] /@ {1, 2, 3}
>
>
>
> However, the following works as expected:
>
> f[x_] := (If[x == 2, Return[a]; x, x]);
>
> f /@ {1, 2, 3}
>
>
>
> Daniel
>
>
>


--
DrMaj...@yahoo.com

David Bailey

unread,
Dec 13, 2009, 4:47:40 AM12/13/09
to
DrMajorBob wrote:
> Return doesn't work as documented, but that's not the best reason to never
> use it.
>
> Your three examples should have been written as
>
> If[# == 2, a, #] & /@ {1, 2, 3}
>
> {1, a, 3}
>
> Function[x, If[x == 2, a, x]] /@ {1, 2, 3}
>
> {1, a, 3}
>
> f[x_] := If[x == 2, a, x]
> f /@ {1, 2, 3}
>
> {1, a, 3}
>
> Tortured constructions give unpredictable results, as a matter of simple
> justice.
>
> Bobby
>

Aren't you being a bit unfair, Daniel has obviously taken time to thin
out this example from whatever complicated context he found it in
originally - minimal examples of problems often don't make sense:)

David Bailey
http://www.dbaileyconsultancy.co.uk

Nasser M. Abbasi

unread,
Dec 14, 2009, 12:04:34 AM12/14/09
to

"David Bailey" <da...@removedbailey.co.uk> wrote in message
news:hg2d7s$j8a$1...@smc.vnet.net...

Not only that, but if someone can write code in any language such as the
output is "unpredictable" then there is something really wrong in this
picture.

No one should be able to write code in a well defined language such that the
output becomes "unpredictable". We are not dealing with the heisenberg
uncertainty principle here. May be the code is hard to understand, ok, but
"unpredictable"?

--Nasser


DrMajorBob

unread,
Dec 14, 2009, 12:06:14 AM12/14/09
to
Using Return encourages spaghetti and procedural code habits, and it
doesn't perform as advertised ANYWAY.

So don't use it.

Bobby

On Sun, 13 Dec 2009 04:38:13 -0600, David Bailey
<da...@removedbailey.co.uk> wrote:

> DrMajorBob wrote:
>> Return doesn't work as documented, but that's not the best reason to
>> never
>> use it.
>>
>> Your three examples should have been written as
>>
>> If[# == 2, a, #] & /@ {1, 2, 3}
>>
>> {1, a, 3}
>>
>> Function[x, If[x == 2, a, x]] /@ {1, 2, 3}
>>
>> {1, a, 3}
>>
>> f[x_] := If[x == 2, a, x]
>> f /@ {1, 2, 3}
>>
>> {1, a, 3}
>>
>> Tortured constructions give unpredictable results, as a matter of simple
>> justice.
>>
>> Bobby
>>
>

> Aren't you being a bit unfair, Daniel has obviously taken time to thin
> out this example from whatever complicated context he found it in
> originally - minimal examples of problems often don't make sense:)
>
> David Bailey
> http://www.dbaileyconsultancy.co.uk
>


--
DrMaj...@yahoo.com

E. Martin-Serrano

unread,
Dec 14, 2009, 12:06:58 AM12/14/09
to

-----Original Message-----
From: David Bailey [mailto:da...@removedbailey.co.uk]
Sent: Sunday, December 13, 2009 11:38 AM
Subject: Re: Return in function

DrMajorBob wrote:
> Return doesn't work as documented, but that's not the best reason to never

> use it.
>
> Your three examples should have been written as
>
> If[# == 2, a, #] & /@ {1, 2, 3}
>
> {1, a, 3}
>
> Function[x, If[x == 2, a, x]] /@ {1, 2, 3}
>
> {1, a, 3}
>
> f[x_] := If[x == 2, a, x]
> f /@ {1, 2, 3}
>
> {1, a, 3}
>
> Tortured constructions give unpredictable results, as a matter of simple
> justice.
>
> Bobby
>

Aren't you being a bit unfair, Daniel has obviously taken time to thin

out this example from whatever complicated context he found it in
originally - minimal examples of problems often don't make sense:)

David Bailey
http://www.dbaileyconsultancy.co.uk

Hi,

Sorry to intervene in the thread.

In any case, I am unable to grasp the kind of transgression made by Daniel.
As seen from "outside", Function[x, If[x == 2, Return[a], x]] /@ {1, 2, 3}
should work as expected. The problem is not with Daniel but with the so
called "unexpected results". I do not see any "tortured construction" in the
expression "Function[x, If[x == 2, Return[a], x]] /@ {1, 2, 3}". Is it
syntactically incorrect? No, it is not. And, if it is not, then the
compiler/interpreter should render what it is being asked to.

It sounds as if the semantics of the "Function[]" or "If[]" constructs were
a bit tortured instead. See this example from the Mathematica Help for
Return[] (Version 6). Strictly equivalent syntax form, but semantically
different according to the results

In[1]:= f1[x_] := (If[x > 5, Return[x]]; x + 3)

In[2]:= f1[6]

Out[2]= 6

Or the equivalent

In[1]:= f1[x_] := (If[x > 5, Return[a]]; x + 3)

In[2]:= f1[6]

Out[2]= a

And now the same expression under the Function[] construct

In[3]:= f2 = Function[{x}, (If[x > 5, Return[x]]; x + 3)];

In[4]:= f2[6]

Out[4]= Return[6]

Why does Return[] behave so different inside the Function[] construct. Maybe
nothing is wrong but clearly something is tricky.


E. Martin-Serrano


Bill Rowe

unread,
Dec 15, 2009, 7:26:52 AM12/15/09
to
On 12/14/09 at 12:04 AM, n...@12000.org (Nasser M. Abbasi) wrote:

>"David Bailey" <da...@removedbailey.co.uk> wrote in message
>news:hg2d7s$j8a$1...@smc.vnet.net...

>>Aren't you being a bit unfair, Daniel has obviously taken time to


>>thin out this example from whatever complicated context he found it
>>in originally - minimal examples of problems often don't make
>>sense:)

>Not only that, but if someone can write code in any language such as


>the output is "unpredictable" then there is something really wrong
>in this picture.

>No one should be able to write code in a well defined language such
>that the output becomes "unpredictable". We are not dealing with the
>heisenberg uncertainty principle here. May be the code is hard to
>understand, ok, but "unpredictable"?

You are being way over simplistic here. Any general purpose
programming language includes the capability of making arbitrary
edits to existing files. That implicitly means I can always
generate code which will cause unpredictable results.

=46urther, a design goal of Mathematica appears to be the ability
to do anything that is possible in Mathematics. Given that goal
and Godel's theorem, it will always be possible to generated
code which has unpredictable results.


magma

unread,
Dec 15, 2009, 7:27:36 AM12/15/09
to

It looks like a bug.
One thing I do not understand: what is the point of writing Return[a];
x in the definition of f[x_] ?
Anything after Return is discarded anyway.

Leonid Shifrin

unread,
Dec 16, 2009, 6:18:25 AM12/16/09
to
Hi Daniel,

My feeling is that this is not a bug.

There are two possible outcomes for any expression wrapped in Return: either
it is inside some lexical (or dynamic) scoping construct for which the
action of Return is defined - and then Return disappears as a part of
breaking-out-of-the-scoping-construct procedure, or it is not and then it is
just a symbolic expression like any other. It seems like neither Function
nor CompoundExpression are considered by Mathematica as the scoping
constructs for which the action of Return is defined as for example for
Module, Block, With, etc.

Under this assumption, your puzzle can be reduced to a simpler one:

In[1]:=
Clear[a,b,c];
c=(Return[a];3)

Out[1]= Return[a]

In[2]:=
b:=(Return[a];3)

In[3]:= b

Out[3]= a

The latter discrepancy can be explained by consulting the exact rules of the
evaluation procedure. Lacking a more up-to-date account, I cite here David
Withoff's "Mathematica internals" of 1992:

The very last step of the evaluation loop is (Chapter 3 - evaluation, p. 7,
on the bottom):

"Discard the head Return, if present, for expressions generated through
application of user-defined rules."

Thus, when you use SetDelayed, you create user-defined delayed rule and then
Return is discarded, while for "direct" evaluation like

In[4]:= Return[a]

Out[4]= Return[a]

it is not.

At least, things seem to work as documented in Withoff's technical report.
One thing that would be nice to have is a complete list of scoping
constructs for which Return is discarded when whatever it is wrapped around
is returned from that scoping construct.

Regards,
Leonid

Nasser M. Abbasi

unread,
Dec 16, 2009, 6:18:14 AM12/16/09
to

"Bill Rowe" <read...@sbcglobal.net> wrote in message
news:hg7vac$eq9$1...@smc.vnet.net...

Dictionary defines unpredictable as

unknown in advance; "an unpredictable (or indeterminable)
future"

I think may be there is a mixing between "result" of code, with "behavior"
of code?

When I type Random[], the behavior is predictable, it will generate random
number from the distribution that Random[] is defined at. The exact result
itself is "unpredictable", since it is ofcourse random. I can't in advance,
know the value that this call will result in. But one can certainly say
that the behavior of the code Random[] is predictable: It will generate a
random number drawn from some distribution.

If someone looks at a piece of code, and then say the result of this code is
"unpredictable", not because the result is a random number, but just because
of the way the code is written, then there is something wrong with the
language itself, because this means the definition of the language _itself_
is undefined, so as one is unable to decide how the language will behave in
this case.

We are talking about a computer programming language here.

I doubt very much one call sell a computer language to the Federal Aviation
Administration to write an aircraft guidance system if one tell them that it
is possible to write code in this language whose behavior can not be
predicted in advance.

--Nasser


Raffy

unread,
Dec 16, 2009, 6:21:11 AM12/16/09
to

I completely agree with the Return[]-retardness. Proper Return[]-
behavior can be implemented using Catch/Throw, but the overhead is
atrocious.

To the naysayers: Mathematica is multi-paradigm; I see nothing wrong
with procedural code if it makes your code more readable and
maintainable.

I feel the most elegant improvement for future versions of Mathematica
would BlockReturn[], WithReturn[], and ModuleReturn[].

However, this would still leave naked Return[]'s in their current
state.

David Park

unread,
Dec 16, 2009, 6:23:02 AM12/16/09
to
There is another use for the terms "predictable" and "unpredictable" in the
theory of computations. A computation is "predictable" if you can derive a
formula for the result without actually going through the entire
computation. I think this relates to NKS and some of the things Stephen
Wolfram is talking about. Much of classical physics concerned predictable
calculations and this has biased us in our view of what is a computation.
Most computations are not predictable, for example: the weather, the
economy, the evolution of society. If you want to know what the result is
you have to accurately simulate every step of the development, or let nature
do the computation and just wait and see.

A good book on this, that might also serve as an independent introduction to
NKS is 'The Lifebox, The Seashell, And The Soul: What Gnarly Computation
Taught Me About Ultimate Reality, The Meaning of Life, And How To Be Happy'
by Rudy Rucker. The book is more serious than the title might indicate.


David Park
djm...@comcast.net
http://home.comcast.net/~djmpark/

From: Bill Rowe [mailto:read...@sbcglobal.net]


On 12/14/09 at 12:04 AM, n...@12000.org (Nasser M. Abbasi) wrote:

>"David Bailey" <da...@removedbailey.co.uk> wrote in message
>news:hg2d7s$j8a$1...@smc.vnet.net...

>>Aren't you being a bit unfair, Daniel has obviously taken time to
>>thin out this example from whatever complicated context he found it
>>in originally - minimal examples of problems often don't make
>>sense:)

>Not only that, but if someone can write code in any language such as
>the output is "unpredictable" then there is something really wrong
>in this picture.

>No one should be able to write code in a well defined language such
>that the output becomes "unpredictable". We are not dealing with the
>heisenberg uncertainty principle here. May be the code is hard to
>understand, ok, but "unpredictable"?

You are being way over simplistic here. Any general purpose
programming language includes the capability of making arbitrary
edits to existing files. That implicitly means I can always
generate code which will cause unpredictable results.

=46urther, a design goal of Mathematica appears to be the ability
to do anything that is possible in Mathematics. Given that goal

and Godel's theorem, it will always be possible to generated
code which has unpredictable results.


Leonid Shifrin

unread,
Dec 17, 2009, 7:22:01 AM12/17/09
to
Nasser,

Take a look on the ANSI C standard, for example. It is full with cases where
some use of the language or standard library function will result in an
"undefined behavior". In practice, this means that such uses must be avoided
(at least if one wants to write portable code), but C does allow them (in
the sense that they compile), and my feeling is that in doing so it gains
much of its power, while remaining a reasonably small (compact) language.
And C is the language in which lots of mission - critical software has been
written.

Regards,
Leonid


On Wed, Dec 16, 2009 at 3:15 AM, Nasser M. Abbasi <n...@12000.org> wrote:

>
> "Bill Rowe" <read...@sbcglobal.net> wrote in message
> news:hg7vac$eq9$1...@smc.vnet.net...

Nasser M. Abbasi

unread,
Dec 17, 2009, 7:22:17 AM12/17/09
to

"----- Original Message -----
From: Leonid Shifrin

Nasser,

Take a look on the ANSI C standard, for example. It is full with cases where
some use of the language or standard library function will result in an
"undefined behavior"."

--------------------------

But that is _exactly_ my point.

For a well defined language, one can look at some code (legally written
code) and using the language reference manual, one can predict how this code
will behave (i.e. what it will do).

All what you said above means that C is not a well defined language.

My understanding all along, is that Mathematica is a _well_ defined
language, and its behavior is predictable. Even though I have not seen a
Mathematica language reference manual anywhere. If you are saying that
Mathematica is not well defined language, then I would take your word as I
am no expert in Mathematica.

------------------------------------------


" In practice, this means that such uses must be avoided (at least if one
wants to write portable code), but C does allow them (in the sense that they
compile), and my feeling is that in doing so it gains much of its power,
while remaining a reasonably small (compact) language. And C is the
language in which lots of mission - critical software has been written. "

--------------------------------------------

One can write mission critical software in a well defined language, no need
to use C for that, just because it is used there, does not mean it is the
right tool. But this is for another place to discuss.

regards,
--Nasser


DrMajorBob

unread,
Dec 17, 2009, 7:25:28 AM12/17/09
to
All well and good, but Return does NOT make code more readable.

Unless you're hooked on that kind of code, I suppose.

Anyway, Return doesn't do what it's supposed to do, so readability seems
irrelevant.

Bobby

On Wed, 16 Dec 2009 05:18:37 -0600, Raffy <ra...@mac.com> wrote:

> On Dec 11, 3:46 am, dh <d...@metrohm.com> wrote:

> I completely agree with the Return[]-retardness. Proper Return[]-
> behavior can be implemented using Catch/Throw, but the overhead is
> atrocious.
>
> To the naysayers: Mathematica is multi-paradigm; I see nothing wrong
> with procedural code if it makes your code more readable and
> maintainable.
>
> I feel the most elegant improvement for future versions of Mathematica
> would BlockReturn[], WithReturn[], and ModuleReturn[].
>
> However, this would still leave naked Return[]'s in their current
> state.
>


--
DrMaj...@yahoo.com

David Bailey

unread,
Dec 17, 2009, 7:26:55 AM12/17/09
to
Raffy wrote:
>
> I feel the most elegant improvement for future versions of Mathematica
> would BlockReturn[], WithReturn[], and ModuleReturn[].
>
I agree - something like that would be extremely useful. Return[] can be
extremely valuable when, for example, you need to temporarily skip part
of a function and return something just as a temporary thing for
development purposes. Embedding the code in an If can be much messier to
use for a 5-minute test!

David Bailey
http://www.dbaileyconsultancy.co.uk

Bill Rowe

unread,
Dec 17, 2009, 7:27:59 AM12/17/09
to
On 12/16/09 at 6:15 AM, n...@12000.org (Nasser M. Abbasi) wrote:

>"Bill Rowe" <read...@sbcglobal.net> wrote in message
>news:hg7vac$eq9$1...@smc.vnet.net...

>>You are being way over simplistic here. Any general purpose


>>programming language includes the capability of making arbitrary
>>edits to existing files. That implicitly means I can always
>>generate code which will cause unpredictable results.

>>=46urther, a design goal of Mathematica appears to be the ability
>>to do anything that is possible in Mathematics. Given that goal and

>>Godel's theorem, it will always be possible to generated code which
>>has unpredictable results.

>Dictionary defines unpredictable as

>unknown in advance; "an unpredictable (or indeterminable) future"

>I think may be there is a mixing between "result" of code, with
>"behavior" of code?

>When I type Random[], the behavior is predictable, it will generate
>random number from the distribution that Random[] is defined at. The
>exact result itself is "unpredictable", since it is ofcourse random.
>I can't in advance, know the value that this call will result
>in. But one can certainly say that the behavior of the code
>Random[] is
>predictable: It will generate a random number drawn from some
>distribution.

>If someone looks at a piece of code, and then say the result of this
>code is "unpredictable", not because the result is a random number,
>but just because of the way the code is written, then there is
>something wrong with the language itself, because this means the
>definition of the language _itself_ is undefined, so as one is
>unable to decide how the language will behave in this case.

>We are talking about a computer programming language here.

Yes, we are talking about a computer programming language here.
And it is entirely possible to write code in a well documented
general purpose computer language so that the *behavior* of the
code is entirely unpredictable. Simply write a pseudo-random
value to a memory location storing executable code. The usual
result of doing something like this is to crash the program or
operating system.

In a language like C or C++, this can happen when a pointer has
the wrong value. This kind of error is relatively easy to make.
And in a language like Forth, it can be particularly hard to
find since the result may well be a failure of previously
debugged code with no impact on the portion of code that
contains the error.


Richard Fateman

unread,
Dec 18, 2009, 6:24:34 AM12/18/09
to
Bill Rowe wrote:
...

> =46urther, a design goal of Mathematica appears to be the ability
> to do anything that is possible in Mathematics. Given that goal
> and Godel's theorem, it will always be possible to generated
> code which has unpredictable results.
>

If you truly believe this, then you probably should reconsider whether
you understand Godel's theorem or the nature of finite automata
(the basis of all computers).

Surely there are programs that can be expressed in Mathematica that
produce results that YOU can't predict, or even results that differ
from machine to machine or even time to time. But these are not
unpredictable. Simply build a computer than is 5% faster but otherwise
operates the same. Run it and you have a prediction that is 100% right.


As for the behavior of Return[], when there is no context available to
return from, that has been explained by reference to Withoff's book.
There are other PL, such as he-who-must-not-be-named, with more
versatile constructions resembling... return_from(name_of_block,value).

Mathematica's implementation seems to have replaced the situation of
error-no-block-to-return-from-....

to producing a value Return[some_value].

This is appears to be a dubious choice since it is unlikely that the
return, in-effect "Held" could later be "Released" with meaningful
semantics in general.

But the lack of adequate semantic models for parts of the language may
not be as important for Mathematica as for some other languages which
have to conform to some external standard. For Mathematica, there is
essentially only one implementation (latest version, anyway) and it is
what it is.

See

http://en.wikipedia.org/wiki/I_am_that_I_am
(I am what/that I am)

or

http://www.azlyrics.com/lyrics/eminem/thewayiam.html

(The Way I Am)

or I yam what I yam (Popeye the Sailor Man)


RJF


>

Norbert P.

unread,
Dec 30, 2009, 4:18:06 AM12/30/09
to
On Dec 11, 3:46 am, dh <d...@metrohm.com> wrote:

Even though I think that it's a bad habit to use Return, it might be
useful at times. And since it's been in Mathematica since the version
1, it should've been fixed a long time ago.

To make the code even simpler, try (version 6.0.2):

In[1]:= f[]:=(Return[a];1);

In[2]:= f[]
Out[2]= a

It works as expected. Now try

In[3]:= (Return[a];1)&[]
Out[3]= Return[a]

This is obviously a bug. One would expect to see "a" if Return worked
properly, or "1" if Return didn't work inside Function, but only in
definitions such as f[]:=... above.

I get a similar result using RuleDelayed as in

In[4]:= 2/. 2:>(Return[a];1)


Out[4]= Return[a]

The documentation is also contradictory. In the description of Return,
there's an example that shows that Return exists only the innermost
loop (construct) such as Do. Much like Break[], why isn't there Break
[expr] instead? But in tutorial/LoopsAndControlStructures they say:
Return[expr] return the value expr, exiting all procedures and loops
in a function

Best,
Norbert

Leonid Shifrin

unread,
Dec 31, 2009, 3:15:20 AM12/31/09
to
Norbert,

Had you followed the development of this thread and you would have noticed
my post where I argued that this is *not* a bug, although indeed a rather
unintuitive feature. The main authoritative source of information on this
matter (apart from the standard documentation) seems to be the technical
report by David Withoff named "Mathematica internals", of 1992. After making
my post I was additionally informed by Fred Simons that the behavior of
Return has been very nicely summarized by Allan Hayes back in 2002. I think
this may be of general interest so I repeat it here:

If Return[x] is generated as a value in Do or Scan then x is immediately
returned;
If Return[x] is generated as an entry in CompoundExpression or as a value of
the body of a While or For loop then Return[x] (not x) is immediately
returned;
If Return[x] is generated as the value of a user-defined function then the
function returns x (not Return[x])
Otherwise Return[x] behaves as a ordinary expression.

This seems to explain the behavior of Return in all cases (at least in my
experience).

Regards,
Leonid

On Wed, Dec 30, 2009 at 12:15 PM, Norbert P. <berta...@gmail.com> wrote:

> On Dec 11, 3:46 am, dh <d...@metrohm.com> wrote:

Leonid Shifrin

unread,
Jan 1, 2010, 5:37:35 AM1/1/10
to
Hi Bobby,

On Thu, Dec 31, 2009 at 10:26 AM, DrMajorBob <btr...@austin.rr.com> wrote:

> Explanations hidden in technical reports do not count as documentation, and
> neither do private communications between experts. (For the same reason.)
>
> If the behavior of Return is not a bug, it should be documented where users
> are likely to see it when looking up "Return" in Help.
>

Agreed. You have a point, and I also think that the documentation for Return
is inadequate. That said, most if not all of people participated in the
discussion in this thread are advanced Mathematica users, to say the least.
And although I don't know the exact circumstances and context in which the
OP (Daniel) encountered this problem, I have no doubt that he could and did
find a workaround even before posting the question.

I think that we all ask questions like this not because we are totally stuck
and see no way out, but in order to understand the system better, including
its darker corners. For a system as large and complex as Mathematica, I
think it is unavoidable to have a large number of such pitfalls, especially
because the system is evolving. Now, there are two ways of answering this
sort of questions: one is to rightly blame the documentation (which
generally is by far not the worst among those for the software I use) , and
another is to give some perhaps not hundred percent authoritative or
"official" but reasonable explanations. I find the latter more
constructive, given that it is the latter that most people with sufficient
Mathematica background seem to be interested in.


> The explanation below seems to be "retrospective cataloging of observed
> behavior", not "designed behavior".


I disagree. I think it is the designed behavior. And the fact that it has
been documented (albeit in a technical report) as early as in 1992, I think
speaks in favor of my guess. The problem is that the semantics of function
calls is emulated in Mathematica by the rule substitution. OTOH, for the
consistency of the system, Return must obey the standard mechanics of
evaluation process, as any other head. Since the decision do discard Return
is comming from the "external" to Return context, you can not just define
built-in DownValues for Return. Moreover, since Return performs a non-local
jump, you can not universally define UpValues for Return either. What are
your choices then?

Here is my guess. Making Return work in a block of code is not difficult -
all you have to do is to define an extra rule for CompoundExpression, which
will make it ignore its arguments standing after Return. In this way you
avoid the complexities and overhead of checking for Return in each of the
many kinds of scoping constructs. By not discarding Return at this stage you
make it possible to nest (break out of nested CompoundExpression-s):

In[1]:= (c; d; (a; b; Return[e]); f)

Out[1]= Return[e]

But this means that Return must be an idle head. Who will then be
responsible for discarding Return at the end? Not Return itself, and not the
scoping constructs which presumably know nothing about Return. It may be
that a universal solution to this problem does not exist or is very hard to
find/prove correct.

The design decision concerning Return seems to have been made such in order
for a user of Return to see no difference from the action of Return in other
languages, *in most sensible cases*. Since the overwhelming majority of
uses of Return are inside some user-defined functions (rules), a single
simple rule of discarding Return generated through application of
user-defined rules covers all such cases. This seems to be one of the cases
where generality has been traded for simplicity, and in this particular case
this looks like a very reasonable solution to me.I wonder how many beginners
or even intermediate Mathematica users ever stumbled upon anything like
Daniel's original example - I think very few.

>
>
> This seems to explain the behavior of Return in all cases (at least in my
>> experience).
>>
>

> Exactly. Your next experience may be different, and you'd simply add it to
> the list.
>

True. But notice that the list is quite short, and it summarizes experiences
of several people, not just me. And somehow in the case of Return I doubt
that it will grow significantly, if at all.

Regards,
Leonid

>
> Bobby

>>> Even though I think that it's a bad habit to use Return, it might be
>>> useful at times. And since it's been in Mathematica since the version
>>> 1, it should've been fixed a long time ago.
>>>
>>> To make the code even simpler, try (version 6.0.2):
>>>
>>> In[1]:= f[]:=(Return[a];1);
>>>
>>> In[2]:= f[]
>>> Out[2]= a
>>>
>>> It works as expected. Now try
>>>
>>> In[3]:= (Return[a];1)&[]
>>> Out[3]= Return[a]
>>>
>>> This is obviously a bug. One would expect to see "a" if Return worked
>>> properly, or "1" if Return didn't work inside Function, but only in
>>> definitions such as f[]:=... above.
>>>
>>> I get a similar result using RuleDelayed as in
>>>
>>> In[4]:= 2/. 2:>(Return[a];1)
>>> Out[4]= Return[a]
>>>
>>> The documentation is also contradictory. In the description of Return,
>>> there's an example that shows that Return exists only the innermost
>>> loop (construct) such as Do. Much like Break[], why isn't there Break
>>> [expr] instead? But in tutorial/LoopsAndControlStructures they say:
>>> Return[expr] return the value expr, exiting all procedures and loops
>>> in a function
>>>
>>> Best,
>>> Norbert
>>>
>>>
>>>
>>
>>
>

> --
> DrMaj...@yahoo.com
>

DrMajorBob

unread,
Jan 1, 2010, 5:38:16 AM1/1/10
to
> Here is my guess. Making Return work in a block of code is not
> difficult...

Subsequently, I think you explained why it's not not only difficult, but
impossible.

So we're back to my original advice: don't USE Return, and you won't have
to worry about it.

Bobby

On Thu, 31 Dec 2009 22:23:20 -0600, Leonid Shifrin <lsh...@gmail.com>
wrote:


--
DrMaj...@yahoo.com

DrMajorBob

unread,
Jan 1, 2010, 5:33:58 AM1/1/10
to
Explanations hidden in technical reports do not count as documentation,
and neither do private communications between experts. (For the same
reason.)

If the behavior of Return is not a bug, it should be documented where
users are likely to see it when looking up "Return" in Help.

The explanation below seems to be "retrospective cataloging of observed

behavior", not "designed behavior".

> This seems to explain the behavior of Return in all cases (at least in my
> experience).

Exactly. Your next experience may be different, and you'd simply add it to
the list.

Bobby

Leonid Shifrin

unread,
Jan 2, 2010, 5:05:54 AM1/2/10
to
Well, I do occasionally use Return, but admittedly not very often.
Ironically, it seems like Return was mostly designed to ease the transition
to Mathematica for users with procedural background, who are very likely to
use it since they don't know about other ways to accomplish their goals. But
I agree that you have a point.

Regards,
Leonid

On Fri, Jan 1, 2010 at 2:38 AM, DrMajorBob <btr...@austin.rr.com> wrote:

> > Here is my guess. Making Return work in a block of code is not
> > difficult...
>
> Subsequently, I think you explained why it's not not only difficult, but
> impossible.
>
> So we're back to my original advice: don't USE Return, and you won't have
> to worry about it.
>

> Bobby


>
> On Thu, 31 Dec 2009 22:23:20 -0600, Leonid Shifrin <lsh...@gmail.com>
> wrote:
>
> > Hi Bobby,
> >
> > On Thu, Dec 31, 2009 at 10:26 AM, DrMajorBob <btr...@austin.rr.com>
> > wrote:
> >

> >> Explanations hidden in technical reports do not count as documentation,
> >> and
> >> neither do private communications between experts. (For the same
> >> reason.)
> >>
> >> If the behavior of Return is not a bug, it should be documented where
> >> users
> >> are likely to see it when looking up "Return" in Help.
> >>
> >

> >> The explanation below seems to be "retrospective cataloging of observed
> >> behavior", not "designed behavior".
> >
> >

> >> This seems to explain the behavior of Return in all cases (at least in
> >> my
> >>> experience).
> >>>
> >>
> >> Exactly. Your next experience may be different, and you'd simply add it
> >> to
> >> the list.
> >>
> >

> > True. But notice that the list is quite short, and it summarizes
> > experiences
> > of several people, not just me. And somehow in the case of Return I doubt
> > that it will grow significantly, if at all.
> >
> > Regards,
> > Leonid
> >
> >
> >
> >>

> --
> DrMaj...@yahoo.com
>
>

Reply all
Reply to author
Forward
0 new messages