MathGroup Archive 2005

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

Search the Archive

Re: Types in Mathematica

  • To: mathgroup at smc.vnet.net
  • Subject: [mg63008] Re: Types in Mathematica
  • From: "Steven T. Hatton" <hattons at globalsymmetry.com>
  • Date: Sun, 11 Dec 2005 04:56:31 -0500 (EST)
  • References: <dn22fb$kum$1@smc.vnet.net> <200512081442.jB8EgCda002721@ljosalfr.globalsymmetry.com> <F44AB4A1-92CA-49D7-ABDD-E94D8270B8EC@jeol.com> <200512081419.17348.hattons@globalsymmetry.com> <dnbmt9$5qf$1@smc.vnet.net> <-4qdnaBC0M37OgTeRVn-uQ@speakeasy.net> <dned7g$6d$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Sseziwa Mukasa wrote:

> 
> On Dec 9, 2005, at 10:48 AM, Steven T. Hatton wrote:
> 
>>
>> Sseziwa Mukasa wrote:
>>>> But a Complex will always have a real and an imaginary component.
>>>> A Rational
>>>> will always have a numerator and a denominator.
>>>
>>> And a List always contains zero or more expressions.
>>
>> I don't see that to be containment in the same sense as a Complex
>> contains
>> its values.
> 
> You're right it's not exactly the same because Complex is an atom and
> a list is not.

Atoms really do seem to satisfy the definition of abstract data type.  One
might even say they satisfy the definition of object in the OOP sense.

>> expression/symbol with the head Complex.
> 
> Only an expression can have the head Complex, a symbol has the head
> Symbol and to prevent confusion I think we should agree to keep that
> straight.

I stand corrected.  Thanks for pointing that out.  You have inspired me to
attempt a UML class diagram of Mathematica data types.  It will indeed be
rooted with expression.  The problem with that model is that we never have
a thing we refer to as "Expression" within the language.

>>   Even if we do view an
>> expression with the head List as a data structure containing elements
>> (often called arguments), we are still able to describe it in terms
>> of the
>> functions which can operate on it, as well as the data abstraction it
>> represents.
> 
> Of which the abstraction is what?

Well, do you _need_ to know the details of how it is implemented in order to
use it?  List is kind of like a "brown paper wrapper" expression.  Its head
is a Symbol named "List" which has certain attributes. Beyond that,
whatever else it does seems to be determined by what it "inherits" from
"Expression".  I'll have more to say on this soon...I hope.

>> When using expressions to represent ADTs we usually don't want to
>> simply
>> extract values using Part.  We want to treat it as if we do not
>> know the
>> internal structure.  We only know the interface.
> 
> I don't think I agree with this, we know several things about Part
> with respect to expressions:

That's not the point.  I'm talking about a protocol based on mutual
agreement, not a law enforced by software (though there are ways of hiding
internal structure of an ADT - or so Maeder claims.)  This is similar to
the way SIMULA originally handled data abstraction.  It's as if we
implemented our C++ classes as struct with all public data members, and
simply agreed to only use the member functions to access the internal
structure.  In principle you /could/ access the member data, but that would
violate the design principle.

> Part cannot take anything beyond the 0th 
> (head) element of atoms, Part returns a Message

I'm not sure I would use the term "Message" here.  But then, "message" is
something I consider specific to SmallTalk, and not generally useful when
discussing OOP.

> when the index is 
> greater than the depth of the expression being taken apart, Part
> returns the expression corresponding to an argument of the larger
> expression when 0 < the second argument to part <= Depth[first
> argument].  If you consider the arguments to be internal structure 
> then the behavior of Part makes it necessary that you treat
> expressions as if you know something about their internals.  It also
> makes clear what an atom is: a Depth 0 object.

What you are describing is the interface to Expression.  I'm talking about
creating things as composite expressions and treating them _as if_ they
were atomic.

>> You cannot extract the components of an expression with head
>> Complex using
>> Part[].
> 
> Because by definition you cannot do that to any atom and an
> expression of the form Complex[_,_] is an atom.
> 
>>   You have to "ask nicely".  For Lists, I believe that Part[] /is/
>> "asking nicely".
> 
> I don't consider this exceptional, all you have to do is distinguish
> the behavior of Part between things that are atoms and things that
> are not, all the rest follows logically.

The point I'm trying to make is that Atoms are staticly defined data types. 
In reality, they are considered constants.  You cannot change the value
of/in an Atom.  You can only replace the whole Atom.  With an Expression,
you /can/ change its contents. 

>> I just found this and have only glanced at it, but I believe it
>> will give a
>> good context for further discussion on this matter:
>>
>> http://library.wolfram.com/infocenter/Conferences/4680/
> 
> Thank you for the pointer, I'll read it.

