From: Glen Able
Subject: Newbie seeking feedback
Date: 
Message-ID: <cnhnn3$ged$1$8300dec7@news.demon.co.uk>
I'm finding myself with the time and energy to have another crack at
learning lisp, after a few abortive attempts.  So I'm using the Allegro
trial.  I'm finding it ok to work with, but the IDE seems a little
primitive, especially the source editor - limited undo, no syntax
highlighting etc.  Do you Allegro users use this, or work in another
third-party editor?  Maybe I've just been spoilt by years of VC++, or maybe
this stuff's not really important?

As a test problem, I thought it would be nice to write some code to solve
the 'Su Doku' problems from The Times:
http://www.timesonline.co.uk/section/0,,18209,00.html

Here's my code - I'd greatly welcome any constructive criticism.
Btw I was very pleased when I'd typed the test grid values in but needed to
change the format - as they were just lists, I was able to paste them into a
quickly hacked function in the listener which reformatted them for me -
beats the pants off the VB macro stuff in VC's IDE.

(defun solve()
  (let ((grid (make-grid)))
    (set-hard grid)
    (format t "Initial state...~%~%")
    (print-grid grid)
    (format t "~%Starting search...~%~%")
    (fill-grid grid)))

(defun set-hard(grid)
  (set-grid grid         '((0 0 5) (0 5 2) (0 6 6)
                           (1 1 7) (1 2 8) (1 5 6) (1 7 2)
                           (2 1 2) (2 6 9) (2 8 3)
                           (3 3 6) (3 6 8)
                           (4 0 4) (4 8 1)
                           (5 2 7) (5 5 4)
                           (6 0 3) (6 2 2) (6 7 5)
                           (7 1 9) (7 3 5) (7 6 1) (7 7 7)
                           (8 2 1) (8 3 8) (8 8 6))))

