Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2005
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Re: Types in Mathematica

  • To: mathgroup at smc.vnet.net
  • Subject: [mg62904] Re: [mg62872] Re: Re: Types in Mathematica
  • From: Sseziwa Mukasa <mukasa at jeol.com>
  • Date: Thu, 8 Dec 2005 00:04:45 -0500 (EST)
  • References: <dn22fb$kum$1@smc.vnet.net> <200512070411.XAA23826@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

On Dec 6, 2005, at 11:11 PM, Steven T. Hatton wrote:

>> Fair enough but Head[{1,2,3}] is not Symbol.
>
> I would say that we have to be clear about what we mean by "Head 
> [{1,2,3}]".

I meant the value of evaluating the expression.

> At one level, it is nothing but a sequence of characters.  When
> Head[{1,2,3}] is evaluated, a downvalue is added to In

That's a side effect of the evaluator, and can be suppressed anyway.   
I don't consider In and Out to be fundamental to the operation of  
Mathematica.  In fact their existences is one of the areas in which  
Mathematica breaks with being purely functional but that's another  
issue.  Others like Jon Harrop probably have far more intelligent  
things than me to say on that subject.

> A.9.2 in the 5.2 Mathematica Book says "A Mathematica expression  
> internally
> consists of a contiguous array of pointers, the first to the head,  
> and the
> rest to its successive elements."  I find that statement very  
> incomplete.

I don't know why, it simply betrays Mathematica's LISP like roots,  
and as Daniel Lichtblau pointed out is to be read more as a model for  
reasoning than as to how Mathematica is actually implemented.  At any  
rate in the purest forms of LISP that's all one has an atom, which is  
defined as an indivisible S-expression and a list which is an S- 
expression of two parts the first is called the head or car and the  
second a pointer to the rest of the list.  I believe I read somewhere  
that Mathematica's representations of expressions are called M- 
expressions and were actually the intended syntax for LISP but for  
some reason S-expressions ended up being preferred.

> In any case, (I believe) the leaves of an expression will be atoms  
> of one
> kind or another.  The atoms are (AFAIK) the only entities in  
> Mathematica
> which hold data.

Heads have values too, an atomic expression is simply one which you  
can't take apart any further, but the atomic expression 1 has a head  
in Mathematica and the head has a value.  The fact that we display  
and write 1 instead of Integer[1]  is syntactic sugar as far as I'm  
concerned because at that point we are typically more interested in  
the interpreting Integer[1] as a value which is the result of some  
computation which is really what one is interested in.

> there are clearly different types of atomic expressions.

Especially if you consider the heads of atoms as defining their type,  
which is why I think that is a useful paradigm for reasoning about  
types in Mathematica.  The fact that Head[Sqrt[2]] isn't Sqrt as Jon  
Harrop pointed out seems to me more an artifact of the evaluator than  
a problem with Mathematica.

>> There are different kinds of statements in C++ of which expressions
>> are but one class (http://cpp.comsci.us/syntax/).  There are no
>> different kinds of expressions in Mathematica all have the same
>> structure Head[Arguments...].
>
> How is that different from saying there are atomic expressions and  
> composite
> expressions in Mathematica?  Is 1 of the form Head[Arguments...]?

However the expression Integer[1] is represented internally, and for  
efficiency's sake it's hard to imagine that it occupies multiple  
words of machine storage, is irrelevant as to how one should reason  
about Mathematica programs.  It's also irrelevant that the Notebook  
Interface displays it as 1 instead of Integer[1].  The question is  
whether one can reason about a program correctly, it seems to me  
ambiguity can be best avoided by understanding 1 to be a) atomic and  
b) representing Integer[1].

>>> What confusion?
>>
>> The confusion over exactly what constitutes a type in Mathematica.
>
> Since there is no formal definition, it is strictly a matter of  
> opinion,
> and/or convention.  Since there seems to be little in the way of  
> commonly
> agreed upon convention, we are stuck with relying on opinion.

But as you pointed out yourself Wolfram documents exactly what  
everything in Mathematica is in A.9.2, it's an expression.  Some  
expressions are atomic, and if you want to assign a "type" to the  
atoms other than expression the best candidate I can see is the head.

