From: Bjoern Petri
Subject: Another simple thing from me
Date: 
Message-ID: <031ce3f27d4e36eb042bf33360e74c96.44739@mygate.mailgate.org>
Hello,

Hmm, LISP is quite different! But I got first success. Now an new question (i
hope it is okay, but i've
really searched enough - hmm, perhaps i'm searching the wrong way).

Okay, here it is:

i'm creating a function which will compare two textfiles. After loading the two
textfiles, i want to
read one of the texfiles (line for line) in an array. But i don't really know
what's better: an one-dimensional array
or an sequence. Whats the difference between these types? Do I have to define
the size at the creation (Array/Sequence)
or can I create one and add and add and add...

Kind regards,
Bjoern

PS: i think my LISP and my English is getting better and better.



-- 
Posted from  [213.69.137.215] 
via Mailgate.ORG Server - http://www.Mailgate.ORG
From: Kent M Pitman
Subject: Re: Another simple thing from me
Date: 
Message-ID: <sfw7krkwmyi.fsf@shell01.TheWorld.com>
"Bjoern Petri" <········@gmx.de> writes:

> i'm creating a function which will compare two textfiles. After
> loading the two textfiles, i want to read one of the texfiles (line
> for line) in an array. But i don't really know what's better: an
> one-dimensional array or an sequence.

A sequence is an abstract type.  In concrete form, it is either a list
or it is an array (where a 1d array is called a vector).  You can't
instantiate a sequence per se, so this is not a choice.

> Whats the difference between these types?

Mostly the 'algorithmic complexity" of the operations on them.
If you need random access, use an array.  If you plan to do linear access,
you can use a list.  The nice thing about a list is that you don't have to
know in advance how long it will be as you're building it.  With an array,
you can make an initial guess, and Lisp will help you if you overrun, but
there may be a time where Lisp has to discard the storage it had and go for
more storage.  

Consider:

(with-open-file (stream "myfile.text")
  (loop for line = (read-line stream nil nil)
        while line
        collect line))

the above makes a list of lines out of the file but hides how.  To see
it more explicitly, try:

(with-open-file (stream "myfile.text")
  (let ((lines '()))
    (loop for line = (read-line stream nil nil)
          while line
          do (push line lines))  ;i.e., (setq lines (cons line lines))
    ;; The above loop will create the list of lines backward,
    ;; so the result must be reversed when you're done.  NREVERSE
    ;; will recycle the same list cell storage to make the reversed copy.
    (nreverse lines)))

Compare this to the following, which coincidentally doesn't need reversing
since arrays are pushed onto at the end instead of the beginning:

(with-open-file (stream "myfile.text")
  (let ((lines (make-array 100 ;initial size of 100 (i.e., room to grow)
	                   :fill-pointer 0 ;but pretend it's empty
                           :adjustable t))) ;extend automatically on overrun
    (loop for line = (read-line stream nil nil)
          while line
          do (vector-push-extend line lines)) ;add elt, extend if needed
    ;; Here we can just return the list directly.
    lines))

> Do I have to define the size at the creation
> (Array/Sequence) or can I create one and add and add and add...

You make a plausible guess and then you build in protection against having
made a mistake.  An adjustable array will be extended automatically by
VECTOR-PUSH-EXTEND if need be. (Don't ever use just VECTOR-PUSH unless you're
_really_ sure you know what you are doing; it's not protected as well.)