(defun make-grid()
  (make-array '(9 9) :initial-element nil))

(defun copy-grid(src)
  (let ((new-grid (make-grid)))
    (dotimes (row 9)
      (dotimes (col 9)
        (setf (aref new-grid row col)
          (aref src row col))))
    new-grid))

(defun show(value)
  (if value
      value
    0))

(defun print-row(grid row)
  (format t "~a ~a ~a | ~a ~a ~a | ~a ~a ~a ~%"
    (show (aref grid row 0))
    (show (aref grid row 1))
    (show (aref grid row 2))
    (show (aref grid row 3))
    (show (aref grid row 4))
    (show (aref grid row 5))
    (show (aref grid row 6))
    (show (aref grid row 7))
    (show (aref grid row 8))))

(defun print-grid(grid)
  (dotimes (row 9)
    (print-row grid row)
    (if (or (eql row 2) (eql row 5))
        (format t "------+-------+------~%"))))

(defun set-grid(grid init)
  (dolist (init-triple init)
    (setf (aref grid
                (car init-triple)
                (cadr init-triple))
      (caddr init-triple))))


(defun first-free-in-row(grid row)
  (dotimes (col 9)
    (if (not (aref grid row col))
        (return (list row col)))))

(defun first-free(grid)
  (dotimes (row 9)
    (let ((position (first-free-in-row grid row)))
      (if position
          (return position)))))

(defun remove-used-row(grid position list)
  (let ((row (car position)))
    (dotimes (col 9)
      (setf list
        (remove (aref grid row col) list))))
  list)

(defun remove-used-col(grid position list)
  (let ((col (cadr position)))
    (dotimes (row 9)
      (setf list
        (remove (aref grid row col) list))))
  list)

(defun remove-used-block(grid position list)
  (let ((row-start (* 3 (floor (/ (car position) 3))))
        (col-start (* 3 (floor (/ (cadr position) 3)))))
    (dotimes (row 3)
      (dotimes (col 3)
          (setf list
          (remove (aref grid
                        (+ row-start row)
                        (+ col-start col))
                  list)))))
  list)

(defun fill-grid(grid)
  (let ((position (first-free grid)))
     (if position
        (continue-fill-grid grid position)
      (print-grid grid))))

(defun continue-fill-grid(grid position)
  (let ((possible '(1 2 3 4 5 6 7 8 9)))
    (setf possible (remove-used-row grid position possible))
    (setf possible (remove-used-col grid position possible))
    (setf possible (remove-used-block grid position possible))
    (if possible
        (dolist (fill-val possible)
          (let ((new-grid (copy-grid grid)))
            (setf
             (aref new-grid (car position) (cadr position))
             fill-val)
            (fill-grid new-grid))))))

From: Kenneth Tilton
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <ktilton-D0F775.05383318112004@nycmny-nntp-rdr-03-ge1.rdc-nyc.rr.com>
In article <·····················@news.demon.co.uk>,
 "Glen Able" <·········@gmail.com> wrote:

> I'm finding myself with the time and energy to have another crack at
> learning lisp, after a few abortive attempts.  So I'm using the Allegro
> trial.  I'm finding it ok to work with, but the IDE seems a little
> primitive, especially the source editor - limited undo, no syntax
> highlighting etc.  Do you Allegro users use this, or work in another
> third-party editor?

I love the Allegro editor. They also let you use Emacs, which has syntax 
hiliting, but I have been using Emacs on OS X for a week and it is cute 
but adds no value. Then again, I am a born proofreader so I do not need 
it to tell me when I made a typo.

Tip: go to the options dialog and under editor set to emacs mode. Then 
study up on the key chords (a list can be called up from one of the help 
menus). It takes a while to learn, of course, but it is worth it.

Also, learn to use the cool control-click way of copying text, including 
entire forms. You will soon realize God meant us to delimit all 
expressions with parentheses, including the operator.

>  Maybe I've just been spoilt by years of VC++, or maybe
> this stuff's not really important?

I have used VC++ just enough to work with C libraries from Lisp. It is 
quite powerful. I find Lisp editors as powerful, tho sometimes in 
different ways. Give it time.

> 
> As a test problem, I thought it would be nice to write some code to solve
> the 'Su Doku' problems from The Times:
> http://www.timesonline.co.uk/section/0,,18209,00.html
> 
> Here's my code - I'd greatly welcome any constructive criticism.

I am sorry, we are The Savages of comp.lang.lisp. We only do destructive 
criticism: use delete instead of remove where possible. example:

> (defun remove-used-row(grid position list)
>   (let ((row (car position)))
>     (dotimes (col 9)
>       (setf list
>         (remove (aref grid row col) list))))
>   list)

That could just be delete in the iteration, a destructive operation 
which avoids re-copying the whole list (what remove does). Note that you 
still have to say (setf list (delete...)) in case the first item gets 
deleted. And you would have to begin with:

     (let ((new-list (copy-list list))....

btw, it took me forever and Peter's new book to get turned on to LOOP, 
but it would work well here. As would set-difference if you did not use 
an array to keep the master copy of the table, rather a list of lists 
(you just have to learn how to destructively modify a list (setf (car 
....) new-value):

  (defun excise-used-row (g p l)
    (set-difference l (nth (car p) g)))
   

> Btw I was very pleased when I'd typed the test grid values in but needed to
> change the format - as they were just lists, I was able to paste them into a
> quickly hacked function in the listener which reformatted them for me -
> beats the pants off the VB macro stuff in VC's IDE.
> 
> (defun solve()
>   (let ((grid (make-grid)))
>     (set-hard grid)
>     (format t "Initial state...~%~%")
>     (print-grid grid)
>     (format t "~%Starting search...~%~%")
>     (fill-grid grid)))
> 
> (defun set-hard(grid)
>   (set-grid grid         '((0 0 5) (0 5 2) (0 6 6)
>                            (1 1 7) (1 2 8) (1 5 6) (1 7 2)
>                            (2 1 2) (2 6 9) (2 8 3)
>                            (3 3 6) (3 6 8)
>                            (4 0 4) (4 8 1)
>                            (5 2 7) (5 5 4)
>                            (6 0 3) (6 2 2) (6 7 5)
>                            (7 1 9) (7 3 5) (7 6 1) (7 7 7)
>                            (8 2 1) (8 3 8) (8 8 6))))
> 
> (defun make-grid()
>   (make-array '(9 9) :initial-element nil))
> 
> (defun copy-grid(src)
>   (let ((new-grid (make-grid)))
>     (dotimes (row 9)
>       (dotimes (col 9)
>         (setf (aref new-grid row col)
>           (aref src row col))))
>     new-grid))

If I have not talked you into going back to lists, you could save 
yourself a little work with:

    #2a((0 0 5)(0 5 2))

Which lets you create the 2d array in one go.

> 
> (defun show(value)
>   (if value
>       value
>     0))

Try: (or value 0)

> 
> (defun print-row(grid row)
>   (format t "~a ~a ~a | ~a ~a ~a | ~a ~a ~a ~%"
>     (show (aref grid row 0))
>     (show (aref grid row 1))
>     (show (aref grid row 2))
>     (show (aref grid row 3))
>     (show (aref grid row 4))
>     (show (aref grid row 5))
>     (show (aref grid row 6))
>     (show (aref grid row 7))
>     (show (aref grid row 8))))

If you do go to a list of lists, you will be able to have a ball with 
format string directives ~{~} and more to get the " |"s (I am not fluent 
enough in that to dash it off) and do this in one line. Great fun.

Nice start on Lisp. You should win a lot of champagne. :)

kenny
From: Glen Able
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <cni94c$8hd$1$830fa7b3@news.demon.co.uk>
"Kenneth Tilton" <·······@nyc.rr.com> wrote in message
··································@nycmny-nntp-rdr-03-ge1.rdc-nyc.rr.com...

> Tip: go to the options dialog and under editor set to emacs mode. Then
> study up on the key chords (a list can be called up from one of the help
> menus). It takes a while to learn, of course, but it is worth it.

Right, there's some nice commands there - I'll have a play.

> Also, learn to use the cool control-click way of copying text, including
> entire forms. You will soon realize God meant us to delimit all
> expressions with parentheses, including the operator.

Any more clues on this?

> > As a test problem, I thought it would be nice to write some code to
solve
> > the 'Su Doku' problems from The Times:
>
> I am sorry, we are The Savages of comp.lang.lisp. We only do destructive
> criticism: use delete instead of remove where possible. example:

Hee hee, you should try putting a post like mine on a C++ newsgroup.  You'd
instantly get a dozen gleeful replies of "Standard C++ has no concept of
editors or The Times or playing with things.  What is your question about
standard C++?"

>
> > (defun remove-used-row(grid position list)
> >   (let ((row (car position)))
> >     (dotimes (col 9)
> >       (setf list
> >         (remove (aref grid row col) list))))
> >   list)
>
> That could just be delete in the iteration, a destructive operation
> which avoids re-copying the whole list (what remove does). Note that you
> still have to say (setf list (delete...)) in case the first item gets

I'll have a crack at the destructive operations.  I guess I'm generating
tons of unnecessary garbage, which may start to be a problem if I carry on
with this (I was thinking of making it generate puzzles as well, by
searching for puzzles which have precisely one solution).

> > (defun show(value)
> >   (if value
> >       value
> >     0))
>
> Try: (or value 0)

Ta.  What I actually want is (or value " ").  I was using 0 as a sort of
placeholder for a space simply because the idea of returning whatever type I
fancied was simply too alien for my C++ encrusted mind.

> If you do go to a list of lists, you will be able to have a ball with
> format string directives ~{~} and more to get the " |"s (I am not fluent
> enough in that to dash it off) and do this in one line. Great fun.

I'll try the list of lists as well, for the hell of it.  Cheers for your
help kenny.
From: Kenneth Tilton
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <ktilton-31378C.10095318112004@nyctyp01-ge0.rdc-nyc.rr.com>
In article <·····················@news.demon.co.uk>,
 "Glen Able" <·········@gmail.com> wrote:

> "Kenneth Tilton" <·······@nyc.rr.com> wrote in message
> ··································@nycmny-nntp-rdr-03-ge1.rdc-nyc.rr.com...
> 
> > Also, learn to use the cool control-click way of copying text, including
> > entire forms. You will soon realize God meant us to delimit all
> > expressions with parentheses, including the operator.
> 
> Any more clues on this?

It is a little counterintuitive for the first hour or so, now I use it 
steadily. You leave the insertion point (caret) where the code will go, 
then control click on a word or left or right parens and, shazzam, it 
gets copied to the insertion point. So it is a copy and paste in one 
click. Note that if there is a selection active, like any good paste it 
will zap the selection.

That last bit comes up a lot during refactoring. Maybe I decide (if Q X 
Y) should be just X or Y, since the Q question has been factored away 
and my code will either X or Y depending on how the refactoring went. So 
I double click (if x y) then control-click, say, X. control-shift-p to 
re-indent.

i also use it a lot instead of symbol-completion. I get to where some 
big long name belongs and, if I can see it on the screen, wham, 
control-click and I have it. beats typing a few characters (wondering 
how many to type) and then control-stop to, damn, bring up a menu of 
matches.

very addictive.

> 
> > > As a test problem, I thought it would be nice to write some code to
> solve
> > > the 'Su Doku' problems from The Times:
> >
> > I am sorry, we are The Savages of comp.lang.lisp. We only do destructive
> > criticism: use delete instead of remove where possible. example:
> 
> Hee hee, you should try putting a post like mine on a C++ newsgroup.  You'd
> instantly get a dozen gleeful replies of "Standard C++ has no concept of
> editors or The Times or playing with things.  What is your question about
> standard C++?"

What about their pub bashes when they get together? I bet that is when 
they let their hair down. 

> 
> >
> > > (defun remove-used-row(grid position list)
> > >   (let ((row (car position)))
> > >     (dotimes (col 9)
> > >       (setf list
> > >         (remove (aref grid row col) list))))
> > >   list)
> >
> > That could just be delete in the iteration, a destructive operation
> > which avoids re-copying the whole list (what remove does). Note that you
> > still have to say (setf list (delete...)) in case the first item gets
> 
> I'll have a crack at the destructive operations.  I guess I'm generating
> tons of unnecessary garbage, which may start to be a problem if I carry on
> with this (I was thinking of making it generate puzzles as well, by
> searching for puzzles which have precisely one solution).
> 
> > > (defun show(value)
> > >   (if value
> > >       value
> > >     0))
> >
> > Try: (or value 0)
> 
> Ta.  What I actually want is (or value " ").  I was using 0 as a sort of
> placeholder for a space simply because the idea of returning whatever type I
> fancied was simply too alien for my C++ encrusted mind.

heh-heh.

> 
> > If you do go to a list of lists, you will be able to have a ball with
> > format string directives ~{~} and more to get the " |"s (I am not fluent
> > enough in that to dash it off) and do this in one line. Great fun.
> 
> I'll try the list of lists as well, for the hell of it.  Cheers for your
> help kenny.

Don't forget the newbie survey:

   http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey

Speaking of which, the Class of 2004 needs help. But I am delighted to 
see a couple of old hands have ponied up their Roads. I thought hell 
would freeze over before I saw some of those. :)

Seriously newbies, let's get those surveys filled out. If we want to do 
Lisp at work, we need to make clear Lisp is not dead, it was only 
resting.

kenny
From: drewc
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <S0dnd.258584$Pl.91720@pd7tw1no>
Kenneth Tilton wrote:
[...]

> Don't forget the newbie survey:
> 
>    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
> 
> Speaking of which, the Class of 2004 needs help. 

Ok, I finally filled out my RtL! is it wrong that i someday dream of 
being in the elite 'Kenny's RtLS Top Ten' ?

fortune and glory await ...

drewc
From: Kenny Tilton
Subject: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <OLdnd.18046$Vk6.17847@twister.nyc.rr.com>
drewc wrote:
> Kenneth Tilton wrote:
> [...]
> 
>> Don't forget the newbie survey:
>>
>>    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
>>
>> Speaking of which, the Class of 2004 needs help. 
> 
> 
> Ok, I finally filled out my RtL! is it wrong that i someday dream of 
> being in the elite 'Kenny's RtLS Top Ten' ?

Well it /is/ a wiki. :)

But if you want to get in on merit, well, you have potential, 
grasshopper. You seem to have strong grounding in the current pop star 
languages. that gives you credibility -- I merely saw that O'Reilly 
published books about them and knew they sucked.

And you were so dissatisfied with them you actually attempted a 
Supergreenspun, actually starting a new language which...

...you concluded was unnecessary once your road arrived at Lisp.

And to top it off, you actually delivered an app using the damn thing! A 
modern-day web thingy!!

> 
> fortune and glory await ...
>

(a) dude, lose the italics!

(b) the judges also look for substantial beef. Above I re-spun your 
piece as it could have read but might not to the hasty reader. When you 
say (paraphrasing) "the other languages weren't cutting it", throw in 
some recognizable (to their users) specifics "demons kept flying out of 
my nose every time I XXX". Walk thru the /un-italicized/ text and flesh 
out the highlight film above.

(c) whatever you do, do not solicit the judges for consideration! :)

Well, the damage is done. That list could use updating. As could the 
Highlight Film, which has not been updated in a very long time and so 
has missed the three people who added Roads.

Tell you what, I am pretty busy these days with CliniSys, cells-gtk, and 
cello/osx, but if you punk-ass newbies (sorry, been listening to hip-hop 
all afternoon) will put up some fricking Roads, Himself may deign to get 
the hood up on the Highlight Film and Top-ten list.

    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey

we out. blood.


-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: drewc
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <Lmend.266701$%k.111289@pd7tw2no>
Kenny Tilton wrote:

> But if you want to get in on merit, well, you have potential, 
> grasshopper. 
(/me beams with pride)

>You seem to have strong grounding in the current pop star 
> languages. that gives you credibility -- I merely saw that O'Reilly 
> published books about them and knew they sucked.

lol .. and i used to think that having an 'Animal Book' was a good-thing.

[...]
>>
>> fortune and glory await ...
>>
> 
> (a) dude, lose the italics!

Ok, done. They were in the template RtL Questions page which i 
copied/pasted... So i removed them from there as well, and added the 
*(switch date 2004) which was missing

> 
> (b) the judges also look for substantial beef. Above I re-spun your 
> piece as it could have read but might not to the hasty reader. When you 
> say (paraphrasing) "the other languages weren't cutting it", throw in 
> some recognizable (to their users) specifics "demons kept flying out of 
> my nose every time I XXX". Walk thru the /un-italicized/ text and flesh 
> out the highlight film above.

Done.

> 
> (c) whatever you do, do not solicit the judges for consideration! :)

Moi? Never! ;)

> 
> Well, the damage is done. That list could use updating. As could the 
> Highlight Film, which has not been updated in a very long time and so 
> has missed the three people who added Roads.
> 
> Tell you what, I am pretty busy these days with CliniSys, cells-gtk, and 
> cello/osx, but if you punk-ass newbies (sorry, been listening to hip-hop 
> all afternoon) will put up some fricking Roads, Himself may deign to get 
> the hood up on the Highlight Film and Top-ten list.
> 
>    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
> 
> we out. blood.

Word. Peace out brethren.

drewc
From: Kenny Tilton
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <Vxfnd.18231$Vk6.11677@twister.nyc.rr.com>
drewc wrote:
> Kenny Tilton wrote:
>> (a) dude, lose the italics!
> 
> 
> Ok, done. They were in the template RtL Questions page which i 
> copied/pasted... So i removed them from there as well

Great, now put them back. :) It is a standard deal on forms to put 
question mini-help in italics so they are not mistaken for part of the 
question:

    Name your favorite hip-hop stars. /(include number of times shot)/

meanwhile, I had a /lot/ of complaints about the (deliberate) vagueness 
of the questions. But i did not need the questions to be three lines 
long when reading a completed survey where the answers spoke for 
themselves anyway.

> , and added the 
> *(switch date 2004) which was missing

Good move. Did you track down all the 2004 entries and add the link? :)

> 
>>
>> (b) the judges also look for substantial beef. Above I re-spun your 
>> piece as it could have read but might not to the hasty reader. When 
>> you say (paraphrasing) "the other languages weren't cutting it", throw 
>> in some recognizable (to their users) specifics "demons kept flying 
>> out of my nose every time I XXX". Walk thru the /un-italicized/ text 
>> and flesh out the highlight film above.
> 
> 
> Done.

Ok, nice deets on the excess boilerplate. But then i should think macros 
would be the first thing you would have learned... oh, ok, you found 
some cool CL libs which already had WITH-HTML-...?