>> You can't inspect the structure of the function in C++ because it's a
>> function definition and there is no facility for programmatically
>> inspecting the contents of a definition in C++.  In Mathematica the
>> contents are stored as an expression in the DownValues which can be
>> modified as any other expression in Mathematica sans restrictions.
>
> But that really seems to rely on the fact that C++ is a compiled  
> language,
> whereas Mathematica is interpreted.

I don't think that matters.  The distinction that's important is  
between statements and expressions, LISP like languages do not have a  
statement type and it is that fact that allows "functions" to be  
treated as a first class types.

> I believe there are important distinction between the way C++ and  
> Mathematica
> support operator overloading.

I do too, but I don't think we agree on what the distinction is.

>> For the sake of brevity and in the correct context clarity, it helps
>> to refer to things like Plus[a_,b_] as a function or operator and For
>> [...] as a statement but the truth is in Mathematica they are both
>> expressions and equivalent in that sense.  Making the distinction may
>> be useful to thinking about problems from the programmer's
>> perspective but there is nothing within Mathematica itself that
>> forces that distinction unlike in C++ where function+(a,b) and for
>> (...){} are different.
>
> I don't follow.  I can write a function
>
> Vector3f plus(const Vecotr3f& v1, const Vecotr3f& v1) {
>   return Vector3f(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
> }
>
> and
>
> Vector3f operaotr+(const Vecotr3f& v1, const Vecotr3f& v1) {
>   return plus(v1,v2);
> }
>
> Then write va + vb to add two Vector3f objects.  How does that  
> compare to
> overloading + in Mathematica?

It's roughly equivalent except in Mathematica I can programmatically  
rewrite the rules for + whereas there is no such facility in C++.  I  
suppose you can consider that an artifact of the fact that C++ is  
compiled (actually is that a requirement?  http://root.cern.ch/root/ 
Cint.html) but I think the real reason for the difference is that  
operator+ is a statement in C++ and there are no facilities for  
programmatically altering statements.

> When trying to represent an ensamble of interacting physical  
> objects, I find
> it useful to be able to maintain state.  In OOP that is fairly
> straightforward.  This is why I like development libraries such as
> OpenSceneGraph.  I've done similar things with Mathematica, but it  
> has not
> been quite as easy.

I've had similar problems, but usually I found that reorganization of  
the problem either allowed the writing of expressions that could  
compute a representation of state when necessary, and at no more  
expense than maintaining a state variable, or obviated the need  
altogether.  When translating programs implemented in other languages  
or interacting with such programs I've found that naively trying to  
use that paradigm in Mathematica leads to difficult to maintain code  
and often it's better to just rewrite the algorithm in a different  
style.  One example are divide and conquer algorithms for linear  
algebra problems.  Typically they are implemented with state  
variables that keep track of indices of submatrices and operations  
like multiplying a matrix against a submatrix of a larger one.  I've  
found that recasting the algorithm as functions which do basic  
operations and encasing them in structures like FoldList, Nest etc.  
which construct the final result from the submatrices leads to  
clearer, if not necessarily more efficient, Mathematica code.

On the other hand, I've noticed a trend in OO graphics programs for  
defining 3 and 4D vectors and matrices as classes and then  
overloading +,-,* etc. which leads to inefficient code like

t=a*b;
d=c*t

instead of

d=a*b*c

which is one of the problems that Blitz++ tries to address.  As we've  
both noticed Blitz++ addresses this problem by using C++ templates  
(and the CPP) to effectively convert statements to expressions which  
can be optimized for efficiency similar to the fundamental difference  
between operator overloading in c++ and Mathematica.

> Part of the problem is that I really didn't understand
> Mathematica well when I started using things such as Dr. Maeder's  
> Classes
> package.

I have heard a lot about Dr. Maeder's package on this mailing list  
but I have not personally used it or investigated it much.

Regards,

Ssezi


  • Prev by Date: Re: Re: Re: Types in Mathematica, a practical example
  • Next by Date: Re: Re: Types in Mathematica thread
  • Previous by thread: Re: Re: Types in Mathematica
  • Next by thread: Re: Re: Re: Types in Mathematica