On 05/03/2017 08:49 AM, oldk1331 wrote:
>> Oh, maybe I didn't express myself well enough. The line
>>
>>   map(f, l) == map!(f, copy l)
>>
>> is an implementation detail. It's a good default, but if the context
>> (speed or violation of some conventions) give rise to another
>> implementation that doesn't build on map!, then one should consider
>> reimplementing map inside the respective domain %.
> 
> Yes, you are right.  That's implementation detail.
> 'map' doesn't have to depend on 'copy' at all, basicly:
>     map(f, l) == cons(f first l, map(f, rest l))
> (then rewrite to avoids recursion)
> 
> So about 'copy', from Aggregate:
>    copy : % -> %
>      ++ copy(u) returns a top-level (non-recursive) copy of u.
> 
> What does that mean for AssociationListAggregate?
> 
> If 'map' doesn't use 'copy', then 'copy' of AssociationListAggregate
> 'returns a top-level (non-recursive) copy' seems fine to me.
> This 'copy' is good enough for non-destructive usage.

Oh, well... I never looked up the specification of copy in Aggregate.
Shame on me!

But now, thinking about that specification, I don't think it makes
sense. Aggregate is a category. What does "top-level" copy actually
mean? Suppose I implement List2 that behaves like List, but uses as
implementation Rep ==> List List S. Now I could have in List2

  construct [1,2,3]

be represented as [[1,2,3]] or as [[1],[2],[3]]. Which one List2 chooses
is an implementation detail hidden to the user.
If copy copies the toplevel, i.e., copy in List2 is defined as

Rep ==> List List T
copy(x: %): % == per copy rep x

then setelt! if not appropriately adapted would change the original
element. I.e., if setelt! is defined like

  setelt!(x: %, i: NNI, t: T): T == setelt!(first rep x, i, t)

for the representation that just puts another list layer around the list or

  setelt!(x: %, i: NNI, t: T): T == rep(x).i.1 := t

for the second case.

Admittedly, that is a stupid construction, but who says what top-level
is? My copy from List2 does follow the specification, but if there is
*no relation documentet in the specification* of copy and other
destructive functions, the "top-level" information is just not enough
for the programmer to exactly predict what will happen if a destructive
function is applied. I refuse to tell the programmer to look into the
source code. A programmer should not be bothered with implementation
details of a library (which might change in a future release of the
library). Note that you (Qian) want to change the representation of
ALIST from Reference List X to List X.

I simply want a clearly documented interface.

> On the other hand, 'ALAGG has Dictionary', and in Dictionary:
> ++ This category models the usual notion of dictionary which involves
> ++ large amounts of data where copying is impractical.
> ++ Principal operations are thus destructive (non-copying) ones.

I haven't deeply looked into that issue, but it sounds like ALIST should
not be a Dictionary then. That's probably also a questionable
decision.

> BTW, 'copy' of Record seems wrong:
> 
> (1) -> T ==> Record(a:List Integer)
>                                                                    Type: Void
> (2) -> x : T := [[1]]
> 
>    (2)  [a = [1]]
>                                                Type: Record(a: List(Integer))
> (3) -> y := copy x
> 
>    (3)  [a = [1]]
>                                                Type: Record(a: List(Integer))
> (4) -> x.a.1 := 2
> 
>    (4)  2
>                                                         Type: PositiveInteger
> (5) -> x
> 
>    (5)  [a = [2]]
>                                                Type: Record(a: List(Integer))
> (6) -> y
> 
>    (6)  [a = [2]]
>                                                Type: Record(a: List(Integer))

No, I don't agree. First of all, Record is not a library-defined domain,
so I don't know of a specification of copy$Record(..).
Second, x contains a pointer to a list "a" of integers. y:=copy x means
that y is now a copy of that pointer to the *same* list "a" of integers.

  x.a.1 := 2

is the same as saying

  u := x.a
  u.1 := 2

so the destructive operation happens at List(Integer) not at
Record(a:List(Integer)), so it is one level deeper and thus, one cannot
blame Record at all.

And copy$Record seems to work OK for top-level modifications.

Ralf

(1) -> R==>Record(a:List INT)
                                                                   Type:
Void
(2) -> x:R := [[1]]

   (2)  [a = [1]]
                                               Type: Record(a:
List(Integer))
(3) -> y := copy x

   (3)  [a = [1]]
                                               Type: Record(a:
List(Integer))
(4) -> x.a := [4]

   (4)  [4]
                                                          Type:
List(Integer)
(5) -> x

   (5)  [a = [4]]
                                               Type: Record(a:
List(Integer))
(6) -> y

   (6)  [a = [1]]
                                               Type: Record(a:
List(Integer))

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/fricas-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to