Well, OK, i think the Supergreenspun gets you in. Soon. i want to make a 
little headway on UFFI-izing cells-gtk before a major revisit to RtL.

btw, I appreciate vasilis giving cells top billing, but from now on lets 
just leave it out of the name of new projects. every library will be 
Cells Inside(tm) pretty soon, so it is kinda redundant.

:)

kenny


-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: drewc
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <vcgnd.264584$nl.137646@pd7tw3no>
Kenny Tilton wrote:
> drewc wrote:
> 
>> Ok, done. They were in the template RtL Questions page which i 
>> copied/pasted... So i removed them from there as well
> 
> 
> Great, now put them back. :) It is a standard deal on forms to put 
> question mini-help in italics so they are not mistaken for part of the 
> question:

Ok, done again! There were no questions there, rather someone elses 
answers, but it's back the way it was (with the exception of the switch 
date bit).

> 
>    Name your favorite hip-hop stars. /(include number of times shot)/

Listening to a lot of MC Solaar lately .. love the francophone flow. 
Never shot AFAIK. Big fan of the toronto scene as well (K-OS for 
example) .. home town boys :). Not much shooting there either. I try to 
stay with the concious side of hip-hop... no bling-bling needed.

underground house and garage (the nyc sound, salsoul, nakedmusic, 
Masters at Work) is more my thing. Funky beats w/ jazzy progressions... 
mmmmmm.

> 
> meanwhile, I had a /lot/ of complaints about the (deliberate) vagueness 
> of the questions. But i did not need the questions to be three lines 
> long when reading a completed survey where the answers spoke for 
> themselves anyway.

pfft. the questions are fine.
> 
>> , and added the *(switch date 2004) which was missing
> 
> 
> Good move. Did you track down all the 2004 entries and add the link? :)

http://alu.cliki.net/Switch%20Date%202004

It seems that people were smart enough to add it themselves. I could do 
a little more wiki-gnome work, but that keeps me away from the REPL... 
perhaps when the Carpal Tunnel starts acting up....

> Ok, nice deets on the excess boilerplate. But then i should think macros 
> would be the first thing you would have learned... oh, ok, you found 
> some cool CL libs which already had WITH-HTML-...?

Essentially. I found UncommonWeb, which is almost exactly like the 
language i was designing, only significantly more powerful! (i didn't 
even know what continuations were when i was writing my language, yet i 
was greenspunning them in there. Ucw has a partial continuations 
implementation that serves my needs exactly).

I generally avoid generating HTML from code, and try to use a template 
approach whenever possible. i find it much easier to maintain that way. 
That being said, since lisp has such great facilities for html 
generation, i find myself using html generation where it fits. (i use 
yaclml, it's included in UCW).

Since UCW had most of what i needed, i never found a reason to write my 
own macro's until recently, when i decided that i could generate the 
entire application from the database description. Now i find myself 
wanting to write a macro for everything, so i'm trying to avoid writing 
any more until i _REALLY_ find a need.... those macros are dangerous!

> 
> Well, OK, i think the Supergreenspun gets you in. Soon. i want to make a 
> little headway on UFFI-izing cells-gtk before a major revisit to RtL.

I most certainly second that motion. cells-gtk is very exciting to me!

> 
> btw, I appreciate vasilis giving cells top billing, but from now on lets 
> just leave it out of the name of new projects. every library will be 
> Cells Inside(tm) pretty soon, so it is kinda redundant.

I remember when i was first reading up on lisp, I was like "I don't 
quite know what this is or what it does .. but i know i need it" ... I 
currently feel the same way about cells :) .. when i figure out what it 
is and why i need it, i'll be that much closer to enlightenment. :).

Until then, cells is the stone the master holds in his hand. Once i can 
grasp it ......


drewc


> 
> :)
> 
> kenny
> 
> 
From: Kenny Tilton
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <OGhnd.18238$Vk6.47@twister.nyc.rr.com>
drewc wrote:
> Kenny Tilton wrote:
> 
>> drewc wrote:
>>
>>> Ok, done. They were in the template RtL Questions page which i 
>>> copied/pasted... So i removed them from there as well
>>
>>
>>
>> Great, now put them back. :) It is a standard deal on forms to put 
>> question mini-help in italics so they are not mistaken for part of the 
>> question:
> 
> 
> Ok, done again! There were no questions there, rather someone elses 
> answers, 

heh-heh, that happens a lot. i think I finally broke down and kept a 
copy on my HD. I'll fix it up shortly. Thx for the heads up.

> Listening to a lot of MC Solaar lately .. love the francophone flow. 

Oh yeah. I had, what?, Prose Combat? An earlier one. Excellent. lost it. :(


> ..... Now i find myself 
> wanting to write a macro for everything, so i'm trying to avoid writing 
> any more until i _REALLY_ find a need.... those macros are dangerous!

Hell, I'll do a macro just so I do not have to quote a symbol. :)

> 
>>
>> Well, OK, i think the Supergreenspun gets you in. Soon. i want to make 
>> a little headway on UFFI-izing cells-gtk before a major revisit to RtL.
> 
> 
> I most certainly second that motion. cells-gtk is very exciting to me!

Almost done with the FFI translation. I am cheating. vasilis himself 
used macros to generate native CLisp FFI, so i am just conditionalizing 
his macro bodies to expand into UFFI FFI unless in CLisp. Suh-weet.

And to think we had to debate Pythonistas for a month over whether 
macros are a good idea. :)

> Until then, cells is the stone the master holds in his hand. Once i can 
> grasp it ......

You cannot take what you already have.

You have used spreadsheet software. Your applications have long-lived 
state, which sometimes changes as other such state changes. A list item 
which loses its membership in a user selection (one bit of long-lived 
state) must take on a new un-highlighted appearance. Perhaps some 
corresponding thing becomes no longer visible, another bit of long-lived 
state. And GUI is just one (good) example of interdependent long-lived 
state.

Cells let you author all long-lived state the way you program VisiCalc:

    (make-instance 'widget
       :highlightedp (c? (find self (selection <list-widget>))))

With the same automatic dependency tracking and automatic change 
propagation. OS events or socket reads initiate cascades of state change 
throughout your application, which is now effectively a spreadsheet 
model imposed on slots of instances.

Without cells, the programmer is a modeller working with a paper 
spreadsheet. That sucking so badly is why Visicalc was the first killer 
app.

Vasilis said he found Cells effective. If you have win32 or linux you 
can grab CLisp now and the distro from cells-gtk and check it out 
yourself. Spreadsheet formula-like rules can be found by searching for 
"c?". Dependencies Just Happen by invoking the reader of a slot. State 
change can be initiated on slot change via "def-c-output".

Note that, as with Celtic, def-c-output served brilliantly in dealing 
with Tk/Gtk -- CLOS instances shadowed Gtk widgets, and macro-generated 
def-c-outputs on each slot corresponding to a Gtk attribute reliably and 
automatically saw to it that the Gtk widget attribute stayed current 
with the shadowing instance's slot. hellasweet.

The hard part is accepting that applications can be programmed this way, 
but I think it is like structured programming: yep, the most convoluted 
goto mess can be rewritten without gotos without changing the semantics.

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Kenny Tilton
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <USond.18270$Vk6.358@twister.nyc.rr.com>
>> Until then, cells is the stone the master holds in his hand. Once i 
>> can grasp it ......

Yet Another Cells-alike:

    http://slashdot.org/comments.pl?sid=129894&cid=10835594

kt

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Randall Randall
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <41a0a811$1_1@alt.athenanews.com>
Kenny Tilton wrote:

> Cells let you author all long-lived state the way you program VisiCalc:
> 
>    (make-instance 'widget
>       :highlightedp (c? (find self (selection <list-widget>))))
> 
> With the same automatic dependency tracking and automatic change 
> propagation. OS events or socket reads initiate cascades of state change 
> throughout your application, which is now effectively a spreadsheet 
> model imposed on slots of instances.

How is this different or better than having
HIGHLIGHTEDP, for example, be a method?  If
it's a method, then it can have the same logic
in it, and you'd typically have an accessor
method for it anyway, so why bother pretending
it's a slot in the first place?

--
Randall Randall <·······@randallsquared.com>
Property law should use #'EQ , not #'EQUAL .
From: Kenny Tilton
Subject: Why the dataflow paradigm? [was Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]]
Date: 
Message-ID: <lk5od.20359$Vk6.5878@twister.nyc.rr.com>
Randall Randall wrote:
> Kenny Tilton wrote:
> 
>> Cells let you author all long-lived state the way you program VisiCalc:
>>
>>    (make-instance 'widget
>>       :highlightedp (c? (find self (selection <list-widget>))))
>>
>> With the same automatic dependency tracking and automatic change 
>> propagation. OS events or socket reads initiate cascades of state 
>> change throughout your application, which is now effectively a 
>> spreadsheet model imposed on slots of instances.
> 
> 
> How is this different or better than having
> HIGHLIGHTEDP, for example, be a method?  If
> it's a method, then it can have the same logic
> in it, and you'd typically have an accessor
> method for it anyway, so why bother pretending
> it's a slot in the first place?

There are a lot of reasons. Let's get some easy ones out of the way:

Easy One one: a purely functional approach for all such attributes will 
not scale. That was our first version off the drawing board. By the time 
you have fifty images each with a dozen functional attributes, yer dead 
when an update event comes along.

Easy One two: please observe that the rule is being supplied at 
make-instance time. For that instance. A different instance of the same 
class can have a different rule. This happens to be huge. It delivers 
the Grail of OO reuse, because I can now customize an instance to suit 
the immediate requirements at some point in my code without creating a 
new subclass. And since this is Lisp, I can even capture lexicals. 
Woohoo. COSI, btw, is similar to Cells, but does not allow instance rules.

Easy one three: now imagine a more complex rule, linked, say, to the 
contents of a database. (Yes, I once endowed a persistent CLOS database 
with Cells.) Now go back to "purely functional will not scale". :)

Now for more profound reasons. They boil down to a phrase you quoted: 
"cascades of state change".

Before getting into the deets, and going back to the spreadsheet 
metaphor, have you ever built a really complex model using one? No 
single rule is very complicated. But if you had that same model on 
paper, the way they did before VisiCalc, god help you when you wanted 
to, say, change the interest rate assumption. The good news is that 
anything like Cells (and there are many such things and you can even 
roll your own from scratch in a few hours) empowers software development 
as much as VisiCalc empowered the spreadsheet user stuck with paper, 
pencil, and slipstick.

