Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Single-step evaluation in Mathematica

70 views
Skip to first unread message

Szabolcs Horvát

unread,
Sep 17, 2007, 3:36:14 AM9/17/07
to

I would like to have a function, hasOwnValue, that takes the name of a
symbol as a string, and tells whether the symbol has an own-value. It
should do this without evaluating the value of the symbol.

Examples:

abc := Print["side effect"]
xyz =.

In := hasOwnValue["abc"] (* "side effect" must not be printed *)
Out = True

In := hasOwnValue["xyz"]
Out = False

How can I achieve this?

This is a practical problem that I ran into, but the general question
is: What do you do when you feel the need for *single-step evaluation*
in Mathematica? E.g. how can I manipulate/transform held expressions
made up of symbols that have values? An artificial example:

a = 1
Hold[{a,b,c}]

How do I reverse the list inside Hold? I could map Hold to each
element, reverse the list, hold the list again, and remove Hold from
individual elements to get Hold[{c,b,a}], but this is very inconvenient.

Szabolcs

Jean-Marc Gulliet

unread,
Sep 18, 2007, 12:37:04 AM9/18/07
to
Szabolcs Horv=C3=A1t wrote:

> I would like to have a function, hasOwnValue, that takes the name of a
> symbol as a string, and tells whether the symbol has an own-value. It
> should do this without evaluating the value of the symbol.
>
> Examples:
>
> abc := Print["side effect"]
> xyz =.
>
> In := hasOwnValue["abc"] (* "side effect" must not be printed *)
> Out = True
>
> In := hasOwnValue["xyz"]
> Out = False
>
> How can I achieve this?

The following function check whether a symbol has any ownvalues defined
and returns True or False, accordingly. Note that we set the attributes
HoldAll to the function so it does not evaluate its argument and one can
use the regular name of the symbols rather than wrapping them in a
string to prevent evaluation.

In[1]:= hasOwnValueQ[s_Symbol /; OwnValues[s] === {}] = False;
hasOwnValueQ[s_Symbol] = True;

SetAttributes[hasOwnValueQ, HoldAll];

abc := Print["side effect"]
xyz =.

efg = 6;

hasOwnValueQ[abc]
hasOwnValueQ[xyz]
hasOwnValueQ[efg]

Out[7]= True

Out[8]= False

Out[9]= True

--
Jean-Marc


Andrzej Kozlowski

unread,
Sep 18, 2007, 12:56:22 AM9/18/07
to

On 18 Sep 2007, at 01:07, Szabolcs Horv=E1t wrote:

> On 17/09/2007, Andrzej Kozlowski <ak...@mimuw.edu.pl> wrote:
>> SetAttributes[f, HoldAll]
>> f[x_String] := ValueQ @@ ToExpression[x, InputForm, Hold]
>
> Thank you for the reply! This solution works perfectly (HoldAll isn't
> even needed)!

You are right, of course. I originally intended to define f both for
strings symbols expressions but forgot about the latter:

SetAttributes[f, HoldAll]
f[x_String] := ValueQ @@ ToExpression[x, InputForm, Hold]
f[x_Symbol]:=ValueQ[x]

Andrzej


> The missing piece was the third argument of
> ToExpression[]. I have always thought that ToExpression[] takes only
> a single argument---I should check the documentation more often. I
> tried using Symbol[] too, which, according to the documentation,
> should "refer to a symbol with the specified name". But it turns out
> that Symbol["abc"] does not _refer_ to the symbol 'abc'; it simply
> _evaluates to_ 'abc'. For example, Symbol["abc"] = 1 does not work.
>
> Szabolcs


Andrzej Kozlowski

unread,
Sep 18, 2007, 1:02:32 AM9/18/07
to

On 17 Sep 2007, at 16:32, Szabolcs Horv=E1t wrote:

>
> I would like to have a function, hasOwnValue, that takes the name of a
> symbol as a string, and tells whether the symbol has an own-value. It
> should do this without evaluating the value of the symbol.
>
> Examples:
>
> abc := Print["side effect"]
> xyz =.
>
> In := hasOwnValue["abc"] (* "side effect" must not be printed *)
> Out = True
>
> In := hasOwnValue["xyz"]
> Out = False
>
> How can I achieve this?
>

> This is a practical problem that I ran into, but the general question
> is: What do you do when you feel the need for *single-step
> evaluation*
> in Mathematica? E.g. how can I manipulate/transform held expressions
> made up of symbols that have values? An artificial example:
>
> a = 1
> Hold[{a,b,c}]
>
> How do I reverse the list inside Hold? I could map Hold to each
> element, reverse the list, hold the list again, and remove Hold from
> individual elements to get Hold[{c,b,a}], but this is very
> inconvenient.
>
> Szabolcs
>


There is of course the built in function ValueQ which essentially
does what you are askign for:

abc := Print["side effect"]

ValueQ[abc]
True

abc =.
ValueQ[abc]
False

Of course the difference here is that the argument of VlaueQ is an
expression and not the string that is the name of the expression.
However, you can make it work with strings:

SetAttributes[f, HoldAll]
f[x_String] := ValueQ @@ ToExpression[x, InputForm, Hold]

Now:

abc := Print["side effect"]

f["abc"]
True
abc =.
f["abc"]
False

Andrzej Kozlowski


Andrzej Kozlowski

unread,
Sep 18, 2007, 1:03:33 AM9/18/07
to

On 17 Sep 2007, at 19:21, Andrzej Kozlowski wrote:

> *This message was transferred with a trial version of CommuniGate
> (tm) Pro*


I forgot about the second part of your question. I don't think it is
possible to achiev ein Mathematica "signle step evaluation" of the
kind you seem to be askign for. However, there are many ways to
acheive the fect you desire. The one that I woudl choose involves
working inside Block with the variables you do not want to evaluate
localized, e.g.:

a = 1;
s = Hold[{a, b, c}];
Block[{a}, Hold @@ Reverse /@ List @@ s]
Hold[{c, b, a}]

Andrzej Kozlowski=

Chris Chiasson

unread,
Sep 18, 2007, 5:53:53 AM9/18/07
to

It would be quite trivial to achieve single step evaluation if the
*Values of all the system variables were readable. However, they are
not.

I recommend reading:
http://library.wolfram.com/conferences/devconf99/villegas/UnevaluatedExpres=
sions.nb

(or, in HTML)

http://library.wolfram.com/conferences/devconf99/villegas/UnevaluatedExpres=
sions/

Also, I would recommend these two posts for the held evaluation
properties of Block, With, Module, RuleCondition, $ConditionHold, and
the multi argument Function:

http://forums.wolfram.com/mathgroup/archive/2007/Aug/msg00958.html

http://forums.wolfram.com/mathgroup/archive/2007/Sep/msg00327.html


--
http://chris.chiasson.name/


0 new messages