From: V.Ch.
Subject: How powerful macros are?
Date: 
Message-ID: <d1si41$d95$1@gavrilo.mtu.ru>
Currently my knowledge of macros (and Lisp as a whole) is extremely 
superficial, so forgive me if it's a silly question, but... Can I use 
macros to make

(setf (aref a 12) 13)

look something more like

a[12] = 13?

I've started playing with List just few weeks ago. I think I got used to 
  somewhat weired loops, branching, etc; but using arrays, and in 
particular, assigning to arrays, seems clumsy enough to be a show-stopper.

From: obfuscatedcode
Subject: Re: How powerful macros are?
Date: 
Message-ID: <1111612981.391295.225340@g14g2000cwa.googlegroups.com>
>macros to make

>(setf (aref a 12) 13)

>look something more like

>a[12] = 13?

The answer is, "yes and no". There are some rather less-discussed parts
of common lisp called "read-macros". Using these it is possible to
create syntax which turns something like a[12] = 13 into (setf (aref a
12) 13) at read-time.

I have actually done this before (ducks to avoid pure lisper
projectiles), though infrequently, to aid in porting Java code to lisp.
As an example, I'll include the code for what I did.

Basically, the syntax I created translated:

  #$array[index]

into

  (aref array index)

(Not exactly what you wanted, but something like it.)

Because I'm using read-macros, I can do things like:

  (setf #$array[index] 15)

and it would work like you'd expect.

Anyway, here is what the code looks like:

(defun read-array-index-macro (stream char1 char2)
  (declare (ignore char1 char2))
  (let ((var-name (read stream t nil t))
        (indices (read stream t nil t)))
    `(aref ,var-name ,@indices)))

(defun read-array-index (stream char)
  (declare (ignore char))
  (read-delimited-list #\] stream t))

(set-macro-character #\[ #'read-array-index)
(set-macro-character #\] (get-macro-character #\) ))
(set-dispatch-macro-character #\# #\$ #'read-array-index-macro)

It works by altering the common lisp readtable to call
READ-ARRAY-INDEX-MACRO whenever the lisp reader sees `#$'. Then my code
reads enough to perform the transformation from the #$ syntax to (aref
...).
From: Marco Antoniotti
Subject: Re: How powerful macros are?
Date: 
Message-ID: <h5l0e.56$fp1.87636@typhoon.nyu.edu>
V.Ch. wrote:
> Currently my knowledge of macros (and Lisp as a whole) is extremely 
> superficial, so forgive me if it's a silly question, but... Can I use 
> macros to make
> 
> (setf (aref a 12) 13)
> 
> look something more like
> 
> a[12] = 13?

Yes you can.  Look at the INFIX package in the CMU AI.Repository.

However, first it does not mean that you want to do it, second you'd 
better ask the question:  cai I use other macro systems to make C++ or 
Java or Perl

	a[12] = 42;

look like

	(setf (aref a 12) 42)

?


> 
> I've started playing with List just few weeks ago. I think I got used to 
>  somewhat weired loops, branching, etc; but using arrays, and in 
> particular, assigning to arrays, seems clumsy enough to be a show-stopper.

You have a very low tolerance.  How are you going to ever learn the 
basics of APL?  Or INTERCAL?

Cheers
--
Marco
From: V.Ch.
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1sni3$fr6$1@gavrilo.mtu.ru>
Marco Antoniotti wrote:
> Yes you can.  Look at the INFIX package in the CMU AI.Repository.
Thanks, I'll certainly have a look at it!
Btw, the name "infix" looks very promising. Can it even...?

> However, first it does not mean that you want to do it, second you'd 
> better ask the question:  cai I use other macro systems to make C++ or 
> Java or Perl
> 
>     a[12] = 42;
> 
> look like
> 
>     (setf (aref a 12) 42)
> 
> ?
Hmmm, and why would I want to translate in that direction? I know, lots 
of code looks very fashionably lately, some people even tried to 
convince me that in proper languages you need to create class to write 
"hello world", but still...

> You have a very low tolerance.  
Well, stong words and emotional language help to get you noticed (and 
your question answered), aren't they?
From: Marco Antoniotti
Subject: Re: How powerful macros are?
Date: 
Message-ID: <SWl0e.57$fp1.87741@typhoon.nyu.edu>
V.Ch. wrote:
> Marco Antoniotti wrote:
> 
>> Yes you can.  Look at the INFIX package in the CMU AI.Repository.
> 
> Thanks, I'll certainly have a look at it!
> Btw, the name "infix" looks very promising. Can it even...?
> 
>> However, first it does not mean that you want to do it, second you'd 
>> better ask the question:  cai I use other macro systems to make C++ or 
>> Java or Perl
>>
>>     a[12] = 42;
>>
>> look like
>>
>>     (setf (aref a 12) 42)
>>
>> ?
> 
> Hmmm, and why would I want to translate in that direction?

Same question, same question :)  The issue is that in CL I can do it 
relatively easily.   You cannot as easily do it in any other language 
(save, maybe, Prolog)

> I know, lots 
> of code looks very fashionably lately, some people even tried to 
> convince me that in proper languages you need to create class to write 
> "hello world", but still...

At the CL prompt "hello world", is just "hello world" :)

> 
>> You have a very low tolerance.  
> 
> Well, stong words and emotional language help to get you noticed (and 
> your question answered), aren't they?

Yep, they do.

Cheers
--
Marco
From: Christopher C. Stacy
Subject: Re: How powerful macros are?
Date: 
Message-ID: <uwtrygldw.fsf@news.dtpq.com>
"V.Ch." <····@notreal.com> writes:

> Currently my knowledge of macros (and Lisp as a whole) is extremely
> superficial, so forgive me if it's a silly question, but... Can I use
> macros to make
> 
> (setf (aref a 12) 13)
> 
> look something more like
> 
> a[12] = 13?
> 
> I've started playing with List just few weeks ago. I think I got used
> to somewhat weired loops, branching, etc; but using arrays, and in
> particular, assigning to arrays, seems clumsy enough to be a
> show-stopper.