Now some deets.

Set-up: In a conventional invalidate/update GUI scheme, the method you 
propose will not take effect until the widget gets redrawn. In Cello 
with its display-list approach, the method will not take effect until 
the display list for the widget gets rebuilt. So...

Problem: The developer working on the selection management of the List 
widget knows enough to force the "redraw" (in either scheme) of the 
list. But what if there is some wholly different widget whose 
highlighted attribute must track the selection? The selection programmer 
not know about this other widget. It does not even exist in their mind. 
They have no idea in what actual widget collection the list will be 
embedded. How do they know to update, say, the photo being displayed in 
the photoview widget when the user clicks on a different item in the 
list of photos?

Weak solution: of course there is a weak solution, because such things 
are achieved without Cells. The list widget takes an on-change callback 
which can be specific to an instance of the widget. We just supply one 
which forces a "redraw" of the photoview. Why is this weak? Two things.

First of all, we have to do it. When I add a thumbnail widget somewhere 
linked to the same selection, it will not work at first because I will 
forget to update the selection callback also to force the update of my 
thumbnail. And when the user says they hate the thumbnail and I take it 
out, the callback will crash.

Cells make this whole business disappear, by making dependencies 
automatic, transparent, and hands-off. In an invalidation scheme:


(def-c-output highlightedp (self new-value old-value)
    ;; this wont get called unless the state changes so...
    (declare (ignore new-value old-value))
    (invalidate-widget self))

In Cello, it is even cooler. When the display list gets built the first 
time, the highlightedp slot will get used. Yer done. (The rule to 
compute the display list knows to post a redisplay -- it would not be 
running unless something had changed.)

Just as with visicalc, Cells users build models which /work by 
themselves/. I have a funny slide in my presentation which shows a team 
of puppeteers struggling with the strings of the marionettes below -- 
they look just like computer programmers trying to make software work.

Second, sure, most GUIs have callbacks like this precisely  to help 
somewhat with the interdependencies. Their very existence makes the case 
for Cells, which handles the problem in the general case. And better, as 
just noted. So do not make the mistake many do when they say, "Ah, but I 
use WidgetsToDieFor(tm) and I only have to setf the highlightedp 
attribute and shazzam! there it is."

Yeah. Is the programmer that wrote all the plumbing for that going to 
come over and do the same for the rest of your application? Indeed, 
people make this mistake often when they hear about Cells, so I think 
any good talk on Cells uses examples not involving GUIs.

I had a ball with Cells programming for RoboCup. The only input is from 
a socket, the only output goes to a socket.

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Randall Randall
Subject: Re: Why the dataflow paradigm? [was Re: The Road to Lisp Newby Survey[was Re: Newbie seeking feedback]]
Date: 
Message-ID: <41a0ed36$1_5@alt.athenanews.com>
Kenny Tilton wrote:
> Randall Randall wrote:
>> Kenny Tilton wrote:
>>> Cells let you author all long-lived state the way you program VisiCalc:
>>>
>>>    (make-instance 'widget
>>>       :highlightedp (c? (find self (selection <list-widget>))))
>>
>> How is this different or better than having
>> HIGHLIGHTEDP, for example, be a method?  If
>> it's a method, then it can have the same logic
>> in it, and you'd typically have an accessor
>> method for it anyway, so why bother pretending
>> it's a slot in the first place?
> 
> There are a lot of reasons. Let's get some easy ones out of the way:
> 
> Easy One one: a purely functional approach for all such attributes will 
> not scale. That was our first version off the drawing board. By the time 
> you have fifty images each with a dozen functional attributes, yer dead 
> when an update event comes along.

I haven't done any GUI programming, so maybe this just went
over my head, but the choice seems to be "Do the work every
time there's any possible change to the data", or "Do the work
only when asked for the result", and it seems obvious that the
latter is going to be less work overall, right?  Therefore, if
the functional approach (doing the minimum work) doesn't scale,
how can an approach that cavalierly does *extra* work when the
result may be thrown away at the next event, before it's ever
used?

> Easy One two: please observe that the rule is being supplied at 
> make-instance time. For that instance. A different instance of the same 
> class can have a different rule. This happens to be huge. It delivers 
> the Grail of OO reuse, because I can now customize an instance to suit 
> the immediate requirements at some point in my code without creating a 
> new subclass. And since this is Lisp, I can even capture lexicals. 
> Woohoo. COSI, btw, is similar to Cells, but does not allow instance rules.

Yes, this seems like a win in the case that your instances
have very different logic that would need to go into a method,
and you can't define the method on different input types.
Basically, this wins if you'd otherwise be defining a lot of
EQL-specializing methods, I guess?

> Easy one three: now imagine a more complex rule, linked, say, to the 
> contents of a database. (Yes, I once endowed a persistent CLOS database 
> with Cells.) Now go back to "purely functional will not scale". :)
> 
> Now for more profound reasons. They boil down to a phrase you quoted: 
> "cascades of state change".

This seems like a paraphrase of "work done when it might be that
no user of this instance will care about the result".

> Before getting into the deets, and going back to the spreadsheet 
> metaphor, have you ever built a really complex model using one? 

Nope.

> No 
> single rule is very complicated. But if you had that same model on 
> paper, the way they did before VisiCalc, god help you when you wanted 
> to, say, change the interest rate assumption. The good news is that 
> anything like Cells (and there are many such things and you can even 
> roll your own from scratch in a few hours) empowers software development 
> as much as VisiCalc empowered the spreadsheet user stuck with paper, 
> pencil, and slipstick.

Again, it's hard for me to imagine how calling the input function
with different arguments, or changing some configuration special
variables, would be less powerful.


> Now some deets.

I'll have to study the rest of this further, since it uses a
bunch of concepts and methods with which I'm not familiar, not
being a GUI programmer (yet).

-- 
Randall Randall <·······@randallsquared.com>
Property law should use #'EQ , not #'EQUAL .
From: Kenneth Tilton
Subject: Re: Why the dataflow paradigm? [was Re: The Road to Lisp Newby Survey[was Re: Newbie seeking feedback]]
Date: 
Message-ID: <ktilton-94AF83.16565621112004@nyctyp01-ge0.rdc-nyc.rr.com>
In article <············@alt.athenanews.com>,
 Randall Randall <·······@randallsquared.com> wrote:

> Kenny Tilton wrote:
> > Randall Randall wrote:
> >> Kenny Tilton wrote:
> >>> Cells let you author all long-lived state the way you program VisiCalc:
> >>>
> >>>    (make-instance 'widget
> >>>       :highlightedp (c? (find self (selection <list-widget>))))
> >>
> >> How is this different or better than having
> >> HIGHLIGHTEDP, for example, be a method?  If
> >> it's a method, then it can have the same logic
> >> in it, and you'd typically have an accessor
> >> method for it anyway, so why bother pretending
> >> it's a slot in the first place?
> > 
> > There are a lot of reasons. Let's get some easy ones out of the way:
> > 
> > Easy One one: a purely functional approach for all such attributes will 
> > not scale. That was our first version off the drawing board. By the time 
> > you have fifty images each with a dozen functional attributes, yer dead 
> > when an update event comes along.
> 
> I haven't done any GUI programming, so maybe this just went
> over my head, but the choice seems to be "Do the work every
> time there's any possible change to the data", or "Do the work
> only when asked for the result", and it seems obvious that the
> latter is going to be less work overall, right?  Therefore, if
> the functional approach (doing the minimum work) doesn't scale,
> how can an approach that cavalierly does *extra* work when the
> result may be thrown away at the next event, before it's ever
> used?

Yes, your lack of GUI programming makes this harder, but you are asking 
good questions, so let us soldier on.

First of all, many people think lazy propagation (only when asked) is 
the only way to go. They are convinced eager propagation will knock any 
system to its knees. Nah, I have been using Cells this way for going on 
a decade without a problem. Anyway...

One thing you are missing is that, for a display attribute such as 
highlightedp, someone is always asking. The user. What good is it to 
know that your functional highightedp would return the right answer if 
nothing is done to force a redraw of the given widget? This is a 
dataflow problem, including flowing all the way out to the user.

There is no unnecessary work going on. Now you say the functional 
approach does "the minimum work". Can we talk? :) What happens when two 
people ask for the same computed attribute? like I said, this is where 
Cells started, before we cached the results of evaluating a rule.


> 
> > Easy One two: please observe that the rule is being supplied at 
> > make-instance time. For that instance. A different instance of the same 
> > class can have a different rule. This happens to be huge. It delivers 
> > the Grail of OO reuse, because I can now customize an instance to suit 
> > the immediate requirements at some point in my code without creating a 
> > new subclass. And since this is Lisp, I can even capture lexicals. 
> > Woohoo. COSI, btw, is similar to Cells, but does not allow instance rules.
> 
> Yes, this seems like a win in the case that your instances
> have very different logic that would need to go into a method,
> and you can't define the method on different input types.
> Basically, this wins if you'd otherwise be defining a lot of
> EQL-specializing methods, I guess?

No, this has nothing to do with EQL methods. Imagine a stretch of code 
in which you are laying out a series of buttons which look pretty damn 
similar to the user. Now as I said, many an elaborate GUI system has 
been developed so programmers /can/ use the same button class for each 
one, but only because they built that elaborate GUI. Cells lets you 
create ten buttons with massively different behavior and appearance 
rules just by the very nature of Cells.

This btw is why I am able to build GUI frameworks myself -- I am simply 
not doing all the work the typical framework author does. This is also 
why there is no need for CLIM, now that we have (three <g>) cell-driven 
GUIs.

> 
> > Easy one three: now imagine a more complex rule, linked, say, to the 
> > contents of a database. (Yes, I once endowed a persistent CLOS database 
> > with Cells.) Now go back to "purely functional will not scale". :)
> > 
> > Now for more profound reasons. They boil down to a phrase you quoted: 
> > "cascades of state change".
> 
> This seems like a paraphrase of "work done when it might be that
> no user of this instance will care about the result".

A dead-end slot? <g> i think I have managed to create one or two of 
those over the years by not noticing during a refactoring that something 
had been obsoleted. Vestigial might be a better word, since they must 
have served a purpose at some time.

