From: Andreas Thiele
Subject: dynamic array?
Date: 
Message-ID: <cmnfdl$7il$03$1@news.t-online.com>
Hi,

I need a sort of two dimensional dynamic array which I can think of in terms
of rows and columns. Columns should have certain attributes like :name or
:hidden. Rows should be easily accessible and modifyable. Well I wrote it
myself and called it snapshot. Although it works fine and already is a
version 2 I still find it a somehow clumsy. I feel I can't see the forrest
for the trees regarding simplicity.

You might review my code for that beast (with two real life examples
attached) at

www.atp-media.de/devel/snapshot.lsp

Any suggestions or hints where I can find something similar or how I can
improve the code are very appreciated.


Thanks

Andreas

From: Jeff M.
Subject: Re: dynamic array?
Date: 
Message-ID: <1099924382.946269.246520@f14g2000cwb.googlegroups.com>
Sounds to me like some kind of database table (of sorts), where you
want to be able to modify column values and sort by column values. If I
were to implement something like this, I'd probable use a list for all
the rows, and each row would be a hash-table, where each key was a
column symbol.

Using the above, sorting becomes no more difficult than using the SORT
function, where the compare function just compares particular keys'
values. You could also create a COLUMN macro that returns a GETHASH, so
it is settable.

That may be a bit simplistic for what you are trying to accomplish,
though. It would require keeping track of the "type" of each column and
writing a compare function for each type to send to SORT. It also might
not be as fast, but I see it being extremely flexible.

I typed up a quick example at:
http://www.retrobyte.org/lisp/table.lisp

Jeff M.
From: Andreas Thiele
Subject: Re: dynamic array?
Date: 
Message-ID: <cmshn9$ctg$02$1@news.t-online.com>
"Jeff M." <·······@gmail.com> schrieb im Newsbeitrag
·····························@f14g2000cwb.googlegroups.com...
> Sounds to me like some kind of database table (of sorts), where you
> want to be able to modify column values and sort by column values. If I
> were to implement something like this, I'd probable use a list for all
> the rows, and each row would be a hash-table, where each key was a
> column symbol.
>
> Using the above, sorting becomes no more difficult than using the SORT
> function, where the compare function just compares particular keys'
> values. You could also create a COLUMN macro that returns a GETHASH, so
> it is settable.
>
> That may be a bit simplistic for what you are trying to accomplish,
> though. It would require keeping track of the "type" of each column and
> writing a compare function for each type to send to SORT. It also might
> not be as fast, but I see it being extremely flexible.
>
> I typed up a quick example at:
> http://www.retrobyte.org/lisp/table.lisp
>
> Jeff M.
>

Hi Jeff,

thanks for your hint. Indeed this "snapshot" should be something like an
ADORecordset. It will mostly work on database results but not only. Yet I
did not consider sorting. I thought it will mostly be done by the database.
Because I want to put arbitrary rows in my snapshot, sorting indeed is an
issue.

Sometimes speaking things out helps. I did not explain my problem clearly.
The snapshot contains a 'row-pointer' so it has a current row. This is what
I called imperative interface. It is the method

(defmethod field ((snapshot snapshot) id)
  "return the named field from current row where id might be either a column
name or number"
... )

which together with a macro for-each-row allows code like:

(for-each-row (snapshot)
  ;; getting a 'field'
  (setf x (field snapshot "Name"))
  ;; or setting a 'field'
  (setf (field snapshot "Name") y))
  )

The unpleasant thing has been what I called the functional interface

(defmethod row-field ((snapshot snapshot) row id) ... )

I had to supply both the snapshot and a row, which is redundant information
and leads to a nonunique interface, because there are two methods field and
row-field.

Just after posting I thought about this further explanation. My easy answer
to my own question is: each row must contain a reference to the snapshot and
should be of class 'row. In this case I can replace method row-field by

(defmethod field ((row row) id) ... )

which is consistent with the first method 'field' and allows functional
access with minimal writing.

Well, your post still helped me, because it started discussion on sorting.


Thanks

Andreas
From: Peter Seibel
Subject: Re: dynamic array?
Date: 
Message-ID: <m3sm7kfecv.fsf@javamonkey.com>
"Andreas Thiele" <··········@nospam.com> writes:

> Hi,
>
> I need a sort of two dimensional dynamic array which I can think of in terms
> of rows and columns. Columns should have certain attributes like :name or
> :hidden. Rows should be easily accessible and modifyable. Well I wrote it
> myself and called it snapshot. Although it works fine and already is a
> version 2 I still find it a somehow clumsy. I feel I can't see the forrest
> for the trees regarding simplicity.
>
> You might review my code for that beast (with two real life examples
> attached) at
>
> www.atp-media.de/devel/snapshot.lsp
>
> Any suggestions or hints where I can find something similar or how I can
> improve the code are very appreciated.