Lisp is not for you.
From: Harald Hanche-Olsen
Subject: Re: How powerful macros are?
Date: 
Message-ID: <pcowtryyssn.fsf@shuttle.math.ntnu.no>
+ ······@news.dtpq.com (Christopher C. Stacy):

| Lisp is not for you.

It's not for him /yet/.  He may still see the light some day.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: V.Ch.
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1smqv$fga$2@gavrilo.mtu.ru>
Christopher C. Stacy wrote:
> Lisp is not for you.

Actually, you may very well be right. Right now Lisp looks interesting 
to me, but I can't properly explain why. May be, there is indeed 
something original (and useful!) in it. Or may be the reason is no 
better than the reason why some people stop to look at road accidents.
From: Frank Buss
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1sko7$k4u$1@newsreader2.netcologne.de>
"V.Ch." <····@notreal.com> wrote:

> Currently my knowledge of macros (and Lisp as a whole) is extremely 
> superficial, so forgive me if it's a silly question, but... Can I use 
> macros to make
> 
> (setf (aref a 12) 13)
> 
> look something more like
> 
> a[12] = 13?

you should do some more Lisp programming, then it feels more natural, 
because the underlying "place" concept is very general and can be used 
for all kinds of variable settings, for example:

CL-USER > (defparameter *test* '(1 2 3))
*TEST*

CL-USER > (setf (car *test*) 5)
5

CL-USER > *test*
(5 2 3)

And another concept is, that every first symbol of a list is interpreted 
as a function call (or macro), so "(setf (aref a 12) 13)" looks very 
natural for Lisp programmers.

But of course, you can use macros to define your C syntax. A dirty hack:

(defmacro a (string)
  (let ((equal-position (position #\= string))
        (open-position (position #\[ string))
        (close-position (position #\] string)))
    (let ((variable (string-trim " " (subseq string
                                             0
                                             open-position)))
          (index (string-trim " " (subseq string 
                                          (1+ open-position) 
                                          close-position)))
          (value (string-trim " " (subseq string
                                          (1+ equal-position)))))
      (with-input-from-string
          (in (format nil "(setf (aref ~a ~a) ~a)" variable index value))
        (read in)))))


CL-USER > (setf a (make-array 20))
#(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL 
NIL NIL)

CL-USER > (a "a[12]=(* 21 2)")
42

CL-USER > (aref a 12)
42


But if you need lots of array access, it is a better idea to define some 
macros or function which does more what your problem needs, and not 
trying to re-implement C syntax.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Rob Warnock
Subject: Re: How powerful macros are?
Date: 
Message-ID: <m7SdnS5UusQ73t_fRVn-3A@speakeasy.net>
Frank Buss  <··@frank-buss.de> wrote:
+---------------
| "V.Ch." <····@notreal.com> wrote:
| > Currently my knowledge of macros (and Lisp as a whole) is extremely 
| > superficial...
| 
| you should do some more Lisp programming, then it feels more natural, 
| because the underlying "place" concept is very general and can be used 
| for all kinds of variable settings, for example:
| CL-USER > (defparameter *test* '(1 2 3))
| *TEST*
| CL-USER > (setf (car *test*) 5)
| 5
| CL-USER > *test*
| (5 2 3)
+---------------

Frank, when speaking to raw newbies it's important to encourage
good habits from the very start, and *not* to encourage undefined
behavior, even though it might require a few more bytes of typing
when constructing examples. One hopes that you really meant to write
the following instead, yes?

  CL-USER > (defparameter *test* (list 1 2 3))


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Frank Buss
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1tki2$arp$1@newsreader2.netcologne.de>
····@rpw3.org (Rob Warnock) wrote:

> One hopes that you really meant to write
> the following instead, yes?
> 
>   CL-USER > (defparameter *test* (list 1 2 3))

yes, thanks. I think this is the HyperSpec chapter, which explains why my 
example was wrong:

http://www.lisp.org/HyperSpec/Body/sec_3-7-1.html

I think I can do it with copy-seq, too:

(defparameter *test* (copy-seq '(1 2 3)))

But how to handle nested lists? I think this could fail:

(defparameter *test* (copy-seq '(1 (2 3) 4)))
(setf (caadr *test*) 9)

I need something like a deep-copy-seq. But is it possible to write such a 
function, which can handle all literal objects, for example arrays?

(defparameter *test* (deep-copy-seq '(1 #(2 3) 4)))

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Rob Warnock
Subject: Re: How powerful macros are?
Date: 
Message-ID: <etednYDYDa-4Fd_fRVn-rQ@speakeasy.net>
Frank Buss  <··@frank-buss.de> wrote:
+---------------
| But how to handle nested lists? I think this could fail:
| 
| (defparameter *test* (copy-seq '(1 (2 3) 4)))
| (setf (caadr *test*) 9)
+---------------

As Andras Simon noted, COPY-TREE would handle this one.
[But not your next one...]

+---------------
| I need something like a deep-copy-seq. But is it possible
| to write such a function, which can handle all literal objects,
| for example arrays? 
| (defparameter *test* (deep-copy-seq '(1 #(2 3) 4)))
+---------------

Perhaps, if you go no farther than including arrarys containing
"simple" constants, such as this example...

But this is an old and very rich topic, much-discussed in this group.
It turns out that "deep copying" is not a well-defined, or at least
not a universal, operation, any more than "deep equality" is. The
upshot is that in DEEP-COPY, "the right thing" turns out to be very
application-dependent. Look for past threads with subjects like
"multiple copies of a CLOS object?", especially the comments in those
threads by Kent Pitman, who has written what is now a short classic
on the topic -- <http://www.nhplace.com/kent/PS/EQUAL.html> -- which
despite the URL & title is about copying as well, and should help
answer your question.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Frank Buss
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1vmue$jbi$1@newsreader3.netcologne.de>
····@rpw3.org (Rob Warnock) wrote:

> It turns out that "deep copying" is not a well-defined, or at least
> not a universal, operation, any more than "deep equality" is.

that's right for a general deep copy. But what should I do for literals? 
Sometimes it is useful to define an array like '#(1 2 3) and later I want 
to change the elements of it, but it is too easy to forget to copy the 
array first and trying to modify the literal array. In C I can say this:

const int a[] = { 1, 2, 3 };

and trying to write "a[1]=10" results in a compile time error. But when I 
write this:

int a[] = { 1, 2, 3 };

I can later change the elements in the array (I hope it's legal in C) and 
it works like expected.

Perhaps in some Lisp implementations with higher safe levels there are 
warnings, but would be nice, if every undefined behaviour would be caught 
by the language (at least for example with safe-level=fool-proof), 
without the need for the programmer to take care of it.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Andras Simon
Subject: Re: How powerful macros are?
Date: 
Message-ID: <vcdis3h32g9.fsf@csusza.math.bme.hu>
Frank Buss <··@frank-buss.de> writes:


> But how to handle nested lists? I think this could fail:
> 
> (defparameter *test* (copy-seq '(1 (2 3) 4)))
> (setf (caadr *test*) 9)

COPY-TREE

Andras
From: V.Ch.
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1smll$fga$1@gavrilo.mtu.ru>
Frank Buss wrote:
> But if you need lots of array access, it is a better idea to define some 
> macros or function which does more what your problem needs, and not 
> trying to re-implement C syntax.
> 

That's probably the way, thanks. Perhaps, in real programs you can 
indeed create some more specific macros or functions.
However, it still seems strange that such a basic construct as array 
must be so verbose. Right now I am trying to get used to Lisp by solving 
problems from Topcoder web site, and all of them involve array handling.
From: Ulrich Hobelmann
Subject: Re: How powerful macros are?
Date: 
Message-ID: <3ae71vF68n0eiU2@individual.net>
V.Ch. wrote:
> That's probably the way, thanks. Perhaps, in real programs you can 
> indeed create some more specific macros or functions.

I would expect any real program to hide array accesses in a module 
anyway.  You'll probably rather work with higher-level data 
structures, so you only have to type the array access/modification 
code once :)

> However, it still seems strange that such a basic construct as array 
> must be so verbose. Right now I am trying to get used to Lisp by solving 
> problems from Topcoder web site, and all of them involve array handling.

What's basic about arrays?  It's a data type with an accessor 
function.  You can fetch the value with (aref a 3) und store a 
value just there with (setf (aref a 3) 'bla).

Often you'll use lists in lisp; they're are much more flexible. 
If you need random access, and the size of your data structure is 
fixed, then create the array.
From: V.Ch.
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1spf5$gdm$1@gavrilo.mtu.ru>
Ulrich Hobelmann wrote:
> What's basic about arrays?  ...
> Often you'll use lists in lisp; they're are much more flexible. 

Oh well... Just 2 points:

1. Do you remember your very first program that implemented some 
algorithm on some kind of a data structure? Which data structure it was?

2. It's the natural structure for computer hardware. Eventually, 
everything comes down to manipulating raw data in RAM - Random Access 
Memory - a vector, basically.
From: Ulrich Hobelmann
Subject: Re: How powerful macros are?
Date: 
Message-ID: <3aebm5F69joffU1@individual.net>
V.Ch. wrote:
> Oh well... Just 2 points:
> 
> 1. Do you remember your very first program that implemented some 
> algorithm on some kind of a data structure? Which data structure it was?

Lists and binary trees in C.  In several variations.  Lists are so 
useful in programming, it's incredible.

> 2. It's the natural structure for computer hardware. Eventually, 
> everything comes down to manipulating raw data in RAM - Random Access 
> Memory - a vector, basically.

Right.  But they are inflexible, i.e. most useful for bulk 
processing or numerical (matrix) computations.
From: Pascal Costanza
Subject: Re: How powerful macros are?
Date: 
Message-ID: <3ae8tqF6apilpU1@individual.net>
V.Ch. wrote:
> Ulrich Hobelmann wrote:
> 
>> What's basic about arrays?  ...
>> Often you'll use lists in lisp; they're are much more flexible. 
> 
> Oh well... Just 2 points:
> 
> 1. Do you remember your very first program that implemented some 
> algorithm on some kind of a data structure? Which data structure it was?

Numbers. ;)

> 2. It's the natural structure for computer hardware. Eventually, 
> everything comes down to manipulating raw data in RAM - Random Access 
> Memory - a vector, basically.

The idea of high-level languages is to use structures that are natural 
for the programmer, or even the user.


Pascal
From: Frank Buss
Subject: Re: How powerful macros are?
Date: 
Message-ID: <d1t85g$l81$1@newsreader2.netcologne.de>
"V.Ch." <····@notreal.com> wrote:

> Right now I am trying to get used to Lisp by
> solving problems from Topcoder web site, and all of them involve array
> handling. 

perhaps you can post a solution and we can try to show you how to enhance 
it.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Pascal Costanza
Subject: Re: How powerful macros are?
Date: 
Message-ID: <3ae5i6F6bdek4U1@individual.net>
V.Ch. wrote:
> Currently my knowledge of macros (and Lisp as a whole) is extremely 
> superficial, so forgive me if it's a silly question, but... Can I use 
> macros to make
> 
> (setf (aref a 12) 13)
> 
> look something more like
> 
> a[12] = 13?

This is a very superficial notational issue. Lisp macros are not about 
changing these kinds of notational issues, but about hiding unimportant 
information. For example, in a for loop, or other looping constructs, 
you are hiding the fact that you are effectively using gotos underneath. 
With a defmethod macro you are hiding the fact that you are effectively 
modifying method dispatch tables. With the setf macro you are hiding the 
fact that you are effectively identifying storage locations in RAM and 
change their contents.

Your setf example above has the same amout of information about its 
internal implementation as the C-style notation. The source code talks 
about an array, an element of that array, and a value to store in that 
array. It doesn't talk about a memory address, an offset to a base 
address, and so on.

Wrt to the notational issues: Lisp's grammar is so extremely simple 
because it is _always_ the first element in a parenthesized form that 
determines its meaning. The 'setf clearly tells you that you are now 
dealing with an assignment. The 'aref clearly tells you that you are now 
dealing with an array access. And so on. There is no fundamental way 
around this notational convention in Lisp. The C-style example is more 
complicated in that regard: Only the '= tells you that are dealing with 
an assignment, just after you have already needed to parse a few tokens. 
Likewise, only the '[ tells you that you are dealing with an array 
access (and in some languages not even that), after you have already 
read a token.

Such exceptional ad-hoc grammatical rules make it very hard to integrate 
macros into a language. In Lisp, we prefer the expressive power of 
macros that let us, for example, implement our own looping, method 
definition, and other similarly interesting language constructs without 
the need to wait for some more inflexible language to provide what we 
want. This is especially interesting for domain-oriented programming. 
Therefore, we are willing to pay the price that it's always the first 
element of a form that must indicate what the rest of the form means 
because that's a very little price to pay compared to the possibilities 
we have at our disposal in return.

If you really care about notational issues, you can use read macros to 
tweak such things. For example, it would be possible to turn the Lisp 
example into this:

(setf [a 12] 13)

...which is probably closer to what you prefer. However, on a larger 
scale, this is not really worth the fuzz.


Pascal
From: Thomas F. Burdick
Subject: Re: How powerful macros are?
Date: 
Message-ID: <xcvmzstbgca.fsf@conquest.OCF.Berkeley.EDU>
"V.Ch." <····@notreal.com> writes:

> Currently my knowledge of macros (and Lisp as a whole) is extremely 
> superficial, so forgive me if it's a silly question, but... Can I use 
> macros to make
> 
> (setf (aref a 12) 13)
> 
> look something more like
> 
> a[12] = 13?

No, you can't do this with macros because their combination of power
and ease of use comes from the fact that they operate on
s-expressions.  You could do what you're asking with reader macros, so
that reading something like the above would produce an s-expression.
It's pretty easy to do, and in fact newbies have been doing similar
things for decades, at least since the 60's.  And yet, these syntactic
extensions never catch on in any general sense.  Instead of jumping
back to what you're more familiar with, you might try pondering that,
and trying to use Lisp's syntax as it is until you get used to the
language, knowing that you can always change the syntax if you get to
like Lisp.  I suspect that in the end you won't want the sugary
syntax, but you could turn out to be one of those few that like mixing
s-expressions with ascii-fied algebraic syntax.

> I've started playing with List just few weeks ago. I think I got used to 
>   somewhat weired loops, branching, etc; but using arrays, and in 
> particular, assigning to arrays, seems clumsy enough to be a show-stopper.

But what's so special about arrays?  I know that the current style is
for software engineers to use arrays for everything, including things
for which they ought to be using lists or trees or some other data
structure, but this might just be a result of most languages making
arrays syntactically so much easier than anything else.  Arrays are
important building blocks, but you're supposed to use building blocks
to *build* things, at which point you're not dealing with the blocks
anymore, and you can't use the special syntax.  We Lispers recognize
that syntactic sugar won't scale, because there just aren't enough
funny characters to go around, at least not ones you can easily type
-- so instead of trying to fight a battle we're going to lose, and
ending out with a system with a weird combination of special syntax
for somethings, and function-call syntax for others, we just go from
the start with the syntax that scales.
From: Andrew P. Lentvorski, Jr.
Subject: Re: How powerful macros are?
Date: 
Message-ID: <1111661392.106569.115490@o13g2000cwo.googlegroups.com>
Thomas F. Burdick wrote:
> But what's so special about arrays?  I know that the current style is
> for software engineers to use arrays for everything, including things
> for which they ought to be using lists or trees or some other data
> structure, but this might just be a result of most languages making
> arrays syntactically so much easier than anything else.  Arrays are
> important building blocks, but you're supposed to use building blocks
> to *build* things, at which point you're not dealing with the blocks
> anymore, and you can't use the special syntax.

Two words: random access.

If I need a simple linear collection, there is no point to using a
list.  Slower element access and more memory--for what benefit?

If I need a "collection of stuff", I tend to reach for hashes.  I'd
rather access based on a key with semantic value for me rather than
position in list.

If I need a hierarchical data structure, I normally need something
stronger than a list--generally some form of a tree.

My personal opinion is that lists are just getting squeezed out by the
fact that Moore's Law has made reaching for an advanced data structure
a practical default choice.

I would actually like to see lisp teaching get away from the emphasis
on lists and recursion.  Closures, macros, and generic functions are
the things I pine for when stuck programming in other languages.

-a
From: Peter Seibel
Subject: Re: How powerful macros are?
Date: 
Message-ID: <m34qf0rhvr.fsf@gigamonkeys.com>
"Andrew P. Lentvorski, Jr." <·····@allcaps.org> writes:

> I would actually like to see lisp teaching get away from the
> emphasis on lists and recursion. Closures, macros, and generic
> functions are the things I pine for when stuck programming in other
> languages.

Hmmm. You should like my book[1] then. I don't talk about lists until
Chapter 12 (while I talk about arrays and hash tables in Chapter 11).
And I never really talk about recursion as a separate topic--I figure
most every language folks use these days supports recursion so it's
not a big deal.

I'd even go so for as to argue that the only reason lists (cons cells
actually) are really interesting in Lisp is beacuse we need a simple
data structure for representing heterogeneous trees so we can
represent source code as data so we can manipulate it with macros. Of
course once you've got cons cells, there are lots of other things the
turn out to be handy for such as prototyping before you've figured out
the "real" data structure you need.

-Peter

[1] <http://www.gigamonkeys.com/book/>
-- 
Peter Seibel                                     ·····@gigamonkeys.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Thomas F. Burdick
Subject: Re: How powerful macros are?
Date: 
Message-ID: <xcvis3aby99.fsf@conquest.OCF.Berkeley.EDU>
"Andrew P. Lentvorski, Jr." <·····@allcaps.org> writes:

> Thomas F. Burdick wrote:
> > But what's so special about arrays?  I know that the current style is
> > for software engineers to use arrays for everything, including things
> > for which they ought to be using lists or trees or some other data
> > structure, but this might just be a result of most languages making
> > arrays syntactically so much easier than anything else.  Arrays are
> > important building blocks, but you're supposed to use building blocks
> > to *build* things, at which point you're not dealing with the blocks
> > anymore, and you can't use the special syntax.
> 
> Two words: random access.

Did you actually read what you quoted?  I mean, past the first
sentance?  Linked lists, vectors, multi-dimensional arrays, hash
tables, and trees all have different properties.  You can force them
to play the role of each other, but it's never nice.  If you need
efficient random access, yes, you want vectors.  Or maybe some sort of
tree.  If you want shared tails, you can build something ugly out of
structures of vectors with pointers to the next tail ... or you could
just use lists.  If you read what I wrote, I'm not cheerleading lists,
I'm arguing for using the right data structure.
From: Kent M Pitman
Subject: Re: How powerful macros are?
Date: 
Message-ID: <u4qet3x3u.fsf@nhplace.com>
"Andrew P. Lentvorski, Jr." <·····@allcaps.org> writes:

> Thomas F. Burdick wrote:
> > But what's so special about arrays?  I know that the current style is
> > for software engineers to use arrays for everything, including things
> > for which they ought to be using lists or trees or some other data
> > structure, but this might just be a result of most languages making
> > arrays syntactically so much easier than anything else.  Arrays are
> > important building blocks, but you're supposed to use building blocks
> > to *build* things, at which point you're not dealing with the blocks
> > anymore, and you can't use the special syntax.
> 
> Two words: random access.

Did I miss something or is #(....) an impossibly unbearable syntax in Lisp?

> If I need a simple linear collection, there is no point to using a
> list.  Slower element access and more memory--for what benefit?

First, don't confuse algorithmic speed with practical speed.
Conses are fast, and arrays are often slower for very short lists.
O(1) can hide a lot of constant-speed sins.

For larger structures, sure, use an array.  The only thing Lisp shows a 
slight bias about is the use of lists to represent programs themselves.
When it comes to program data, though, I don't see any preference in Lisp
to use CONS/LIST/PUSH over any other function (e.g., VECTOR-PUSH-EXTEND)
unless you think the name is too long.  And we do provide DEFUN and
INLINE declarations for allowing you to make shorter names with no loss
of efficiency.

> If I need a "collection of stuff", I tend to reach for hashes.  I'd
> rather access based on a key with semantic value for me rather than
> position in list.

I do it a lot myself.  Are you saying Lisp doesn't provide this?

I've also extended the language so that I have re-readable hash tables
for cases where I need that.  Yes, that should be in the language, but at
least we have readmacros and print-object methods.  What other languages
that you're comparing us to have the ability to repair misdesigns in the
language under user control, especially without breaking other programs
that don't want those repairs.  (e.g., yes, you could modify the semantics
of an open-source alnguage, but then you affect all programs, not just your
own)
 
> If I need a hierarchical data structure, I normally need something
> stronger than a list--generally some form of a tree.

Does something you've read about Lisp by a competent programmer suggest
that we only use lists?  If so, please cite it.

> My personal opinion is that lists are just getting squeezed out by the
> fact that Moore's Law has made reaching for an advanced data structure
> a practical default choice.

Hmmm. Seems to me that list chains are still going to win big in
modern architectures under instruction fetch lookahead in ways that
some other data structures are going to make opaque.

You could, of course, make the case that Moore's law has allowed
people to simply not care about speed.  That's a harder case to
overcome.  Except it argues for people using whatever they want... It
doesn't argue for something being squeezed out.

It's true that Lisp programs themselves are lists, but that's rarely
an interesting issue because in all cases that really matter, the
computation to analyze anything related to program syntax is done at
compile time and is done and gone by the time your program is
executing for its intended use.  Further, even in an interpreted
situation, as if that really matters commercially, it's highly likely
that the arguments will be accessed in the order given by the lists,
such that lists are at least a defensible choice of data structure.

> I would actually like to see lisp teaching get away from the emphasis
> on lists and recursion.

We can't keep lisp teaching away from the emphasis on lists and
recursion exactly because (almost) no one uses Lisp to teach
conventional programming.  They take their pet child C or Java or C++
and show conventional programming they could be showing in Lisp, and
then when they get to something it's too painful to show in their
language, they come to us and show our features in a light that is
very non-representative of how normal lisp programming is done.  Then
they expect us to be grateful for the bad press they've given us by making
people think that we do all our data storage in lists.

> Closures, macros, and generic functions are
> the things I pine for when stuck programming in other languages.

People don't teach these things because they don't realize they're 
even there.  You have to get substantially farther into Lisp than
having had your grandfather read you The Little Lisper at bedtime
in the 1970's in order to know Lisp has these ... sigh.

I don't think the problem is correctly characterized as being a
problem of what is taught.  I think the problem is who is doing the
teaching.  To round numbers, I mean.  Surely there are some good Lisp
teachers out there.  But our worst enemy in some cases are those
"helpful" teachers that mention Lisp in a way that is not really helpful.

(Reminds me of the time someone I know called to say her church had
held an "authentic" Passover seder to help enlighten them about
Judaism...  "Except," she explained, as if almost embarrassed, "we
didn't slaughter any little animals."  I'm sure that was a BIG help
for her "understanding".)

Some kinds of "enlightenment" I think people can do without...
From: Raffael Cavallaro
Subject: Q: How powerful macros are? A: Very.
Date: 
Message-ID: <raffaelcavallaro-87AEBB.01261424032005@comcast.dca.giganews.com>
In article <············@gavrilo.mtu.ru>, "V.Ch." <····@notreal.com> 
wrote:

> Can I use 
> macros to make
> 
> (setf (aref a 12) 13)
> 
> look something more like
> 
> a[12] = 13?

This is available via the common lisp infix reader macro available at:
<http://www-cgi.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code
/syntax/infix/infix.cl>

example:
CL-USER 1 > (defvar infixarray (make-array '(4 4)))
INFIXARRAY

CL-USER 2 > infixarray
#2A((NIL NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL NIL 
NIL))

CL-USER 3 > #I(infixarray[2,2] = 3)
3

CL-USER 4 > infixarray
#2A((NIL NIL NIL NIL) (NIL NIL NIL NIL) (NIL NIL 3 NIL) (NIL NIL NIL 
NIL))

Array subscript notation is only one of the many capabilities of the 
infix reader macro. If you don't need a full infix syntax reader, you 
can get simple assignment of array elements by subscript via this 
straightforward macro (no error checking, but you'll get the idea - it's 
quite simple).

CL-USER 1 > (defvar test-array (make-array '(3 3)))
TEST-ARRAY

CL-USER 2 > test-array
#2A((NIL NIL NIL) (NIL NIL NIL) (NIL NIL NIL))

CL-USER 3 > (defmacro aset (array-name array-subscript value)
               `(setf (aref ,array-name ,@array-subscript) ,value))
ASET

CL-USER 4 > (aset test-array (1 1) 6)
6

CL-USER 5 > test-array
#2A((NIL NIL NIL) (NIL 6 NIL) (NIL NIL NIL))

Ralph
From: Förster vom Silberwald
Subject: Re: How powerful macros are?
Date: 
Message-ID: <1111656897.815988.308420@l41g2000cwc.googlegroups.com>
V.Ch. 	  Mar 23, 12:04 pm     wrote:

==
Currently my knowledge of macros (and Lisp as a whole) is extremely
superficial, so forgive me if it's a silly question, but... Can I use
macros to make

(setf (aref a 12) 13)

look something more like

a[12] = 13?

I've started playing with List just few weeks ago. I think I got used
to
  somewhat weired loops, branching, etc; but using arrays, and in
particular, assigning to arrays, seems clumsy enough to be a
show-stopper.
==

First let me say: yes Lisp is for you, though, Scheme would be better.

However, as a physicist who uses Scheme/Bigloo every day I can assure
you that the array indexing stuff is a non issue. I use the following
quite often (I think you can apply something similar in CommonLisp):

---
(define
   (a&::obj x::vector i::int j::int)
   (vector-ref (vector-ref x i) j))

(define
   (a!::obj x::vector i::int j::int el::obj)
   (vector-set! (vector-ref x i) j el))
----

referencing elements in an array:

(a& array i y)

setting elements in an array:

(a! array i j element)


Schneewittchen
From: Pascal Costanza
Subject: Re: How powerful macros are?
Date: 
Message-ID: <3afq5sF67lae2U1@individual.net>
F�rster vom Silberwald wrote:

> First let me say: yes Lisp is for you, though, Scheme would be better.

Hear hear.

> However, as a physicist who uses Scheme/Bigloo every day I can assure
> you that the array indexing stuff is a non issue. I use the following
> quite often (I think you can apply something similar in CommonLisp):
> 
> ---
> (define
>    (a&::obj x::vector i::int j::int)
>    (vector-ref (vector-ref x i) j))
> 
> (define
>    (a!::obj x::vector i::int j::int el::obj)
>    (vector-set! (vector-ref x i) j el))
> ----
> 
> referencing elements in an array:
> 
> (a& array i y)
> 
> setting elements in an array:
> 
> (a! array i j element)

Oh, you mean (aref array i j) and (setf (aref array i j) element) ?

Arrays in Common Lisp can be multidimensional. I mean, really 
multidimensional, not just arrays of arrays of arrays.

Now tell us again, why would Scheme be better in this regard? ;-P


Pascal
From: Förster vom Silberwald
Subject: Re: How powerful macros are?
Date: 
Message-ID: <1111750131.978848.165770@z14g2000cwz.googlegroups.com>
Pascal Costanza wrote:

> Oh, you mean (aref array i j) and (setf (aref array i j) element) ?
>
> Arrays in Common Lisp can be multidimensional. I mean, really
> multidimensional, not just arrays of arrays of arrays.
>
> Now tell us again, why would Scheme be better in this regard? ;-P

I haven't said that Scheme is better in that regard. How could I? My
Lisp knowledge tends to go towards zero. The only thing which my brain
can hold are some Scheme functions.

Personally, I haven't had problems with vectors of vector of vector of
vectors. I found it often comfortably because sometimes I had to cope
with arrays which stored arrays of different lengths. And upon creation
it was easy to have a list as array element first and have them
converted into a vector.

As far as I know there exists some srfi's for means of implementing
multidimensional arrays.

However, I never was in dire need of such genuine multi dimensional
arrays.

I am not sure whether multi dimensional arrays would be an argument pro
Lisp. Don't know.

Schneewittchen
From: Joe Marshall
Subject: Re: How powerful macros are?
Date: 
Message-ID: <is3hqccf.fsf@ccs.neu.edu>
"V.Ch." <····@notreal.com> writes:

> Currently my knowledge of macros (and Lisp as a whole) is extremely
> superficial, so forgive me if it's a silly question, but... Can I use
> macros to make
>
> (setf (aref a 12) 13)
>
> look something more like
>
> a[12] = 13?

You can persuade the Lisp reader to do this.  I wouldn't suggest it,
though.

> I've started playing with List just few weeks ago. I think I got used
> to somewhat weired loops, branching, etc; but using arrays, and in
> particular, assigning to arrays, seems clumsy enough to be a
> show-stopper.

The problem with putting an `infix' front-end on Lisp is that it won't
help you understand programs written by others and it will impede the
ability to share your code with others.  Suppose you go out and get
Vaughn Pratt's CGOL.  You're writing a Lisp program and it doesn't
work.  You could post it here, but if your code looks like this:

define "SIEVE" n,1;
array(sv,#fixnum,n/64+1);
sv(0):=1;		
let s=[1];		
for i in 3 to n/2 by 2 do
 if prime i then	 
  (let ts=nil;		
   for j in s do	
    (let k=j;		
     while k<n do	
       (if k not isin [1,i,j] then
	  (let kq = k:^:-6, kr = k:^:-1 :A: 31;
	   sv(kq):=sv(kq) :V: (1 :^: kr));	
	let m:=k*i;
	if m<n then ts:=k.ts;	
	k:=m));			
   s:=ts)$		

No one here will be able to help you.

You'll be doing yourself a big favor by sticking to the standard when
you start.
From: Alan Crowe
Subject: Re: How powerful macros are?
Date: 
Message-ID: <864qeza66m.fsf@cawtech.freeserve.co.uk>
V.Ch. inquired
> Can I use macros to make
>
> (setf (aref a 12) 13)
>
> look something more like
>
> a[12] = 13?

Well with read-macros you can do anything, which offers you
much less structure than is useful.

If you want to cut with the grain of the language, stick to
the ordinary macros that you define with defmacro. If you
refrain from passing them strings to parse (probably a wise
discipline) you are stuck with S-expressions.

One idea is to set things up so that you can omit the aref

(setf (a 12) 13)

the method is to supplement the variable `a' with functions `a'
and (setf a).

For example 

(defvar a (make-array '(2 3)))

(defun a (i j)
  (aref a i j))

(defun (setf a)(x i j)
  (setf (aref a i j) x))

Well, you would not want to type that little lot in over and
over again. Here is a macro:

(defmacro alet ((name dimensions &rest make-array-keyword-args)
		  &body code)
      `(let ((,name
	      (make-array ,dimensions
			  ,@make-array-keyword-args)))
	 (flet ((,name (&rest indices)
		       (apply (function aref)
			      ,name
			      indices))
		((setf ,name) (x &rest indices)
		 (setf (apply (function aref)
			      ,name
			      indices)
		       x)))
	       ,@code)))

Example 1
---------
(alet (m '(2 2 2))
  (dotimes (i 2)
    (dotimes (j 2)
      (dotimes (k 2)
        (setf (m i j k) (random 10)))))
  m)

=> #3A(((2 8) (9 0)) ((4 5) (6 0)))

Example 2
---------
(alet (m '(2 2) :initial-contents '((1 2)(3 4)))
	(format t "~&Trace = ~A"
		(loop for i below 2 sum (m i i))))

=> Trace = 5

So that is helping

(setf (m i j k) ...)

instead of 

(setf (aref m i j k) ...)

There is a huge problem with this, and it is none the
smaller for being hard to explain and sounding a bit feeble
when written down.

Huge Problem
------------
Computer scientists have been designing notations since the
mid-40's. At first they offered huge advantages. Going from
machine code (actual 1's and 0's) to assembler was huge.
Fortran, Lisp, and Algol offered substantial advantages over
assember in the 60's, but the returns had already started to
diminish, and pretty well collapsed there after.  What did
Pascal and C offer? Nothing like the old giant steps
forwards.

Designing fully general purpose notations is all played out.
The next step is to capture knowledge about your application
in your macroexpanders. 

What you want to avoid is having your attempts to wring the
last dregs out of general purpose notations get in the way
of moving on to the next step. So stick with S-expressions,
because they play nicely with defmacro. If you try to come
up with general purpose macros you will just go round in
circles. Common Lisp is already a good general purpose
language, you will not come up with fully general purpose
improvements.

Ask yourself instead what your application area is asking
you for. One question is "what idioms am I typing in over
and over?". A second question involves unlearning what you
have learnt in order to become an effective C programmer. In
C you have to think up ways of organising your code so that
you do not bog down in lots of repetitive typing. You need a
design in which common code lives in functions rather than
being typed in repeatedly, so you learn to bend your
thoughts to live within the limitations of functions.  In
CL, the macroexpanders will do your repetitive typing and
simple code transformations for you. To take advantage of
this you must unlearn your C habits.

Alan Crowe
Edinburgh
Scotland
From: tinyurl.com/uh3t
Subject: Re: How powerful macros are?
Date: 
Message-ID: <REM-2005mar28-001@Yahoo.Com>
> From: "V.Ch." <····@notreal.com>
> Can I use macros to make
(setf (aref a 12) 13)
look something more like
a[12] = 13?

Other people have responded by suggesting ways you can use reader
macros or string parsers to allow such a syntax in your source code to
auto-translate to the appropriate function call. But I'll address a
different issue.

> I've started playing with List [sic] just few weeks ago. I think I
> got used to somewhat weired [sic] loops, branching, etc;

I personally think C's way of doing if-then-else:
  if (test) thenclause;
  else elseclause;
where syntactically it looks like two independent statements, is
more clumsy than either of the following Lisp syntaxes:
  (if test  ;no extra level of parens needed
     thenclause
     elseclause)  ;obviously part of same expression
  (cond (test then1 then2 then3 ... thenvalue)
        (t else1 else2 ... elsevalue))
with the added value that in either case the same syntax can be used
for either a standalone statement or an expression that returns a
value. In C if you really want to have a conditional expression you
have to use the totally unscrutable syntax:
  test ? thenclause : elseclause;
How is Lisp's syntax worse than that??

> but using arrays, and in particular, assigning to arrays, seems
> clumsy enough to be a show-stopper.

If you consider that to be a "show-stopper", then you aren't using a
proper structured approach to organizing your software. You need to
think of using abstract data types (ADTs). You figure out some useful
data structure with associated functions, build a software module that
provides a public interface for building and operating upon that data
structure, then when you are writing the rest of your program you never
have to look at the innerds of that module, you merely make function
calls to the public interface functions. In software courses the
traditional ADTs are stack, queue, and some kind of balanced binary
tree such as AVL tree. Deep inside the ADT module you might build an
array and perform array indexing on it, but if you really really can't
deal with Lisp's array-access syntax even in that small part of your
program you can hire somebody else to write that small part for you.
All the rest of your program will then make function calls in any case.
But with function calls, Lisp syntax is the same as or better than C
syntax:
  C:    f();
  Lisp: (f)           ;One less character in this case
  C:    f(a,b,c);
  Lisp: (f a b c)     ;Same number of characters in other cases
And of course comments take less characters in Lisp too, single
semicolon instead of /* ... */ or //.

By the way, do you really like memorizing operator-precedence tables,
or adding extra unnecessary parentheses to overcome your failed memory?
In Lisp you just have to remember to match your parens, and be careful
about quote marks if you use string literals, no list of operators to
memorize. Also Lisp doesn't have any reserved words that affect parsing
your source-code syntax, so you don't have to worry about accidently
naming a local variable the same as a reserved word and getting totally
weird error messages due to totally screwed up parsing.

Anyway, I'm available, at reasonable rates, to write any ADTs you need,
if you really really have a mental block about using function-call
syntax to perform array access.
From: ···············@yahoo.com
Subject: Re: How powerful macros are?
Date: 
Message-ID: <1112216150.827216.60920@l41g2000cwc.googlegroups.com>
You've gotten lots of long and serious answers, but you should also get
a quickie, assuming a is one-dimensional.

(defmacro aset (array index value)
  `(setf (aref ,array ,index) ,value))

(aset a 12 13) ;; is what you want

See also vom Silberwald's answer
From: Pascal Bourguignon
Subject: Re: How powerful macros are?
Date: 
Message-ID: <877jjosv8a.fsf@thalassa.informatimago.com>
···············@yahoo.com writes:

> You've gotten lots of long and serious answers, but you should also get
> a quickie, assuming a is one-dimensional.
> 
> (defmacro aset (array index value)
>   `(setf (aref ,array ,index) ,value))
> 
> (aset a 12 13) ;; is what you want
> 
> See also vom Silberwald's answer

With:

(defmacro aset (array &rest ixes&v)
   `(setf (aref ,array ,@(butlast ixes&v)) ,(car (last ixes&v))))

you can even set multidimentional arrays:

[12]> (let ((a (make-array '(3 3 3) :initial-element 0)))
    (aset a 1 0 2   1)
    a)

#3A(((0 0 0) (0 0 0) (0 0 0))
    ((0 0 1) (0 0 0) (0 0 0))
    ((0 0 0) (0 0 0) (0 0 0)))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

This is a signature virus.  Add me to your signature and help me to live
From: ···············@yahoo.com
Subject: Re: How powerful macros are?
Date: 
Message-ID: <1112283995.672110.15220@g14g2000cwa.googlegroups.com>
Beautiful!
From: Kent M Pitman
Subject: Re: How powerful macros are?
Date: 
Message-ID: <u8y453yh3.fsf@nhplace.com>
"V.Ch." <····@notreal.com> writes:

> Currently my knowledge of macros (and Lisp as a whole) is extremely
> superficial, so forgive me if it's a silly question, but... Can I use
> macros to make
> 
> (setf (aref a 12) 13)
> 
> look something more like
> 
> a[12] = 13?
> 
> I've started playing with List just few weeks ago. I think I got used
> to somewhat weired loops, branching, etc; but using arrays, and in
> particular, assigning to arrays, seems clumsy enough to be a
> show-stopper.

You are confused even in the terminology you use to express your desire.
Let me try to sort some of this out...

First, Lisp is not about how something looks.  You can use Lisp (or,
incidentally, any "Turing equivalent" language connected to a display
system) to make something look any way you want.  e.g.,

(defun show-form (x)
  (cond ((atom x) (prin1 x))
        (t (show-compound-form (car x) x))))

(defmethod show-compound-form (op form)
  (write-char #\()
  (show-function (car form))
  (dolist (arg (cdr form))
    (write-char #\Space)
    (show-form arg))
  (write-char #\)))

(defmethod show-compound-form ((op (eql 'aref)) form)
  (show-form (cadr form))
  (write-char #\[)
  (loop for (arg . more) on (cddr form)
        do (show-form arg)
           (when more (write-char #\,)))
  (write-char #\]))

(defmethod show-compound-form ((op (eql 'setf)) form)
  (loop for (place exp . more) on (cdr form) by #'cddr 
        do (show-form place)
           (write-char #\=)
           (show-form exp)
           (when more (terpri))))

(defun show-function (op) (prin1 op)) ;oversimplification 

Having done the above, you can do:

 (show-form '(setf (aref a 12) 13))

to see

 a[12]=13

if that's what you like.  But just because you can make it "look" that way
does not mean you have done the work needed to make it "parse" that way.
You cannot ever modify the look of a language like Lisp, that has the 
ability to print and re-read data, without changing BOTH a parser
and a printer.

Internally, no matter whether you start with (SETF (AREF A 12) 13)
or a[12]=13, the important part is that you have to write the reader
support to make it happen.  You want to be reading about readmacros,
not macros, for that.  Readmacros are responsible for taking input text
(pre-parsed) and converting it to structure such as the language will see.

Some reasons Lisp people don't like this is because

 (a) infix parsers/printers are a pain to write;
     that is, figuring out that (+ a (* b c)) can be
     printed as a+b*c but that  (* a (+ b c)) has to be
     printed as a*(b+c) is non-trivial

 (b) it obscures structure; that is, figuring out how many
     subforms are in a+b*c*d+e is troublesome because it's 
     definitional, not canonical.  That is, it might be
     (+ a (* b c d) e) or (+ a (+ (* b (* c d)) e)) or
     (+ a (+ (* b c d) e)) or (+ (+ a (* b c d)) e) or ...
     whereas the Lisp syntax natively makes this clear.

     If you're routinely writing programs to traverse others'
     programs, this kind of thing matters.

Internally, definitionally, Lisp is defined in terms of conses.  
What it means to be a function call is not f(x) nor (f x) but

  --Cons--> +---+              +---------+
            |Car-----Symbol--->| Package ----Package--> #<PACKAGE CL-USER>
            +---+              +---------+                    ^
            |Cdr---+           | Name -------String--> "F"    |
            +---+  |           +---------+                    |
                   |                                        Package
                   +--Cons-->+---+           +---------+      |
                             |Car---Symbol-->| Package -------+
                             +---+           +---------+
                             |Cdr---+        | Name  -----String--> "X"  
                             +---+  |        +---------+
                                    |
                                  Symbol
                                    |            +---------+
                                    +----------->| Package -----> #<PACKAGE CL>
                                                 +---------+
                                                 | Name --------> "NIL"
                                                 +---------+
                                                 | Value -----+
                                                 +---------+  |
                                                     ^        |
                                                     |      Symbol
                                                     +--------+

That is, Lisp is defined in terms of structure, not text.

There are packages for Lisp that have come and gone over time implementing
various degrees of infix notation.  e.g., CGOL (in a dialect of Lisp
older that CL) made every single character a readmacro and then used its
own parser and its own printer, but had all of Lisp's computational semantics.
Mostly, though, people who give Lisp's syntax a chance find that it's simpler
and clearer and easier to work with than the alegbraic notations in most
programming situations.  Certainly, if you're writing a program to communicate
with mathemeticians, you might prefer their customary notation just as any
program prefers domain notation to internal representation for talking to
users.  But most users of computers are not mathemeticians, so most of the
time it hardly matters.