I did read it quickley.  It appears Maeder would have had a stronger type
system in Mathematica.  This is what I was really trying to get at when I
started this thread ... back in the Early Modern Era.  I suspect there were
discussion about this sort of thing in the early days, and the notion of a
type system along the lines of C++ was rejected.  Was it just a question of
who could yell loudest or pout longest, or were there solid reasons for not
taking that approach?

What would happen if users could define Atom-like types?  That is, types
that only expose their content through an interface.  Whoops!  That's OOP! 
One of the bigest problems, as I see it, is the lack of automatic type
conversion.

>> What determines (holds) the value of Arg[1+I]?
> 
> The value of Arg[1+I] is Arg[1+I] 

Are you talking about the pattern, or the result given by evaluating the
expression?

> there are also rewrite rules for 
> equivalent expressions where equivalence is defined by expr1==expr2
> being congruent to True eg:
> 
> In[54]:=
> FullForm[Arg[1 + I]]
> Arg[1 + I] == Times[1/4, Pi]
> 
> Out[54]//FullForm=
> Times[Rational[1,4],Pi]
> 
> Out[55]=
> True.

Indeed, another pit of vipers I seem to have stepped into.  What I should
have written was What determines (holds) the value of Arg[1+I]//N?

>>   Where does it "live"?
> 
> In the space of arguments to the evaluator.  Since there are rewrite
> rules associated with Arg one has to be careful about when they look
> at an Arg expression depending on what they want to do with it.

This is certainly a point of frustration I have with Mathematica.  If I look
at the documentation for Arg[], I am not given a comprehensive description
of its behavior.
 
> There are actually some very interesting theoretical on relations and
> how then end up being implemented in RDBMSes (short version,
> poorly).

Not sure exactly what you mean here.  If you are talking about RDBMS vs. say
ODBMS, I haven't seen much come out of ODBMS which I found useful.  The
idea is attractive, but the reality becomes quite a mess.  I really wasn't
suggesting we could, or should, try to describe Mathematica "things" as
entries in an RDBMS, I would merely using the example in order to motivate
the analogy of an axis.

> While we continue on our tour of programming languages the 
> logic languages 

??  What do you mean here?  Can you provide an example?  I have been
glancing at SML over the past few days.  I also compiled and crashed Axiom.

> would be appropriate examples for reasoning about 
> relations.  And they too bear a strong relationship (pun not
> intended) to LISP like languages.

I suspect most languages that strive to capture the essence of mathematical
reasoning will be expressed in a prefix functional form similar to
Mathematica's internal form.  It may not be easy to read or write
expressions in that form, but it makes writting the evaluator much simpler. 
Since Lisp already works this way (moving the head inside the '(',')'), the
will have similarities to Lisp.

>> UpValues
>> DownValues
>> OwnValues
>> SubValues
> 
> These things are side effects of the evaluator, like In and Out, not
> fundamental.  They are very useful though because they describe
> expressions we can use to interact with the rewrite rules used by the
> evaluator itself.

They _are_ the rewrite rules.  At least from the user's perspective.  Do you
not agree?  See 2.6.2 in the Help Browser.

> Attributes are definitely an interesting beast, I'm not sure but I
> suspect they can be considered a special set of rules used by the
> evaluator.

I am willing to bet they are simply bits in a single int variable in the
Symbol struct.  What the consequences of their being there are, is a
different story.  They may well be arguments to a switch statement.

>> internal data
> 
> I'm not sure internal data is any more worth worrying about to a
> Mathematica programmer as a naked quark is to a nuclear engineer.

You may not be interested in the details, but knowing that there is data in
there, and what kind of data abstraction it represents, is certainly
useful.

>> messages
> 
> Message are just expressions, which is why you can trace on Message
> [___] to stop evaluation at a point a message is issued.  Messages
> are not atomic.

It appears there is actually an Expression "Messages" associated with a
Symbol that has messages, so it might be meaningful to view them as member
data of the Symbol.  The are certainly not accessed using a part
specification.

>> Context (symbol is probably best understood as a fully qualified
>> name.)
> 
> Likewise a Context is just another expression whose value is a side
> effect of the evaluator (in particular of Get[] and Needs[]
> expressions). 

Contexts are Strings Head[Context[Arg]]. That's why they need to be quoted
when given as arguments to expressions.

> To reason about these things is to reason about the 
> rewrite rules of the evaluator, but is aside from the idea of types.

I don't agree.  The items I listed are the abstract data members of the
"type" Symbol.  The evaluator doesn't have rewrite rules any more than a
compiler has function definitions.  The rules exist in the expression
structure passed to the evaluator.
-- 
The Mathematica Wiki: http://www.mathematica-users.org/
Math for Comp Sci http://www.ifi.unizh.ch/math/bmwcs/master.html
Math for the WWW: http://www.w3.org/Math/


  • Prev by Date: Re: Types in Mathematica
  • Next by Date: How to compute this sum?
  • Previous by thread: Re: Types in Mathematica
  • Next by thread: Re: Re: Re: function of a function