Re: Is there a better way?



Rainer Joswig <joswig@xxxxxxx> wrote:

First, let me say thanks. Sorry I haven't responded sooner; other
events were taking my time.

I'm going to learn this language if it kills me. To that end, I still
have a few questions.

In article <1i4nj72.va9wjk15wk1z8N%wrf3@xxxxxxxxxxxxxxx>,
wrf3@xxxxxxxxxxxxxxx (Bob Felts) wrote:

I'm writing some code that uses Zach Bean's wonderful SKIPPY library to
create gif files to graph some secret data. I need to map genus and
species to colors and put together the following table. The names have
been changed to protect the guilty. And it really isn't a biology
project, but species/genus works as an equivalent abstraction.

(defparameter *color-table*
'(("Species1" . ((nil . (nil . ( 0 0 0)))))
("Species2" . (("Genus1" . (nil . (255 255 255)))
("Genus2" . (nil . (255 255 0)))
("Genus3" . (nil . ( 67 167 241)))
("Genus4" . (nil . (255 0 255)))
("Genus5" . (nil . ( 0 255 255)))
(nil . (nil . (255 100 100)))))
("Species3" . (("Genus1" . (nil . (255 230 108)))
("Genus2" . (nil . (128 0 128)))
("Genus3" . (nil . ( 0 128 128)))
(nil . (nil . ( 0 255 0)))))
(nil . ((nil . (nil . (255 128 0)))))))

Make sure that you understand that above is a literal constant
and should NOT (!!!) be modified. It is not allowed in ANSI CL
to modify literal constants. If you want kind of
a list that you can modify, you need to create one
(using LIST, COPY-LIST, COPY-TREE, ...).


From a purist perspective, I agree with you. But I'm not sure I have
the right mental model of what's happening here. If I may descend to a
"vulgar" langauge, in C I can write:

SomeStructureType foo =
{ { ...}, {...}, {...} ...}

I can freely modify the contents of foo, unless I preface the
declaration with 'const'.

Is this equivalent to the defparameter? Or is there an implicit 'const'
in the Lisp expression? It seems seems strange to me that I can't
declare something like this and use it, without first copying it
somewhere else.


I picked this form since is makes finding Species/Genus easy with
assoc(). nil matches anything, which is handled by #'assoc-string (not
shown here).

It might be a bit more idiomatic to use symbols instead of strings.


There's madness to my method; the strings are what is found in a text
file and I want to be able to look at the things in the text file and
map them to the table without having to need an intermediate conversion.
This makes it simple to add another entry to the table - just add what
is seen in the text file.

Instead of data with list accessors (CAR, CDR) use a data type described
with DEFSTRUCT or DEFCLASS. If you want to use lists, then use DEFSTRUCT
with the list option. Like here:

? (defstruct (foo (:type list)) a b)
FOO
? (make-foo :a 'bar :b "baz")
(BAR "baz")
? (foo-a *)
BAR
?


I'm having trouble making the connection between what I think this does
and what I think I need. I spent some time yesterday googling for
defstruct; didn't help me much. However, I'll play with this when I get
some time to see what I can figure out.

[...]

the color table:

(defun init-clut (clut)
(loop for species in *color-table*
do
(loop for genus in (rest species)
do
(let ((color-info (rest genus)))
(setf (car color-info)
(ensure-color (apply #'rgb-color (cdr color-info)) clut))))))

IF you use a primitive LOOP, DOLIST is as good.


Since I'm still learning Lisp, I'm stressing LOOP at the moment just to
build muscle memory.

Otherwise you can use LOOP like this:

(defun init-clut (clut)
(loop for (name . genus) in *color-table*
do (loop for (name . color-info) in genus
do (setf (car color-info)
(ensure-color (apply #'rgb-color (cdr color-info))
clut)))))


Oh, my! Something else to learn.

But then you have the implementation of your color table
in your other code.

I would write a function that maps a function over the
color-table. Similar to this usage:

(defun init-clut (clut)
(map-color-table-entries
(lambda (r g b)
(ensure-color (rgb-color r g b) clut))))




ensure-color is the SKIPPY function to make an RGB triplet into a color
table and return the index.

My guestion is: is there a better way to do this? I'm not quite happy
with using the (nil . (R G B)) constuct to handle associating a color
index with an RGB triplet, but I'm not sure why I don't like it. I
should be happy that everything is data driven and that the code to
handle colors is quite short, but something is making me restless.

Any comments?

See also

See the article "DEFTABLE: A Macro for Implementing Tables"
by Peter Norvig, in Lisp Pointers.

http://www-cgi.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code
/ext/tables/0.html
http://portal.acm.org/citation.cfm?id=382665

I wish I could. I'm going on vacation next week and need to watch the
budget. :-o

.



Relevant Pages

  • Re: Is there a better way?
    ... species to colors and put together the following table. ... (defun map-color (species genus) ... (loop for species in *color-table* ... (setf (car color-info) ...
    (comp.lang.lisp)
  • Re: Cuk converter bizzare control loop
    ... >I expect this is probably a characteristic of the species. ... >just uses output inductor in series with 10 ohm load. ... >Would like to hear a comment on the control loop from someone who has played ...
    (sci.electronics.design)
  • Not Off topic - Optimization of a finite volume differencing scheme for multispecies transport
    ... reaction problem involving a large number of chemical species (more ... The transport actually have the following form ... Assuming that diffusion coefficients are the same for all species, ... Relationship between loop order and subscript order is also ...
    (comp.lang.fortran)

Loading