> 
> > Before getting into the deets, and going back to the spreadsheet 
> > metaphor, have you ever built a really complex model using one? 
> 
> Nope.

Growing up I got to watch my father working spreadsheets in pencil when 
he brought work home. ick.

> 
> > No 
> > single rule is very complicated. But if you had that same model on 
> > paper, the way they did before VisiCalc, god help you when you wanted 
> > to, say, change the interest rate assumption. The good news is that 
> > anything like Cells (and there are many such things and you can even 
> > roll your own from scratch in a few hours) empowers software development 
> > as much as VisiCalc empowered the spreadsheet user stuck with paper, 
> > pencil, and slipstick.
> 
> Again, it's hard for me to imagine how calling the input function
> with different arguments, or changing some configuration special
> variables, would be less powerful.

The problem may be that you are staring so hard at the one highlightedp 
rule example I gave. You have to open a word-processing application and 
stare at the sea of butons, scroll bars, menus, popups, check boxes, tab 
controls... the Big Problem of IT is that almost anyone can write a 
solid twenty-line program. The field starts to thin at 100 LOC. By 1k 
LOC we only have professionals. At 10k only the best are still around. 
At 100k it is a crap shoot whether the system ever gets off the ground.

Brooks identified the exponential increase in interdependent program 
state as an inherent (he used "essential") ineluctable barrier to an 
order of magnitude improvement in software development in his famous "No 
Silver Bullet" essay.

But you will not see the problem in just one rule watching just one 
other slot. Only as the application scales does the problem arise, and 
projects fail.



> 
> 
> > Now some deets.
> 
> I'll have to study the rest of this further, since it uses a
> bunch of concepts and methods with which I'm not familiar, not
> being a GUI programmer (yet).

It is not just GUI. I mentioned RoboCup. The player had a goal which was 
a function of the game situation. The goal was a tree of tactics, 
tailored further to the game situation. each tactic (subgoal?) had a 
rule to determine when it had succeeded. subgoals were wuiescent until 
preceding subgoals toggled "complete". etc etc etc.

Likewise the Cliniys system has a rule on a document in the database. If 
one page has been scanned in, they all better have been. If not, an 
Alert instance gets created in the DB. Then if some operator scans in 
the last missing page, Cells arranges for the Alert to be deleted. ie, 
It's alive!!! (scary, right?)

And of course GUI elements can watch the DB as well. So there is a list 
box which shows a site any errors. During the demo we like to have that 
list box in view showing the alert and then drop the page in the scanner 
and watch the alert go away. What no one but me knows is that I wrote 
zero code to make that happen. The "contents" rule for the list box just 
says "find all alerts".

ie, There are no "refresh view" menu items in my applications. Can you 
imagine the support call? "Hey, I just scanned the damn thing in and the 
Alert still says "page 3 missing". Your software sucks!"

How do they know to go look for Alerts? The big Alerts button on the 
main dashboard switches the text color to red when it sees any Alerts in 
the DB.

kenny
From: Bruce Stephens
Subject: Re: Why the dataflow paradigm?
Date: 
Message-ID: <87k6sehjs5.fsf@cenderis.demon.co.uk>
Kenneth Tilton <·······@nyc.rr.com> writes:

[...]

> One thing you are missing is that, for a display attribute such as
> highlightedp, someone is always asking. The user. What good is it to
> know that your functional highightedp would return the right answer
> if nothing is done to force a redraw of the given widget? This is a
> dataflow problem, including flowing all the way out to the user.

Yeah, that's what I'd guess would happen: you're using this framework
to display stuff, so a large proportion of the results are always
going to be required.  Indeed, I'd guess that it would be more awkward
to do things lazily the other way around---much cleaner to let
changing inputs propagate immediately.

Why did other systems (for example, Garnet) stress constraint
programming so much, if Cells can get away with dataflow?  

I can sort of understand why you'd want constraint programming if the
user is involved in moving things around (for example, in the window
manager scwm, which has a constraints version that I never got to
build).  In those sorts of systems you want to allow users to change a
variety of different things, and compute the rest.  Is that what was
happening in Garnet, to some extent?  

Why doesn't it happen in Cells, I wonder?  (Or is it just that Cells
is basically dataflow, but it's possible to hack more general
constrainty behaviour in the few cases where it seems necessary?)

[...]
From: Kenneth Tilton
Subject: Re: Why the dataflow paradigm?
Date: 
Message-ID: <ktilton-41F939.19515321112004@nyctyp01-ge0.rdc-nyc.rr.com>
In article <··············@cenderis.demon.co.uk>,
 Bruce Stephens <············@cenderis.demon.co.uk> wrote:

> Kenneth Tilton <·······@nyc.rr.com> writes:
> 
> [...]
> 
> > One thing you are missing is that, for a display attribute such as
> > highlightedp, someone is always asking. The user. What good is it to
> > know that your functional highightedp would return the right answer
> > if nothing is done to force a redraw of the given widget? This is a
> > dataflow problem, including flowing all the way out to the user.
> 
> Yeah, that's what I'd guess would happen: you're using this framework
> to display stuff, so a large proportion of the results are always
> going to be required.  Indeed, I'd guess that it would be more awkward
> to do things lazily the other way around---much cleaner to let
> changing inputs propagate immediately.
> 
> Why did other systems (for example, Garnet) stress constraint
> programming so much, if Cells can get away with dataflow?  

I am afraid you have me on this one. I thought KR worked like Cells in 
that the rule was fully determinative of the slot value. When I hear 
constraints I think of partial constraints and multi-way constraints. so 
I am also not sure that I am getting away with anything they are not.

Do you mean lazy vs eager propagation? Again, i think KR is eager, but 
it has been a while since I read the doc.

> 
> I can sort of understand why you'd want constraint programming if the
> user is involved in moving things around (for example, in the window
> manager scwm, which has a constraints version that I never got to
> build).  In those sorts of systems you want to allow users to change a
> variety of different things, and compute the rest.  Is that what was
> happening in Garnet, to some extent?  

But Cells does the same thing. And Cells are considered to be 
constraints, albeit in the trivial sense since they fully determine the 
value of a slot -- no cnstraint-solving engine has to decide how to 
resolve conflicting constraints.

> 
> Why doesn't it happen in Cells, I wonder?  (Or is it just that Cells
> is basically dataflow, but it's possible to hack more general
> constrainty behaviour in the few cases where it seems necessary?)

Sure. You just have to fake it:

      :x position (c? (min (x mouse) *right-max*))

kt
From: Fred Gilham
Subject: Re: Why the dataflow paradigm?
Date: 
Message-ID: <u7pt26hai2.fsf@snapdragon.csl.sri.com>
Kenneth Tilton wrote:
> I am afraid you have me on this one. I thought KR worked like Cells
> in that the rule was fully determinative of the slot value. When I
> hear constraints I think of partial constraints and multi-way
> constraints. so I am also not sure that I am getting away with
> anything they are not.
>
> Do you mean lazy vs eager propagation? Again, i think KR is eager,
> but it has been a while since I read the doc.

I know KR uses caching, and instead of recomputing an invalid value,
an invalid marker gets stored in the cache.  Then when the value is
requested, if the cache contains an invalid marker, the formula for
the slot will get recomputed.  I think this is lazy evaluation.

-- 
Fred Gilham                                        ······@csl.sri.com
Democracy and capitalism seem to have triumphed.  But, appearances can
be deceiving.  Instead of celebrating capitalism's virtues, we offer
it grudging acceptance, contemptuous tolerance but only for its
capacity to feed the insatiable maw of socialism. We do not conclude
that socialism suffers from a fundamental and profound flaw. We
conclude instead that its ends are worthy of any sacrifice including
our freedom...                                 -- Janice Rogers Brown
From: Thomas F. Burdick
Subject: Re: Why the dataflow paradigm?
Date: 
Message-ID: <xcvwtwdlshq.fsf@conquest.OCF.Berkeley.EDU>
Kenneth Tilton <·······@nyc.rr.com> writes:

> In article <··············@cenderis.demon.co.uk>,
>  Bruce Stephens <············@cenderis.demon.co.uk> wrote:
> 
> > Kenneth Tilton <·······@nyc.rr.com> writes:
> > 
> > [...]
> > 
> > > One thing you are missing is that, for a display attribute such as
> > > highlightedp, someone is always asking. The user. What good is it to
> > > know that your functional highightedp would return the right answer
> > > if nothing is done to force a redraw of the given widget? This is a
> > > dataflow problem, including flowing all the way out to the user.
> > 
> > Yeah, that's what I'd guess would happen: you're using this framework
> > to display stuff, so a large proportion of the results are always
> > going to be required.  Indeed, I'd guess that it would be more awkward
> > to do things lazily the other way around---much cleaner to let
> > changing inputs propagate immediately.
> > 
> > Why did other systems (for example, Garnet) stress constraint
> > programming so much, if Cells can get away with dataflow?  
> 
> I am afraid you have me on this one. I thought KR worked like Cells in 
> that the rule was fully determinative of the slot value. When I hear 
> constraints I think of partial constraints and multi-way constraints. so 
> I am also not sure that I am getting away with anything they are not.
> 
> Do you mean lazy vs eager propagation? Again, i think KR is eager, but 
> it has been a while since I read the doc.

Nope, lazy.  Working with Cells has made my recollection of KR and
Garnet fuzzier, but IIRC most of the time this doesn't matter, because
events to a given window cause it to be updated.  But if you get input
from, say, a socket, you need to call UPDATE on the window, or
UPDATE-ALL to get all visible windows.
From: Bruce Stephens
Subject: Re: Why the dataflow paradigm?
Date: 
Message-ID: <87is7yqg00.fsf@cenderis.demon.co.uk>
Kenneth Tilton <·······@nyc.rr.com> writes:

> In article <··············@cenderis.demon.co.uk>,
>  Bruce Stephens <············@cenderis.demon.co.uk> wrote:

[...]

>> Why did other systems (for example, Garnet) stress constraint
>> programming so much, if Cells can get away with dataflow?  
>
> I am afraid you have me on this one. I thought KR worked like Cells in 
> that the rule was fully determinative of the slot value. When I hear 
> constraints I think of partial constraints and multi-way constraints. so 
> I am also not sure that I am getting away with anything they are not.

