8

Reading the comments in this answer has motivated me to request a full solution to part of this problem.

What I'd like is an efficient solution that returns True if there exist an OwnValue and False in all other cases. This narrow behavior mirrors what folks coming from other programming languages expect of asking if something has a value or not.

A solution needs to be able to handle symbols with any number of OwnValue, UpValues, DownValues, SubValues, NValues, and FormatValues. The only evalution that should occur is that required to get the value of the symbol's OwnValue.

Motivation

My motivation for this request is twofold.

  1. There have been many queries on this topic, but none that appear to be specific enough to narrow down to one correct interpretation. I hope this question solves that.
  2. The behavior requested mirrors the behavior of most programming languages that folks are familiar with. That is, when we think of a symbol/"variable" having a value, we really mean to ask if the symbol has some OwnValues or not. Yes there are other interpretations of what it means to have a ValueQ that does not do extra evaluations, but this question does not cover them.
nixeagle
  • 2,263
  • 1
  • 18
  • 24
  • This is a rather complex problem. This inspired me to ask the same (thinking that a solution is ready), but it turned out to have some more subtle points. – Szabolcs Mar 23 '12 at 21:05
  • It is a duplicate indeed. However, those answers need a kind of a "philosophical" update, because what looks at the surface as a problem of evaluation leaks is in fact a problem of the impedance mismatch between Mathematica evaluation process and what we usually mean when saying that something has a value. One of the solutions by @Mr.Wizard can actually IMO serve as a definition for ValueQ consistent with Mathematica's evaluation semantics - but it turn out to not be very useful in practice, since it triggers even trivial evaluations. – Leonid Shifrin Mar 23 '12 at 21:08
  • 1
    In other words, the main problem is to distinguish between evalations which we consider leaks and those which we don't. The comments below the solution of @Mr.Wizard and this chatroom contain more on that. – Leonid Shifrin Mar 23 '12 at 21:11
  • Alright, I understand the vote to close as a duplicate. However I still would like to see a complete and reasonably efficient solution to this problem. I've seen it mentioned in several other answers and on stack overflow enough that I feel a solid solution would be helpful to us all. Please note that I did not see the other question proposed as a possible "answer" to mine when I submitted this one. – nixeagle Mar 23 '12 at 21:14
  • @nixeagle But did you look at the link given by Szabolcs? It is not the same one as you linked to in your question. I gave a partial solution there, and I'd argue that the problem is not well-defined in general. And if you try to make it well-defined, I suspect that you will open a big can of worms. – Leonid Shifrin Mar 23 '12 at 21:16
  • @leo yea I looked at it just now, but I was unaware of it at the time I submitted. I'm of two minds if this is truely a duplicate or not though :/. Here I'm asking for a reasonably efficient full solution to a problem that so far has only incomplete answers scattered about. Regardless I really don't care if a full solution solving this is posted under this question or any other ;). I've only noticed the longstanding problem while doing my recent hobby of reading all the submitted questions on this new site that I missed while I was away ;). – nixeagle Mar 23 '12 at 21:18
  • @sza, I"ve updated this question to be more specific on what a full solution requires. – nixeagle Mar 23 '12 at 21:22
  • @nixeagle Well, as far as I am concerned, the full solution can not be given because the problem is not well defined. If you look at the links I gave, you will see my line of reasoning. In a way, my solution is full, within given constraints which were a part of my interpretation of the problem. The solution of Mr.Wizard is also full one, given his interpretation. This is not as trivial as it may seem, once you start digging into it deep enough. The real problem IMO is in the fundamental difference between mma evaluation process and evaluation in other languages we are used to. – Leonid Shifrin Mar 23 '12 at 21:24
  • @leonid, Even with my updated definition? That is the only evaluation that should occur is that required to get the symbol's OwnValue. This would be equivalent (somewhat) to commonlisp symbol manipulation. In common lisp symbols have multiple values associated with them, a symbol-value, function-value, macro-value, documentation-value, attribute-list-value (also known as a plist), and so on. If I missed a full solution meeting those constraints then I feel that this question has no place here and ought to be closed. – nixeagle Mar 23 '12 at 21:28
  • @nixeagle Yes, even for your updated definition. In general, it is IMO not possible to determine whether a given expression (like say f[x]) will evaluate to something else (call it a value) without actually performing a full evaluation. So, the only possibility is to clone all symbols in the dependency tree of a given symbol, and evaluate the expression in a separate dynamic environment with the clones (so that any changes in clones won't affect the rest of the system). This will, however, be prohibitively expensive. – Leonid Shifrin Mar 23 '12 at 21:33
  • @leo, so to be clear, f[x] the symbol can have a value that is not the result of evaluating the associated function? And that we are really unable to tell if the symbol is a function or not without actually asking MMA to evaluate it? I am aware that MMA is essentially a glorified pattern matcher and that fact may play a role into this problem. – nixeagle Mar 23 '12 at 21:37
  • @nixeagle Consider an example: ClearAll[g];g[x_]:=(flag=True);f[x_]/;g[x]:=x^2. The point is, f[x] will evaluate to x^2, but it is not clear to me how you can establish this fact without leaking evaluation, because, if you don't allow any evaluation, you won't know whether the condition is True or False. You can find a way for this particular example, but imagine more complicated definitions and tests. – Leonid Shifrin Mar 23 '12 at 21:41
  • @leo, Well that to me reads like a function call not a OwnValue. I really think I'm massively confused now. I understand that you guys have a ton more experience than I, but yet I'm struggling to see why I can't just dismiss f[x] as having no OwnValue and reacting accordingly. MMA.SE has been suggesting I move this to chat for the last 2 or 3 replies... should we do so? – nixeagle Mar 23 '12 at 21:46
  • @nixeagle If you think of it, the problem is really in the fundamentally different from other languages paradigm of term-rewriting, used by M, in particular masqueraded by more familiar notions of variables, functions, etc. There are really no variables and functions in M, and for that matter, no values - just expressions. And M's notion of what to consider an evaluation is different from ours: most sub-evaluations done in the process of evaluating a given expression are trivial, but from the M's viewpoint, there is no natural way to distinguish. – Leonid Shifrin Mar 23 '12 at 21:50
  • 2
  • 1
    @Mr.Wizard please see the chat conversation leo and I had. I was in the process of narrowing this question down to request a very specific behavior that has only one valid answer, leo agreed that doing so would be a worthwhile action. I really would like to have this re-opened so I may narrow the question down correctly so it is not a duplicate. – nixeagle Mar 23 '12 at 22:18
  • Well actually looks like I'm allowed to further edit the question while it is closed. Anyhow, I'd like this to be re-opened so that a specific solution to this problem can be provided. We actually already know the solution (check the chat), but I'd like it be be here crystal clear for others who want this behavior as well. – nixeagle Mar 23 '12 at 22:30
  • Reopened per request. – Mr.Wizard Mar 23 '12 at 22:59
  • Thank you @Mr.Wizard. I've went ahead and clarified the question's intent as well as provided the answer that leo gave. He requested I go ahead and self answer. I've taken the time to explain the various issues and why there is oftentimes confusion with what ValueQ should "mean". Hopefully this question and answer(s) will prove worthwhile to keep as it is narrowly focused to one specific interpretation of the ValueQ questions. – nixeagle Mar 23 '12 at 23:27
  • After looking at your update, it is still not clear how this is appreciably different from the other question. Also, if you only pass a single symbol to it, ValueQ does not leak evaluation. – Szabolcs Mar 24 '12 at 16:02
  • The point is specifically to never leak evaluation ever and to define the problem in such a way that there is only one reasonable interpretation of what it means. Every other related discussion on this gets tied up in the various interpretations of what ValueQ does. This lays it out in black and white what the meaning of it is and how to get an alternate (sometimes expected) meaning. – nixeagle Mar 24 '12 at 16:45
  • @nixeagle Yes, you're right, there's value in having such a function. In fact in practice I only use ValueQ for OwnValue, so why not explicitly restrict it to that? – Szabolcs Mar 24 '12 at 17:17
  • @szabolcs This is why the answer leo and I came down to is essentially that. We define ownValueQ to mean ValueQ by the second definition given. Mathematica has its reasons for defining ValueQ as it does, but this is not always what users expect or want. I've tried to make this distinction clear here with this question and answer. Hopefully it is clear enough to help other users who run into this and wonder. A question about how to get ValueQ to be "safe" using Mathematica's meaning is fodder for another question. – nixeagle Mar 24 '12 at 17:27

1 Answers1

10

Leonid and I had a very productive chat with the end result of Leonid asking me to go ahead and post the answer. If others have a better answer to this narrowly phrased question please do not let my submission deter you!

Essentially the problem with these "safe" ValueQ questions is one of interpretation. What does it mean when we ask if a symbol has a value?

  1. Mathematica says a symbol has a value if it has any of the following: OwnValues, UpValues, DownValues, NValues, SubValues or FormatValues. This makes sense in the context of MMA being essentially a glorified pattern matcher.
  2. Folks that come from a non MMA background with prior programming experience will say that a symbol only has a value if it has some OwnValues. This mirrors the behavior of nearly every non MMA programming language in existence.

In order for MMA to implement #1 above, MMA chooses to do some evaluation in order to determine if any of the Up/Down/N/Sub/Format values actually contain a meaningful value. This is the heart of the problem. If the user expects behavior #2, that can be had with a very simple function that requires no evaluation at all.

SetAttributes[ownValueQ,HoldAll];
ownValueQ[s_Symbol] := ValueQ[s]; 
ownValueQ[_]        := False

The above includes no evaluation as the implementation of ValueQ when handling OwnValues on a symbol is:

HoldComplete[sym]=!=(HoldComplete[sym]/.OwnValues[sym])
Sjoerd C. de Vries
  • 65,815
  • 14
  • 188
  • 323
nixeagle
  • 2,263
  • 1
  • 18
  • 24