newLISP Fan Club

Forum => newLISP in the real world => Topic started by: dave_f on January 07, 2008, 06:53:06 PM

Title: can't push into a list in an array ?
Post by: dave_f on January 07, 2008, 06:53:06 PM
First, I made an array of five empty lists.  Then I tried to add an element to one of the lists in the array, using push.  It didn't work, and I would like to understand why not.  Here's the story:



> (set 'A-of-L (array 5 '(()) ))

(() () () () ())

> (push 'a  (A-of-L 2))

a

> A-of-L

(() () () () ())

> (A-of-L 2)

()



Sorry if this is clueless-newbie question!



thanks,



dave_f



newLISP 9.2.12

Mac OS 10.4.11

Intel iMac
Title: Re: can't push into a list in an array ?
Post by: Cyril on January 07, 2008, 07:53:56 PM
Quote from: "dave_f"First, I made an array of five empty lists.  Then I tried to add an element to one of the lists in the array, using push.  It didn't work, and I would like to understand why not.


Because newLISP, unlike other lisp's (Common Lisp, Scheme) and unlike most of the dynamic languages (Python, Ruby) does copying values, not references. '(A-of-L 2)' returns not the "same" empty list that is hold by an array, but a fresh copy of empty list. 'push' modifies this fresh copy and then loses it. If you want to modify a list buried deeply in nested list structure, you can use additional indices as arguments to 'push' (or other destructive functions), but if list is nested into array -- I believe there are no way to do it. Can anyone disprove this?
Title:
Post by: Cyril on January 07, 2008, 08:09:31 PM
BTW, here is question to community and to Lutz especially: is the current approach of nested indexing of mixed array and list structures good enough? If someone have a nested list, he can index it as (mylist 2 3 4), for a multidimensional array (myarray 2 3 4) works also, but for an array nested into list and vice versa this fails. And, the worse of all, it doesn't even signal an error, superfluous indices are just dropped. I believe that not signaling errors is a bad practice. Changing the out-of-range index behavior in 9.2.12 (not tested yet, just read announce) is a good step, can we (and shall we) continue in this direction?



To be clear: there is two different and independent suggestions: (1) to allow mixed list and array structures be transparently indexed (2) to signal superfluous indices as an error. They may be considered independedly.
Title:
Post by: Lutz on January 08, 2008, 05:33:49 AM
Quoteallow mixed list and array structures be transparently indexed


This could lead to ambiguous situations. But when this is the intention, do: ((array 1 2) 3) or (nth 3 (array 1 2))


Quotesignal superfluous indices as an error


Perhaps ... not sure on this one. Personally when working with nested lists, I prefer the current behavior of dropping superfluous indices.



Lutz
Title:
Post by: cormullion on January 08, 2008, 10:28:25 AM
Dave, try nth-set to set the value of the cell of the array:


(nth-set (A-of-L 2) 23)

If you do this:


(set 'A-of-L (array 5 (map char (sequence 65 70))))

followed by this:


(A-of-L  2)

you're going to get a string:


"C"

Then after this:


(push "23" (A-of-L 2) -1)

you've pushed "23" to the end of "C", then thrown the result - "C23" away.



push returns only the inserted element, so it's not quite what you want.



To add something to the end of an array element, you could use something like this:


(nth-set (A-of-L 2) (append (A-of-L 2) "suffix"))

Personally I avoid using arrays as far as possible; I don't need the speed advantage, and I think that they're slightly less versatile. With lists, you know you're on safe ground with newLISP, and most of the really cool features work on lists but not always on arrays (although Lutz likes to narrow the gap sometimes)



In fact, when I was doing some maze drawing stuff, I used this code:


(set  'height 40
        'width 40
        'wall-length 20
        'maze (array-list (array height width '("ensw"))))


which looks as if I'm using arrays purely for the cool initialization... :)
Title:
Post by: Cyril on January 08, 2008, 10:19:14 PM
Quote from: "Lutz"But when this is the intention, do: ((array 1 2) 3) or (nth 3 (array 1 2))


No problem while accessing a deeply nesting structure. Hard problem when trying to modify it. In more traditional languages, accessor yields a reference to inner structure (array or list or something), and you can modify it as you like. In newLISP there are no references (at least, no ubiquitous references), and the task of modifying a deeply nested structure is solved by lists of indices. This work consistent with all operations on nested lists and/or nested arrays (thanks, Lutz!), but it fails on mixed array/list structures. Such a beasts became in fact immutable (you can only take an inner thing in whole and replace it with modified version, but not modify one element of it). This seems illogical and inconvenient for me.
Title:
Post by: cormullion on January 09, 2008, 10:35:09 AM
I'm still unsure about arrays - but I've never thought of using mixed array/list structures. As you say, they must be beasts - but isn't the only reason to use arrays one of speed - and are mixed array/list structures any faster than standard lists?



I have only limited applications for newLISP - text processing, blogging engine, etc - so can't imagine the benefits of using an array/list structure...



I believe you can pass lists by reference - never done that either, though±