You're right.  Now I look at the papers
<http://www-2.cs.cmu.edu/afs/cs/project/garnet/www/papers.html> again,
it's obvious that they're doing the same kind of thing as Cells.  Even
the titles are things like "Integrating Pointer Variables into One-Way
Constraint Models" (one-way constraint is what Cells does), and
"Graphical Techniques in a Spreadsheet for Specifying User
Interfaces".

Looking at the Amulet docs, that's what Amulet does, too.

So I was entirely misunderstanding what these systems (and probably
others, like the newish Laszlo) were doing.

[...]
From: Kalle Olavi Niemitalo
Subject: Re: Why the dataflow paradigm?
Date: 
Message-ID: <87vfbxn2ax.fsf@Astalo.kon.iki.fi>
I have a feeling I'll regret posting this.

Kenneth Tilton <·······@nyc.rr.com> writes:

> One thing you are missing is that, for a display attribute such as 
> highlightedp, someone is always asking. The user. What good is it to 
> know that your functional highightedp would return the right answer if 
> nothing is done to force a redraw of the given widget? This is a 
> dataflow problem, including flowing all the way out to the user.

I wonder if a hybrid approach is possible.  The nodes (do you
call them cells?) that directly affect the user interface would
be tagged as requiring immediate updates, and they would
propagate this tag to their data providers.  Then, when a data
source changes, only the tagged direct descendants would be
updated immediately; the rest would just be marked as stale and
updated on demand.

On the other hand, even for UI objects, it would make sense to
delay updating them (and sending OpenGL display lists over the
network) until the incoming event has been fully processed.  For
example, in a text editor, replacing the selection with a paste
should not require first deleting the selection from the screen
and scrolling the following text up, and then scrolling it back
down in order to insert the paste.

For extra points, stop updating the UI objects when they are
obscured by another window.  Then the nodes on which they depend
might not have to be updated either.  Though if you don't use
many intermediate nodes that are expensive to compute, perhaps
this isn't worth the trouble.

If you make node A depend on node B (so that A is updated
whenever B changes), and then forget about A, will there still
be a reference from B that prevents collecting A as garbage?
Do you use weak references of some kind, or do you rely on
UNWIND-PROTECT to detach all nodes that are no longer needed?
From: Kenny Tilton
Subject: Re: Why the dataflow paradigm?
Date: 
Message-ID: <Bisod.18250$ld2.4154158@twister.nyc.rr.com>
Kalle Olavi Niemitalo wrote:

> I have a feeling I'll regret posting this.
> 
> Kenneth Tilton <·······@nyc.rr.com> writes:
> 
> 
>>One thing you are missing is that, for a display attribute such as 
>>highlightedp, someone is always asking. The user. What good is it to 
>>know that your functional highightedp would return the right answer if 
>>nothing is done to force a redraw of the given widget? This is a 
>>dataflow problem, including flowing all the way out to the user.
> 
> 
> I wonder if a hybrid approach is possible.

Why bother with the added complexity? And the slower performance? Which 
is what lazy does for you. The propagation stops if any dependent cell 
gets recalculated and decides not to change. But if I am not going to 
propagate immediately, I have to mark as invalid not just my immediate 
dependents butthe entire downstream (if you will) dependency graph. I 
have lost the optimization of stopping propagation when possible. Every 
cell downstream is now flagged as invalid and all there rules will get 
kicked off when they get asked.


>  The nodes (do you
> call them cells?) that directly affect the user interface would
> be tagged as requiring immediate updates, and they would
> propagate this tag to their data providers.  Then, when a data
> source changes, only the tagged direct descendants would be
> updated immediately; the rest would just be marked as stale and
> updated on demand.

Preemy op. Have you seen a dataflow set-up where eager prop was both 
slow and unnecessary? Were synapses unable to help?


> 
> On the other hand, even for UI objects, it would make sense to
> delay updating them (and sending OpenGL display lists over the
> network) until the incoming event has been fully processed.  For
> example, in a text editor, replacing the selection with a paste
> should not require first deleting the selection from the screen
> and scrolling the following text up, and then scrolling it back
> down in order to insert the paste.

That is not how GUIs work. All that happens is that each GUI element 
tells the OS "my turf needs redrawing", or a display list gets rebuilt. 
Each event propagates fully before polling for the next event (which 
would be an update event on Mac OS 9 since those were artificail events 
given top priority. So one event would have all the consequences you 
describe in the text-editing model, and all the visual elements involved 
would say "update my turf" (nothing happens except that the OS records 
the region and combines it with any others, saving them up for one 
update event), and then the event handling is over. We get the next 
(update) event and redraw those widgets overlapping the update region 
(if we take the trouble to check, which most of us do).


> 
> For extra points, stop updating the UI objects when they are
> obscured by another window.  Then the nodes on which they depend
> might not have to be updated either.  Though if you don't use
> many intermediate nodes that are expensive to compute, perhaps
> this isn't worth the trouble.

Well you do not know about other windows in the OSes I have used. But 
the main point is that there is simply no need for all this, except in 
the imagination not just of you but anyone i have ever met who hears 
"eager propagation". :) I think I could clear a room faster with that 
phrase than "fire!". :)

> 
> If you make node A depend on node B (so that A is updated
> whenever B changes), and then forget about A, will there still
> be a reference from B that prevents collecting A as garbage?
> Do you use weak references of some kind, or do you rely on
> UNWIND-PROTECT to detach all nodes that are no longer needed?

There goes the free lunch. :) I do have to have instances which are 
leaving the application model for good bow out gracefully. They also 
must come into existence gracefully, hence the two functions to-be and 
not-to-be. The good news is that the populations of my app models are 
also mediated by cells. The KIDS slot of a parent has an output callback 
which takes care of calling to-be or not-be as necessary. so to-be gets 
called once at app start-up on a root model instance, and that is that.

kt


-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Adrian Kubala
Subject: Re: Why the dataflow paradigm? [was Re: The Road to Lisp Newby Survey[was Re: Newbie seeking feedback]]
Date: 
Message-ID: <slrncqanoj.ofi.adrian@sixfingeredman.net>
Kenneth Tilton <·······@nyc.rr.com> schrieb:
> And of course GUI elements can watch the DB as well.

I'm curious, how do you get the database to tell you when something
changes? Maybe you're talking about some nifty pure-lisp database and
not a run-of-the-mill SQL one? Or maybe you catch updates in your lisp
layer and assume the db doesn't change behind your back?
From: Kenny Tilton
Subject: Re: Why the dataflow paradigm? [was Re: The Road to Lisp Newby Survey[was Re: Newbie seeking feedback]]
Date: 
Message-ID: <OYUpd.32147$Vk6.25726@twister.nyc.rr.com>
Adrian Kubala wrote:

> Kenneth Tilton <·······@nyc.rr.com> schrieb:
> 
>>And of course GUI elements can watch the DB as well.
> 
> 
> I'm curious, how do you get the database to tell you when something
> changes? Maybe you're talking about some nifty pure-lisp database and
> not a run-of-the-mill SQL one? Or maybe you catch updates in your lisp
> layer and assume the db doesn't change behind your back?

AllegroStore is a nifty Lisp wrapper of ObjectStore, which I believe is 
still the market leader in object databases. Native language C++.

AllegroStore use the MOP to create a near-transparent persistent CLOS 
DB. So for all intents and purposes it may as well be a pure lisp DB. 
Maybe it was! I never had to mess with ObjectStore, and believe you me I 
/really/ did my level best to hose the thing. This, btw, is a real 
tribute to Lisp and Franz, because I learned subsequently that 
ObjectStore is a monstrosity to work with directly, though its 
fundamental quality and performance once gotten working are industry 
best. I am talking more here about the painlessness of working with 
AllegroStore and how Lisp & Franz managed to isolate me from the 
apparent nightmare of ObjectStore DB programming and maintenance.

To make a long story short, my persistent classes had a metaclass which 
multiply-inherited from AllegroStore and Cell metaclasses (when Cells 
was metaclass-implemented). Then I specialized slot-value-using-class 
and shared-initialize with methods to trigger dataflow off slot changes 
and DB writes (I forget what it was, but deletes got caught somehaow as 
well). This was done generally, so a one-time "glue" effort of a week or 
two served for all classes.

If I had to do it for SQL I would start by grabbing someone's CLOS 
wrapper for it, or roll my own. Then hooks to drive the dataflow would 
be easy, too. I might even just do a MOP thing myself and use the same glue.

kenny


-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Pascal Bourguignon
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <87k6sijubc.fsf@thalassa.informatimago.com>
drewc <·····@rift.com> writes:
> > You seem to have strong grounding in the current pop star
> > languages. that gives you credibility -- I merely saw that O'Reilly
> > published books about them and knew they sucked.
> 
> lol .. and i used to think that having an 'Animal Book' was a good-thing.

Having an "Animal Book" only means that you haven't a Lisp Book.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The world will now reboot; don't bother saving your artefacts.
From: Mark McConnell
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <d3aed052.0411191559.789db461@posting.google.com>
Pascal Bourguignon <····@mouse-potato.com> wrote in message news:<··············@thalassa.informatimago.com>...
> drewc <·····@rift.com> writes:
> > > You seem to have strong grounding in the current pop star
> > > languages. that gives you credibility -- I merely saw that O'Reilly
> > > published books about them and knew they sucked.
> > 
> > lol .. and i used to think that having an 'Animal Book' was a good-thing.
> 
> Having an "Animal Book" only means that you haven't a Lisp Book.

This week I wrote Lisp code (Linj code, actually) to convert data into
an SVG map.  O'Reilly's SVG book, with a peacock thing [no, reach for
shelf, look it up] great argus pheasant on the cover, has been my
faithful companion.  As has the Hyperspec, for code like
(format s "#~2,0X~2,0X~2,0X" (red c) (green c) (blue c))
From: Adam Warner
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <pan.2004.11.20.09.27.26.330594@consulting.net.nz>
Hi Mark McConnell,

> This week I wrote Lisp code (Linj code, actually) to convert data into
> an SVG map.  O'Reilly's SVG book, with a peacock thing [no, reach for
> shelf, look it up] great argus pheasant on the cover, has been my
> faithful companion.  As has the Hyperspec, for code like
> (format s "#~2,0X~2,0X~2,0X" (red c) (green c) (blue c))