I just took a quick look at this but it looks similar enough to
something that I wrote for my book that you might find my take on the
same problem interesting. A draft of the relevant chapter is at:

  <http://www.gigamonkeys.com/book/practical-an-mp3-database.html>

And it gets used in:

  <http://www.gigamonkeys.com/book/practical-an-mp3-browser.html>

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Andreas Thiele
Subject: Re: dynamic array?
Date: 
Message-ID: <cmsj2e$9dd$05$1@news.t-online.com>
"Peter Seibel" <·····@javamonkey.com> schrieb im Newsbeitrag
···················@javamonkey.com...
> "Andreas Thiele" <··········@nospam.com> writes:
>
> > Hi,
> >
> > I need a sort of two dimensional dynamic array which I can think of in
terms
> > of rows and columns. Columns should have certain attributes like :name
or
> > :hidden. Rows should be easily accessible and modifyable. Well I wrote
it
> > myself and called it snapshot. Although it works fine and already is a
> > version 2 I still find it a somehow clumsy. I feel I can't see the
forrest
> > for the trees regarding simplicity.
> >
> > You might review my code for that beast (with two real life examples
> > attached) at
> >
> > www.atp-media.de/devel/snapshot.lsp
> >
> > Any suggestions or hints where I can find something similar or how I can
> > improve the code are very appreciated.
>
> I just took a quick look at this but it looks similar enough to
> something that I wrote for my book that you might find my take on the
> same problem interesting. A draft of the relevant chapter is at:
>
>   <http://www.gigamonkeys.com/book/practical-an-mp3-database.html>
>
> And it gets used in:
>
>   <http://www.gigamonkeys.com/book/practical-an-mp3-browser.html>
>
> -Peter
>
> --
> Peter Seibel                                      ·····@javamonkey.com
>
>          Lisp is the red pill. -- John Fraser, comp.lang.lisp

Peter,

playing around with some nice internet subjects your book gives indepth
explanations for rookies like me. I enjoyed reading the chapters.

Very helpful.


Thanks

Andreas
From: Wade Humeniuk
Subject: Re: dynamic array?
Date: 
Message-ID: <i%Njd.79358$VA5.11232@clgrps13>
Andreas Thiele wrote:

> Hi,
> 
> I need a sort of two dimensional dynamic array which I can think of in terms
> of rows and columns. Columns should have certain attributes like :name or
> :hidden. Rows should be easily accessible and modifyable. Well I wrote it
> myself and called it snapshot. Although it works fine and already is a
> version 2 I still find it a somehow clumsy. I feel I can't see the forrest
> for the trees regarding simplicity.
> 
> You might review my code for that beast (with two real life examples
> attached) at
> 
> www.atp-media.de/devel/snapshot.lsp
> 
> Any suggestions or hints where I can find something similar or how I can
> improve the code are very appreciated.

I would do something along these lines.  Storage is an adjustable array of
instances of CLOS classes.  Columns are then slots.  To add a column one
would have to redefine the class.

I think an array is better for storage, it is easier to index.

(in-package :cl-user)

(defclass searchable-instances ()
   ((storage :initform (make-array 256 :fill-pointer 0 :element-type t :adjustable t)
             :accessor storage)
    (storage-type :initarg :type :reader storage-type)
    (current-index :initform nil :reader current-index)))

(defmethod number-instances ((obj searchable-instances))
   (length (storage obj)))

(defmethod add-instance ((obj searchable-instances) new-instance)
   (assert (typep new-instance (storage-type obj)))
   (vector-push-extend new-instance (storage obj)))

(defmethod column-values ((obj searchable-instances) column)
   (map 'list (lambda (inst) (slot-value inst column)) (storage obj)))

#|

;; Example

(defclass person ()
   ((name :initarg :name)
    (age :initarg :age)))

CL-USER 24 > (setf si (make-instance 'searchable-instances :type 'person))
#<SEARCHABLE-INSTANCES 2067831C>

CL-USER 25 > (add-instance si (make-instance 'person :name "wade" :age :too-old))
0

CL-USER 26 > (number-instances si)
1

CL-USER 27 >(add-instance si (make-instance 'person :name "libby" :age 13))
1

CL-USER 28 > (number-instances si)
2

CL-USER 29 > (column-values si 'age)
(:TOO-OLD 13)

CL-USER 30 > (defclass person ()
                ((name :initarg :name)
                 (age :initarg :age)
                 (sex :initarg :sex :initform :unknown)))
#<STANDARD-CLASS PERSON 2066AFCC>

CL-USER 31 > (column-values si 'sex)
(:UNKNOWN :UNKNOWN)

CL-USER 32 >

|#

Wade