From: Lieven Marchand
Subject: arrays as literal objects
Date: 
Message-ID: <m31yl8tves.fsf@localhost.localdomain>
Can arrays constructed by the sharpsign A syntax be considered as
literal objects which the file compiler can coalesce?

Given the specification of #A to call MAKE-ARRAY I would have thought
not but Lispworks/Linux 4.1.20 does it.

The following function when put in a file, compiled and loaded will
return T.

(defun test-1 ()
  (let (a b)
    (setf a #1A(0 1 2 3))
    (setf b #1A(0 1 2 3))
    (eq a b)))

Weirdly enough, the following 

(defun test-2 ()
  (let ((a #1A(0 1 2 3))
        (b #1A(0 1 2 3)))
    (eq a b)))

returns NIL.

In any case, I think this is a very surprising behaviour that should
be considered a bug.

-- 
Lieven Marchand <···@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words

From: Kent M Pitman
Subject: Re: arrays as literal objects
Date: 
Message-ID: <sfwheu4gryy.fsf@world.std.com>
Lieven Marchand <···@wyrd.be> writes:

> Can arrays constructed by the sharpsign A syntax be considered as
> literal objects which the file compiler can coalesce?
 
It sure looks to me like there's little room for ambiguity on this.

From the glossary:

| literal adj. (of an object) referenced directly in a program rather than
|  being computed by the program; that is, appearing as data in a quote form,
|  or, if the object is a self-evaluating object, appearing as unquoted data.
|  ``In the form (cons "one" '("two")), the expressions "one", ("two"), 
|    and "two" are literal objects.'' 

> Given the specification of #A to call MAKE-ARRAY I would have thought
> not but Lispworks/Linux 4.1.20 does it.

But it calls MAKE-ARRAY at >* read *< time, not at semantics-application
time.  No information about how the array got there is left over by the time
evaluation semantics are applied.

Semantics application is not based on the reader syntax you use, since in
fact some objects that are compiled were never even typed in and HAVE no
read syntax.  This includes not only results of GENSYM but even any forms
that are constructed using cons, list, etc., using backquote, using 
MAKE-SYMBOL or INTERN, using math operators like +, -, *, etc. that might
construct literal constants for inclusion, etc.

It's the type of the object that's relevant.  For example, see:

| 3.1.2.1 Form Evaluation
|
| Forms fall into three categories: symbols, conses, 
| and self-evaluating objects. 
 
> The following function when put in a file, compiled and loaded will
> return T.
> 
> (defun test-1 ()
>   (let (a b)
>     (setf a #1A(0 1 2 3))
>     (setf b #1A(0 1 2 3))
>     (eq a b)))
> 
> Weirdly enough, the following 
> 
> (defun test-2 ()
>   (let ((a #1A(0 1 2 3))
>         (b #1A(0 1 2 3)))
>     (eq a b)))
> 
> returns NIL.
> 
> In any case, I think this is a very surprising behaviour that should
> be considered a bug.

I don't think so.  I hope I've explained why to your satisfaction.

To get the behavior you appear to want, I recommend you use
(load-time-value (make-array ...)).

Also, of related interest:

| 3.1.2.1.3 Self-Evaluating Objects
|
| ...
| The consequences are undefined if literal objects (including
| self-evaluating objects) are destructively modified.
From: Lieven Marchand
Subject: Re: arrays as literal objects
Date: 
Message-ID: <m3wv2xy6ob.fsf@localhost.localdomain>
Kent M Pitman <······@world.std.com> writes:

> Semantics application is not based on the reader syntax you use, since in
> fact some objects that are compiled were never even typed in and HAVE no
> read syntax.  This includes not only results of GENSYM but even any forms
> that are constructed using cons, list, etc., using backquote, using 
> MAKE-SYMBOL or INTERN, using math operators like +, -, *, etc. that might
> construct literal constants for inclusion, etc.
> 
> It's the type of the object that's relevant.  For example, see:
> 
> | 3.1.2.1 Form Evaluation
> |
> | Forms fall into three categories: symbols, conses, 
> | and self-evaluating objects. 

I'd missed that. Somehow, I'd convinced myself that only things like
strings and integers were self-evaluating and things that were
constructed with reader macros weren't.

> I don't think so.  I hope I've explained why to your satisfaction.

Yes. Thanks a lot.

> To get the behavior you appear to want, I recommend you use
> (load-time-value (make-array ...)).

I just wanted to initialize a variable with an array that I'll modify
later on. What is the advantage of load-time-value above just calling
make-array, especially if it's important that the variable is
initialized that way everytime the function is called?

-- 
Lieven Marchand <···@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words
From: Barry Margolin
Subject: Re: arrays as literal objects
Date: 
Message-ID: <ePsp7.18$0s2.3834@burlma1-snr2>
In article <··············@localhost.localdomain>,
Lieven Marchand  <···@wyrd.be> wrote:
>Kent M Pitman <······@world.std.com> writes:
>
>> Semantics application is not based on the reader syntax you use, since in
>> fact some objects that are compiled were never even typed in and HAVE no
>> read syntax.  This includes not only results of GENSYM but even any forms
>> that are constructed using cons, list, etc., using backquote, using 
>> MAKE-SYMBOL or INTERN, using math operators like +, -, *, etc. that might
>> construct literal constants for inclusion, etc.
>> 
>> It's the type of the object that's relevant.  For example, see:
>> 
>> | 3.1.2.1 Form Evaluation
>> |
>> | Forms fall into three categories: symbols, conses, 
>> | and self-evaluating objects. 
>
>I'd missed that. Somehow, I'd convinced myself that only things like
>strings and integers were self-evaluating and things that were
>constructed with reader macros weren't.

Being self-evaluating is dependent on the type, not the reader (after all,
EVAL has no way of knowing whether a reader-macro was used -- BTW,
doublequote is often a reader macro).  The original CLTL was less specific
about which types of objects are self-evaluating.  Numbers and strings were
required to be self-evaluating, but everything else was
implementation-dependent.  X3J13 decided to make all standard objects other
than symbols and conses self-evaluating, as no implementations had taken
advantage of the opportunity to implement other evaluation models for any
of these types.

>> I don't think so.  I hope I've explained why to your satisfaction.
>
>Yes. Thanks a lot.
>
>> To get the behavior you appear to want, I recommend you use
>> (load-time-value (make-array ...)).
>
>I just wanted to initialize a variable with an array that I'll modify
>later on. What is the advantage of load-time-value above just calling
>make-array, especially if it's important that the variable is
>initialized that way everytime the function is called?

If you use MAKE-ARRAY, it will create a new array every time the function
is called.  If you use LOAD-TIME-VALUE, a value will be computed at the
time the file is loaded, and the variable will be initialized with that
same value each time the function is called.  It would be similar to:

(defparameter *initial-value* (make-array ...))

(defun ...
  (let ((variable *initial-value*))
    ...))

Using this technique or LOAD-TIME-VALUE, then the variable will "remember"
the modifications you made during the last call.  If you don't want this
memory, call MAKE-ARRAY when binding the variable.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: arrays as literal objects
Date: 
Message-ID: <sfw1yl5ihqc.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> In article <··············@localhost.localdomain>,
> Lieven Marchand  <···@wyrd.be> wrote:
> >Kent M Pitman <······@world.std.com> writes:
> ...
> >> To get the behavior you appear to want, I recommend you use
> >> (load-time-value (make-array ...)).
> >
> >I just wanted to initialize a variable with an array that I'll modify
> >later on. What is the advantage of load-time-value above just calling
> >make-array, especially if it's important that the variable is
> >initialized that way everytime the function is called?
> 
> If you use MAKE-ARRAY, it will create a new array every time the function
> is called.  If you use LOAD-TIME-VALUE, a value will be computed at the
> time the file is loaded, and the variable will be initialized with that
> same value each time the function is called.  It would be similar to:
> 
> (defparameter *initial-value* (make-array ...))
> 
> (defun ...
>   (let ((variable *initial-value*))
>     ...))
> 
> Using this technique or LOAD-TIME-VALUE, then the variable will "remember"
> the modifications you made during the last call.  If you don't want this
> memory, call MAKE-ARRAY when binding the variable.

If it helps any old-timers out there, LOAD-TIME-VALUE gives you the power
to get an effect like "own variables" in Algol.  Maybe modern languages have
this too with some more catchy name...
From: Janis Dzerins
Subject: Re: arrays as literal objects
Date: 
Message-ID: <87sndkev4n.fsf@asaka.latnet.lv>
Kent M Pitman <······@world.std.com> writes:

> Barry Margolin <······@genuity.net> writes:

> > Using this technique or LOAD-TIME-VALUE, then the variable will "remember"
> > the modifications you made during the last call.  If you don't want this
> > memory, call MAKE-ARRAY when binding the variable.
> 
> If it helps any old-timers out there, LOAD-TIME-VALUE gives you the power
> to get an effect like "own variables" in Algol.  Maybe modern languages have
> this too with some more catchy name...

Static variables, in C (and C++).

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Pekka P. Pirinen
Subject: Re: arrays as literal objects
Date: 
Message-ID: <ur8t5bqk4.fsf@globalgraphics.com>
Lieven Marchand <···@wyrd.be> writes:
> Can arrays constructed by the sharpsign A syntax be considered as
> literal objects which the file compiler can coalesce?

Yes.  As Kent explains, they are literals, and ANS 3.2.4.4 explicitly
specifies which literals may be coalesced: those that are similar.
Similarity is defined on array. so it can happen.

> Weirdly enough, the following 
> 
> (defun test-2 ()
>   (let ((a #1A(0 1 2 3))
>         (b #1A(0 1 2 3)))
>     (eq a b)))
> 
> returns NIL.

That's also legal, since there's no obligation to coalesce, but it is
curious.  The explanation is that the call to EQ gets constant-folded,
as the compiler has substituted the values of A and B for the
variables.  In the other example, it doesn't try that, since the
variables have two different values in the scope, due to SETF.
Constant folding is done by a calling EVAL during compilation, at
which point we still have two separate arrays, so the result is NIL.
-- 
Pekka P. Pirinen, Global Graphics Software
Pick your enemies carefully.  They're harder to get rid of than friends.