It's a tricky point but your FORMAT string is non-standard. The correct
string is "#~2,'0X~2,'0X~2,'0X" (i.e. you have to quote the pad
character).

Regards,
Adam
From: Mark McConnell
Subject: Re: The Road to Lisp Newby Survey [was Re: Newbie seeking feedback]
Date: 
Message-ID: <d3aed052.0411221552.11b06038@posting.google.com>
Adam Warner <······@consulting.net.nz> wrote in message news:<······························@consulting.net.nz>...
> Hi Mark McConnell,
> 
> > This week I wrote Lisp code (Linj code, actually) to convert data into
> > an SVG map.  O'Reilly's SVG book, with a peacock thing [no, reach for
> > shelf, look it up] great argus pheasant on the cover, has been my
> > faithful companion.  As has the Hyperspec, for code like
> > (format s "#~2,0X~2,0X~2,0X" (red c) (green c) (blue c))
> 
> It's a tricky point but your FORMAT string is non-standard. The correct
> string is "#~2,'0X~2,'0X~2,'0X" (i.e. you have to quote the pad
> character).

Ouch, you're right.  The version without the quoting fails on both
Allegro and CLisp.
From: Bulent Murtezaoglu
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <873bz7e35w.fsf@p4.internal>
>>>>> "KT" == Kenneth Tilton <·······@nyc.rr.com> writes:
    KT> In article <·····················@news.demon.co.uk>,
    KT>  "Glen Able" <·········@gmail.com> wrote:
[...]
    >> Maybe I've just been spoilt by years of VC++, or maybe this
    >> stuff's not really important? [...]

It is important.  Unlike Kenny I detest VC++ (tho my usage is stuck at
6.0), I don't think I am alone in this among emacs users.  If you try
emacs and tell us what bits you are missing perhaps we can tell you
how/where to get them.  For starters, syntax highting and unlimited
undo are available out-of-box in emacs.  Learning emacs is a good
investment if you'll keep going.

[...]
    KT> ... Note that you still have to say (setf list (delete...)) 
    KT> in case the first item gets deleted. [...]

Not so. (the advice is OK, the reason is wrong).  

"delete, when sequence is a list, is permitted to setf any part, car
or cdr, of the top-level list structure in that sequence."

http://www.lispworks.com/reference/HyperSpec/Body/f_rm_rm.htm

So delete can change the top level of the list any way it wishes and it 
is not guaranteed to change it the way you'd expect.  (as KT says, I 
expect the savages to correct me if I am reading it wrong).

Perhaps you could try to figure out why KT was talking about the first
element anyway.  Understanding that is important.  (and trying
understand that on a vague hint like this might cause, um, collateral
learning.)

cheers,

BM
From: Kenny Tilton
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <xU0nd.7983$Yh2.2320112@twister.nyc.rr.com>
Bulent Murtezaoglu wrote:

>>>>>>"KT" == Kenneth Tilton <·······@nyc.rr.com> writes:
> 
> [...]
>     KT> ... Note that you still have to say (setf list (delete...)) 
>     KT> in case the first item gets deleted. [...]
> 
> Not so. (the advice is OK, the reason is wrong).  
> 
> "delete, when sequence is a list, is permitted to setf any part, car
> or cdr, of the top-level list structure in that sequence."
> 
> http://www.lispworks.com/reference/HyperSpec/Body/f_rm_rm.htm
> 
> So delete can change the top level of the list any way it wishes and it 
> is not guaranteed to change it the way you'd expect.  (as KT says, I 
> expect the savages to correct me if I am reading it wrong).

<savage> My point is that one thing (delete x y) will /not/ do is 
re-bind y in the event the cons cell to which y is bound (aka, the first 
cons cell in the list), happens to hold x in its car. </savage>

:)

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Bulent Murtezaoglu
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <87r7mrcms4.fsf@p4.internal>
>>>>> "KT" == Kenny Tilton <·······@nyc.rr.com> writes:
[...]
    KT> <savage> My point is that one thing (delete x y) will /not/ do
    KT> is re-bind y in the event the cons cell to which y is bound
    KT> (aka, the first cons cell in the list), happens to hold x in
    KT> its car. </savage>

Thus you savagely destroy my little tutorial question.  Grrr.  The point 
was: you cannot count on delete modifying its argument in the way you 
expect so you should always use the return value regardless of any 
binding, first cons etc. concerns you may have.  

(and shame on you for using broken syntax mark-up)

cheers,

BM
From: Kenny Tilton
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <xB1nd.7987$Yh2.2334701@twister.nyc.rr.com>
Bulent Murtezaoglu wrote:

>>>>>>"KT" == Kenny Tilton <·······@nyc.rr.com> writes:
> 
> [...]
>     KT> <savage> My point is that one thing (delete x y) will /not/ do
>     KT> is re-bind y in the event the cons cell to which y is bound
>     KT> (aka, the first cons cell in the list), happens to hold x in
>     KT> its car. </savage>
> 
> Thus you savagely destroy my little tutorial question.  Grrr.

Doh! But, hey, what was wrong with my set up? I savagely left the OP 
wondering, what is wrong with the first item being deleted? Except I was 
not being as vicious as I might have: he had demonstrated enough mastery 
that i knew he would stare at it and figure it out on his own. Had he 
not, I would not have set such a monstrous trap.

:)

kenny

> (and shame on you for using broken syntax mark-up)

forgive me. I am an old dawg, this newfangled HTML is too new a trick.

k

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Edi Weitz
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <u6543eb4m.fsf@agharta.de>
On Thu, 18 Nov 2004 08:48:03 -0000, "Glen Able" <·········@gmail.com> wrote:

> I'm finding myself with the time and energy to have another crack at
> learning lisp, after a few abortive attempts.  So I'm using the
> Allegro trial.  I'm finding it ok to work with, but the IDE seems a
> little primitive, especially the source editor - limited undo, no
> syntax highlighting etc.  Do you Allegro users use this, or work in
> another third-party editor?  Maybe I've just been spoilt by years of
> VC++, or maybe this stuff's not really important?

I guess most serious AllegroCL developers use Emacs/ELI which is fully
supported by Franz Inc.:

  <http://www.franz.com/support/documentation/6.2/doc/eli.htm>

You might also want to give SLIME a try - a similar solution which is
portable to other Lisp implementations:

  <http://common-lisp.net/project/slime/>

See also:

  <http://cl-cookbook.sourceforge.net/emacs-ide.html>
  <http://cl-cookbook.sourceforge.net/windows.html>

These two introductory articles were written before SLIME existed but
they should give you a good general overview of Emacs-based IDEs for
Common Lisp.

If you've never used Emacs before the learning curve is quite steep
but it's worth it. You can do very cool things with IDEs like ELI or
SLIME that make Visual Studio pale in comparison. (You won't get as
much eye-candy, though.)

Cheers,
Edi.
From: Mark McConnell
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <d3aed052.0411190640.6807a345@posting.google.com>
Edi Weitz <········@agharta.de> wrote in message news:<·············@agharta.de>...
> If you've never used Emacs before the learning curve is quite steep
> but it's worth it.
IMO the learning curve is not so bad.  Open an Emacs and type
ctrl-h t
for a tutorial.
From: Fred Gilham
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <u7d5ybj7st.fsf@snapdragon.csl.sri.com>
> Here's my code - I'd greatly welcome any constructive criticism.

A very nice program!  If you add

(declare (optimize (speed 3) (safety 1)))

at the beginning it seems like it runs significantly faster (at least
in CMU Lisp).  Do this after debugging because it will probably make a
lot of debugging information go away.

By the way, when you write

(defun solve() ....

it makes it look like you're still thinking in C or C++, because
you're treating the argument list syntactically.  It really is a list.
Some people even write

(defun solve nil ...

to indicate that a function takes no arguments.  (I don't do that
because it looks funky, but it is valid.)

It's just nitpicking but it stands out when reading the code.

-- 
Fred Gilham                                  ······@csl.sri.com
The density of a textbook must be inversely proportional to the
density of the students using it. --- Dave Stringer-Calvert
From: Fred Gilham
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <u7pt2b0vxb.fsf@snapdragon.csl.sri.com>
OK, one more point.  I tried changing all the "remove" calls to
"delete" calls.  It didn't work.  Then I noticed the following:

(defun continue-fill-grid (grid position)
  (let ((possible '(1 2 3 4 5 6 7 8 9)))
    (setf possible (remove-used-row grid position possible))
    (setf possible (remove-used-col grid position possible))
    (setf possible (remove-used-block grid position possible))
    (if possible
        (dolist (fill-val possible)
          (let ((new-grid (copy-grid grid)))
            (setf
             (aref new-grid (car position) (cadr position))
             fill-val)
            (fill-grid new-grid))))))



The (let ((possible '(1 2 3 4 5 6 7 8 9)))
       ...

line is a problem because '(1 2 3 4 5 6 7 8 9) is constant structure.
So to use the "delete" calls you have to change it to

(list 1 2 3 4 5 6 7 8 9).

Kinda fooled me because you can change the remove calls in
remove-used-col and remove-used-block and things still work.  But
that's because the remove call in remove-used-row creates a new list
with mutable list structure.

As far as whitespace and similar issues go, I must compliment you on
not using camel-case. :-)

-- 
Fred Gilham                                        ······@csl.sri.com
Our original rights freed us from the state's power. Nowadays, most
alleged "rights" increase the state's power over us. -- Joseph Sobran
From: Kenneth Tilton
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <ktilton-30E6F3.15173418112004@nyctyp02-ge0.rdc-nyc.rr.com>
In article <··············@snapdragon.csl.sri.com>,
 Fred Gilham <······@snapdragon.csl.sri.com> wrote:


> As far as whitespace and similar issues go, I must compliment you on
> not using camel-case. :-)

Wait! is there any place he used recursion where he could have 
iterated?!! I think he used "list" for listy arguments... we should come 
up with a list of inconsequential things which make us savages snap like 
twigs. "LISP", parens on their own lines, "lst", studlyCaps...

:)

kt
From: Glen Able
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <cnj316$mup$1@news6.svr.pol.co.uk>
"Fred Gilham" <······@snapdragon.csl.sri.com> wrote in message
···················@snapdragon.csl.sri.com...
>
> OK, one more point.  I tried changing all the "remove" calls to
> "delete" calls.  It didn't work.  Then I noticed the following:

> The (let ((possible '(1 2 3 4 5 6 7 8 9)))
>        ...
> line is a problem because '(1 2 3 4 5 6 7 8 9) is constant structure.
> So to use the "delete" calls you have to change it to
>
> (list 1 2 3 4 5 6 7 8 9).
>
> Kinda fooled me because you can change the remove calls in
> remove-used-col and remove-used-block and things still work.  But
> that's because the remove call in remove-used-row creates a new list
> with mutable list structure.

Ahhh, I was just struggling with this - thanks!  But what actually happens,
or fails to happen when you use 'delete' on a constant list?

> As far as whitespace and similar issues go, I must compliment you on
> not using camel-case. :-)

I use camel-case routinely in C++, of course, but I'm glad to abandon it
because I'm sure all the stretching while SHIFTing is damaging my hands.
That said, I like the convention of 'FunctionName' and 'variableName'
because, along with syntax highlighting, it makes it less of a strain to
mentally parse code.

I also appreciate your point about the parens in
(defun solve() ....  I shall use 'nil' until the point is driven home.

cheers,
G.A.
From: Peter Seibel
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <m3zn1ec0ix.fsf@javamonkey.com>
"Glen Able" <·········@gmail.com> writes:

> Ahhh, I was just struggling with this - thanks! But what actually
> happens, or fails to happen when you use 'delete' on a constant
> list?

Undefined behavior. I.e. nasal demons, etc. But in practice one thing
that may happen is the literal constant (i.e. part of the code) will
be destrucively modified and your code will never work the same again.

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kalle Olavi Niemitalo
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <87pt29g0pj.fsf@Astalo.kon.iki.fi>
"Glen Able" <·········@gmail.com> writes:

> I also appreciate your point about the parens in
> (defun solve() ....  I shall use 'nil' until the point is driven home.

I don't think one should write the empty lambda list as "nil".
From: Pascal Bourguignon
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <871xepk5oj.fsf@thalassa.informatimago.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> "Glen Able" <·········@gmail.com> writes:
> 
> > I also appreciate your point about the parens in
> > (defun solve() ....  I shall use 'nil' until the point is driven home.
> 
> I don't think one should write the empty lambda list as "nil".

COMMON-LISP:NIL, 'COMMON-LISP:NIL, () and '() are all the same (EQ) in
Common-Lisp.

But one can overload some nuances:

    COMMON-LISP:NIL     false.
    'COMMON-LISP:NIL    the symbol NIL.
    ()                  an empty list (of arguments) (in program).
    '()                 the empty list               (as data).

However, merely: NIL 
may be ambiguous. 
It could be in a package where COMMON-LISP:NIL has been shadowed.  


(defpackage "RIVIERES"
    (:shaddow "NIL")
    (:export "NIL" "SEINE" "MISSISSIPI"))
(in-package "RIVIERES")
(defparameter NIL        (make-instance 'riviere :continent "Afrique"))
(defparameter SEINE      (make-instance 'riviere :continent "Europe"))
(defparameter MISSISSIPI (make-instance 'riviere :continent "Am�rique du Nord"))


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The world will now reboot; don't bother saving your artefacts.
From: Kalle Olavi Niemitalo
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <87llcxo5ja.fsf@Astalo.kon.iki.fi>
Pascal Bourguignon <····@mouse-potato.com> writes:

> Kalle Olavi Niemitalo <···@iki.fi> writes:
>
>> I don't think one should write the empty lambda list as "nil".
>
> COMMON-LISP:NIL, 'COMMON-LISP:NIL, () and '() are all the same (EQ) in
> Common-Lisp.

Sure, it will work.  But I think it'd be bad style.
From: Coby Beck
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <ccMnd.173580$df2.12411@edtnps89>
"Pascal Bourguignon" <····@mouse-potato.com> wrote in message 
···················@thalassa.informatimago.com...
> Kalle Olavi Niemitalo <···@iki.fi> writes:
>
>> "Glen Able" <·········@gmail.com> writes:
>>
>> > I also appreciate your point about the parens in
>> > (defun solve() ....  I shall use 'nil' until the point is driven home.
>>
>> I don't think one should write the empty lambda list as "nil".
>
> COMMON-LISP:NIL, 'COMMON-LISP:NIL, () and '() are all the same (EQ) in
> Common-Lisp.

Of course they are, but that is orthagonal to questions of style and 
convention.  I have never read or written code that has (defun foo nil ...) 
or (lambda nil ...) and Kalle is right that one should not do that.

Also shadowing CL:NIL seems like another very bad idea.

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Glen Able
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <cnkbq9$s81$1$8302bc10@news.demon.co.uk>
"Fred Gilham" <······@snapdragon.csl.sri.com> wrote in message
···················@snapdragon.csl.sri.com...
>

The sequence of setf's here seems a bit clunky

> (defun continue-fill-grid (grid position)
>   (let ((possible '(1 2 3 4 5 6 7 8 9)))
>     (setf possible (remove-used-row grid position possible))
>     (setf possible (remove-used-col grid position possible))
>     (setf possible (remove-used-block grid position possible))
>     (if possible...


Does this look more idiomatic?


(defun continue-fill-grid(grid position)
  (let ((possible (remove-used-block
                   grid
                   position
                   (remove-used-col
                    grid
                    position
                    (remove-used-row
                     grid
                     position
                     (list 1 2 3 4 5 6 7 8 9))))))
    (if possible...
From: Kenny Tilton
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <u5mnd.18248$Vk6.4482@twister.nyc.rr.com>
Glen Able wrote:

> "Fred Gilham" <······@snapdragon.csl.sri.com> wrote in message
> ···················@snapdragon.csl.sri.com...
> 
> 
> The sequence of setf's here seems a bit clunky
> 
> 
>>(defun continue-fill-grid (grid position)
>>  (let ((possible '(1 2 3 4 5 6 7 8 9)))
>>    (setf possible (remove-used-row grid position possible))
>>    (setf possible (remove-used-col grid position possible))
>>    (setf possible (remove-used-block grid position possible))
>>    (if possible...
> 
> 
> 
> Does this look more idiomatic?
> 
> 
> (defun continue-fill-grid(grid position)
>   (let ((possible (remove-used-block
>                    grid
>                    position
>                    (remove-used-col
>                     grid
>                     position
>                     (remove-used-row
>                      grid
>                      position
>                      (list 1 2 3 4 5 6 7 8 9))))))

Good having that imperative sequence out of there, but there is still 
that repeated pattern of (<fn> grid position <list>). But code is data, 
so how about (untested)?:

    (let ((p (list ...)))
       (loop for fn in '(remove-used-row
                         remove-used-col
                         remove-used-block)
             do (setf p (funcall fn grid position p)))

Or since its a pattern thang (untested):

    (macrolet ((chopf (fn)
                 `(setf possible (,fn grid position possible))))
       (let ((possible (list...)))
           (chopf remove-used-row)
           (chopf remove-used-col)
           (chopf remove-used-block)
           ...

or (I never test):

    (macrolet ((impossiblef (fns)
                 `(progn
                     ,@(mapcar (lambda (fn)
                               `(setf possible
                                 (,fn grid position possible)))
                          fns))))
       (let ((possible (list...)))
          (impossiblef remove-used-row
                       remove-used-col
                       remove-used-block)

Ick. :)

kenny


-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Kenneth Tilton
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <ktilton-AEAF92.14500118112004@nycmny-nntp-rdr-03-ge0.rdc-nyc.rr.com>
In article <··············@snapdragon.csl.sri.com>,
 Fred Gilham <······@snapdragon.csl.sri.com> wrote:

> > Here's my code - I'd greatly welcome any constructive criticism.
> 
> A very nice program!  If you add
> 
> (declare (optimize (speed 3) (safety 1)))
> 
> at the beginning it seems like it runs significantly faster (at least
> in CMU Lisp).  Do this after debugging because it will probably make a
> lot of debugging information go away.
> 
> By the way, when you write
> 
> (defun solve() ....
> 
> it makes it look like you're still thinking in C or C++, 

Fascinating. Possibly the first time someone on Usenet has been spanked 
for not having enough whitespace. I told ya...

..the Savages of comp.lang.lisp. (Let's get a team photo at ILC 2005.)

:)

kenny
From: Emre Sevinc
Subject: Re: Newbie seeking feedback
Date: 
Message-ID: <87y8gztsce.fsf@bilgi.edu.tr>
"Glen Able" <·········@gmail.com> writes:

> I'm finding myself with the time and energy to have another crack at
> learning lisp, after a few abortive attempts.  So I'm using the Allegro
> trial.  I'm finding it ok to work with, but the IDE seems a little
> primitive, especially the source editor - limited undo, no syntax
> highlighting etc.  Do you Allegro users use this, or work in another
> third-party editor?  Maybe I've just been spoilt by years of VC++, or maybe
> this stuff's not really important?

I'm a Lisp newbie, too. I've never tried the Allegro
edition and my Lisp environment is GNU Emacs and SLIME.
The environment in which I work Lisp provides syntax
highlighting, keyword (and previously written variables, etc.)
completion, parens matching, parens completion, many levels
of undo. In addition to that full documentation is integrated. 
I can reach help in Emacs which uses HyperSpec and CLtL. Except
the full documentation, whenever I write a Lisp function the
status line automatically (or should I say automagically ;-)
provides simple definition and signature for it which is
very adequate. All of this and much more comes without 
a price tag and doesn't consume more than a few MB on my disk. 

I'm at the same time a professional ASP and SQL Server developer
and we had plans to switch to .NET and the last time I looked
at Visual Studio.NET it was on a DVD set which sent shivers
down my spine.

By the way, my Lisp environment is on Debian GNU/Linux
and it seems that Debian GNU/Linux (or any other UNIX compatible OS)
provides a very natural, consistent and helpful interface
for Lisp programming. 

If you're in MS Windows environment maybe you can try XEmacs
and SLIME to get a feel for it.

Happy hacking,

-- 
Emre Sevinc

eMBA Software Developer         Actively engaged in:
http:www.bilgi.edu.tr           http://ileriseviye.org
http://www.bilgi.edu.tr         http://fazlamesai.net
Cognitive Science Student       http://cazci.com
http://www.cogsci.boun.edu.tr