From: Alexander Burger
Subject: A Succinctness Challenge
Date: 
Message-ID: <2hrjv4FgfiehU1@uni-berlin.de>
There are endless discussions about the best and most powerful
progrmming environment. The subject is mostly a matter of taste, and can
usually not be measured in absolute terms. But perhaps is it possible in
some certain, well-defined fields?

According to Paul Graham, the power of a programming language is equal
to its succinctness (see "http://www.paulgraham.com/power.html"). I
agree with him, and extend his postulate from languages to application
development environments in general.

I'm spending most of my time writing the database-and-GUI kind of
business applications. So this is the field where I'm personally
interested in, and which is sufficiently large and specialized in its
requirements to be also of general interest. I'm using Pico Lisp for
that, having built an application server framework on top of it with
quite high succinctness and abstractions for this type of applications.

I don't doubt that other people have tried to solve these problems before, so
there should be other environments with equal or higher succinctness (and thus
programming power). To make the systems somehow comparable, I specified a very
simple application with certain typical features, and posted it as a challenge
to the Lisp community:

   http://software-lab.de/succinctness.html

There is a specification, a complete solution (in Pico Lisp), and a link
to a life test setup.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090

From: Christopher C. Stacy
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <un03r47bb.fsf@news.dtpq.com>
>>>>> On 29 May 2004 14:10:46 GMT, Alexander Burger ("Alexander") writes:
 Alexander> According to Paul Graham, the power of a programming
 Alexander> language is equal to its succinctness.
 Alexander> I agree with him

I think programming languages are more about "expressiveness",
of which "succinctness" is just one aspect.  This all just sounds
to me like an opportunity to argue over the meaning of words.

>>>>> On 29 May 2004 14:10:46 GMT, Alexander Burger ("Alexander") writes:

 Alexander> There are endless discussions about the best and most
 Alexander> powerful progrmming environment.

I thought this was settled 20 years ago and the answer was "Genera".
(The MIT-cum-Symbolics crowd had plenty of discussions and ideas about
relatively radical new places to move forward from there, but the world
wasn't even ready for Genera, yet, so those were never realized.)

 Alexander> But perhaps is it possible in some certain, well-defined fields?

Generally, people will construct a problem that suits 
the answer they wanted.

For example, I think most people would even agree that SQL 
is the best language for manipulating SQL databases as such.

APL is a very concise and beautiful language for expressing 
many kinds of problems.

If you're talking about programming environments, I think 
you'll find that it's fairly religous.   Might as well ask
what the "best" editor is.

And we all know the answer is ZMACS/ZWEI, so don't kid yourself.

:)
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2hrnacFfsf5tU1@uni-berlin.de>
Christopher C. Stacy <······@news.dtpq.com> wrote:
> Generally, people will construct a problem that suits 
> the answer they wanted.

No, I have this type of problem permanently, and I'm sure that other
people have it, too.


> For example, I think most people would even agree that SQL 
> is the best language for manipulating SQL databases as such.

But how succinct are the resulting programs?

I don't want to start a philosophical debate, but simply see hard facts.
A short and succinct solution. Is that so difficult?


> And we all know the answer is ZMACS/ZWEI, so don't kid yourself.

> :)

Maybe 42 ? ;-)

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: David Steuber
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <87isedkgu5.fsf@david-steuber.com>
Alexander Burger <···@software-lab.de> writes:

> Christopher C. Stacy <······@news.dtpq.com> wrote:
> > Generally, people will construct a problem that suits 
> > the answer they wanted.
> 
> No, I have this type of problem permanently, and I'm sure that other
> people have it, too.

Perhaps you should see another doctor.  There has to be a cure!

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Marco Baringer
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <m2d64mi2z6.fsf@bese.it>
Alexander Burger <···@software-lab.de> writes:

> But how succinct are the resulting programs?

by definiton they can't be as succint as the apps you write with a
framework designed for writing your apps :). of course, your framework
imposes one kind of mindset, ucw imposes another, certain apps are
easier with your framework, certain apps are easier with ucw,the real
question we should be asking is "how much should a framework impose?"
ucw tends to do only the web/frow-contral stuff and leave everytihng
else to the programmer, i honestly don't know where the line should
lie.

anyway, here's a ucw version of your program.

Notes:

0) the db is in RAM. UCW doesn't impose a particular db setup, so i'll
   just use the simplest one i can think of. Redfining the accessors
   for the person class should be easy enough should someone want to
   add a "proper" DBMS in here.

1) I've left out the date manipulation code, it's currently broken.

2) The view tables are written out by hand only because i haven't
   decided which abstraction i want for auto generating data views,
   not because i don't want it. (well, that's my excuse at least :)).

3) i've not implemented the propagation of sex changes from one person
   to their childern's parents, it's fairly trivial, rather boring,
   and adds nothing to this example.

4) there's more or less no explicit validation when creating a new
   user since this app never asks you for textual input but only
   allows you to chose from a list of valid possibilites. this choice
   would have to be revisited if the db becomes large.

5) This a 40 minute hack which may or may not even work, i just hope
   it's enough to give you an idea of what the ucw API is like.

The app initally presents the user with a listing of all the people in
the db (and a "create new user" button), navigating the app is done by
clicking on the names of the current person's spouses, parents or
children. the "search for person by name" button doesn't exist.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(in-package :it.bese.ucw-user)

(defclass people-app (standard-application)
  ((people :accessor people :initform (make-hash-table :test 'equal))))

(defapplication *people-db*
  (:url-prefix "/ucw/people/")
  (:clase people-app))

(defclass person ()
  ((name :accessor person.name :initarg :name :initform (gensym))
   (sex  :accessor person.sex  :initarg :sex  :initform :unknown)
   (mother :accessor person.mother :initarg :mother :initform nil)
   (father :accessor person.father :initarg :father :initform nil)
   (children :accessor person.children :initarg :children :initform nil)
   (spouses :accessor person.spouses :initarg :spouses :initform nil)))

;;; init the db

(let ((adam (make-instance 'person :name "Adam"
                                   :sex :male
                                   :birthdate (cl-icu:make-date 0)))
      (eve (make-instance 'person :name "Eve"
                                  :sex :female
                                  :birthdate (cl-icu:make-date 0))))
  (push adam (person.spouses eve))
  (push eve (person.spouses adam))
  (setf (gethash "Adam" (people *people-db*) adam
        (gethash "Eve" (people *people-db*) eve))))

;;;; viewing, editing and navigating an individual

(defcomponent person-viewer (standard-component)
  ((person :accessor person :initform nil :initarg :person)))

(defaction view ((p person))
  (call (make-instance 'person-viewer :person p)))

(defaction change-name ((p person))
  (let ((new-name (call 'string-choser
                        :message "New name:"
                        :validate (lambda (name)
                                    (not (gethash name (people *people-db*))))
                        :error-message "Sorry, the name ~S is taken.")))
    (remhash (person.name p) (people *people-db*))
    (setf (person.name p) new-name
          (gethash new-name (person.name *people-db*)) p))
  p)

(defaction change-sex ((p person))
  (setf (person.sex p) (call 'option-dialog
                             :message "New sex?"
                             :options '((:male . "Male") (:female . "Female"))
                             :confirm nil))
  (case (call 'option-dialog
              :message "What should we do about ~S's child's fathers?"
              :options '((:leave . "Leave the DB in an invalid state.")
                         (:update . "Change the other parent's sex and swap mother and father.")))
    (:leave
     ;; just return the person
     t)
    (:update ;;update the entire db
     (dolist (c (person.children p))
       (case (person.sex p)
         ;; person has changed from male to female, need to change the
         ;; mother's sex and update all of the mother's children.
         (:female ...)
         ;; person has changed from female to male, need to change the
         ;; father's sex and update all of the father's children.
         (:male ...)))))
  p)

(defaction chose-or-make-person ((subject person) message &key (test #'identity))
  (or (call 'option-dialog
            :message message
            :options (list*
                      (cons nil "Make a new person.")
                      (loop
                         for person being the hash-values of (people *people-db*)
                         when (funcall test person)
                           collect person)))
      (call 'new-person :person (make-instance 'person) :test test)))

(defaction change-mother ((p person))
  (let ((new-mother (chose-or-make-person p "Who should be the new mother?"
                                          :test (lambda (possible-mother)
                                                  (eql :female (person.sex possible-mother))))))
    (setf (person.mother p) new-mother)
    (unless (find p (person.children new-mother))
      (push p (person.children new-mother)))
    p))

(defaction change-father ((p person))
  (let ((new-father (chose-or-make-person p "Who should be the new father?"
                                          :test (lambda (possible-mother)
                                                  (eql :male (person.sex possible-mother))))))
    (setf (person.father p) new-father)
    (unless (find p (person.children new-father))
      (push p (person.children new-father)))
    p))

(defaction add-spouse ((p person))
  (let ((new-spouse (chose-or-make-person p "Who should be the now spouse?"
                                          :test (lambda (possible-spouse)
                                                  ;; assume a conservative country
                                                  (not (eql (person.sex possible-spouse)
                                                            (person.sex p)))))))
    (push new-spouse (person.spouses p))
    (unless (find p (person.spouses p))
      (push p (person.spouses new-spouse))))
  p)

(defaction add-childer ((p person))
  (let ((new-child (chose-or-make-person p "new child?")))
    (push new-child (person.children p))
    (ecase (person.sex p)
      (:male (setf (father new-child) p))
      (:female (setf (mother new-child) p)))
    p))

(defaction delete-child ((p person) (child person))
  (setf (person.children p) (delete child (person.children p)))
  ;; must chose a new mother-father for child
  (if (eql p (person.mother child))
      (setf (person.mother child)
            (chose-or-make-person p (format nil "New mother for ~S?"
                                                (person.name child))))
      (setf (person.father child)
            (chose-or-make-person p (format nil "New father for ~S?"
                                                (person.name child)))))
  p)

(defaction delete-spouse ((p person) (spouse person))
  (setf (person.spouses p) (delete spouse (person.spouses p)))
  (setf (person.spouses spouse) (delete p (person.spouses spouse)))
  p)

(defmethod render-on ((res response) (v person-viewer))
  (with-slots (name sex birthdate mother father children spouses)
      (person v)
    ;; yes, this mess should be class->table macro, 
    (<:table
     (<:tr (<:td "Name:") (<:td (<:as-html name)
                                (<ucw:a (lambda () (change-name (person v)))
                                        "Change Name.")))
     (<:tr (<:td "Sex:") (<:td (<:as-html sex)
                               (<ucw:a (lambda () (change-sex (person v))) 
                                       "Change Sex.")))
     (<:tr (<:td "Mother:") (<:td (<ucw:a (lambda () (view mother))
                                          (<:as-html (person.name mother)))
                                  (<ucw:a (lambda () (change-mother (person v)))
                                          "Change Mother.")))
     (<:tr (<:td "Father:") (<:td (<ucw:a (lambda () (view father))
                                          (<:as-html (person.name father)))
                                  (<ucw:a (lambda () (change-father (person v)))
                                          "Change Father.")))
     (<:tr (<:td "Children:")
           (<:td
            (<:ul
             (dolist (c children)
               (<:li (<ucw:a (lambda () (view c)) (<:as-html (person.name c)))
                     (<ucw:a (lambda () (delet-child (person v) c)) "Delete.")))
             (<ucw:a (lambda () (add-child (person v))) "Add a child."))))
     (<:tr (<:td "Spouses:")
           (<:td
            (<:ul
             (dolist (s spouses)
               (<:li (<ucw:a (lambda () (view s)) (<:as-html (person.name s)))
                     (<ucw:a (lambda () (delete-spouse (person v) s)) "Delete."))))
            (<ucw:a (lambda () (add-spouse (person v))) "Add a spouse."))))
    (<ucw:a (lambda () (make-new-person (make-instance 'new-person :person (make-instance 'person))))
            "Create a new person.")
    (<ucw:a (lambda () (answer-component v (person v))) "Ok.")))

;;; creating new people

(defcomponent new-person (person-viewer)
  ((test :accessor test :initform (lambda (v) (declare (ignore v)) t) :initarg :test)))

(defmethod render-on :after ((r response) (p new-person))
  ;; just add a cancel button
  (<ucw:a (lambda () (answer-component p nil)) "Cancel."))

(defaction make-new-person ((default new-person))
  (loop
     for p = (view default)
     do (cond
          ((null p) ;; cancel 
           (return-from make-new-person nil))
          ((gethash (person.name new-person) (people *people-db*))
           (call 'info-message 
                 :message (format nil "Sorry, the name ~S already exists."
                                      (person.name new-person))))
          ((null (funcall (test default) p))
           (call 'info-message 
                 :message (format nil "Sorry, the person did not pass the extra validation.")))
          (t ;; ok, save the person.
           (setf (gethash (person.name new-person) new-person))
           (return-from make-new-person new-person)))))

;;;; the "main window" component

(defcomponent person-window (standard-component)
  ((body :accessor body :initform nil)
   (title :accessor title :initform "The People App" :backtrack t)))

(defmethod render-on ((res response) (w person-window))
  (<:html
   (<:head (<:title (<:as-html (title w))))
   (<:body
    (render-on (body w))
    (<ucw:a (lambda () (make-new-person (make-instance 'new-person)))
            "New person."))))

;;; the main entry point

(defentry-point "index.ucw" () ()
  (goto (make-instance 'person-window))
  (setf (component.place self) (make-place (body self)))
  (loop
     (call 'range-view :data (maphash (lambda (k v)
                                        (declare (ignore k))
                                        v)
                                      (people *people-db*))
                       :item-render-method (lambda (p)
                                             (<:as-html (person.name p))))))

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2hu8d6Fh7lheU1@uni-berlin.de>
Marco, thank you very much for going through the trouble to write a
solution. If you permit, I'll put your article on my page as the first
member of reader-conctributed solutions.

Marco Baringer <··@bese.it> wrote:
> framework designed for writing your apps :). of course, your framework
> imposes one kind of mindset, ucw imposes another, certain apps are
> easier with your framework, certain apps are easier with ucw,the real

You are right, concerning the GUI framework.

I didn't know ucw, but it seems to be a web development package. Then
it does not really access the type if (interactive) applications I
need for my projects, but covers mainly the HTTP/HTML part, right? But
this is Ok, as you said, if we settle on certain types of apps.


> ucw tends to do only the web/frow-contral stuff and leave everytihng
> else to the programmer, i honestly don't know where the line should

If I understand your code correctly, you implemented the management of
object-relations on-the-fly.

So now it would be interesting to separate the parts which implement a
general API (the "abstractions") from those which a special for the
demo application (the "elaborations") to see the resulting
succinctness.

Explanation: In my usual work I have to write such applications
permanently, and then there are much more complicated relations than
in the given spec, between tens or hundreds of classes, so we cannot
code these things explicitly each time.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: David Golden
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <o75uc.868$Z14.962@news.indigo.ie>
Christopher C. Stacy wrote:

> For example, I think most people would even agree that SQL
> is the best language for manipulating SQL databases as such.
 

Yeah, but it sure sucks for relational database work ;-)
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2htgq0Fg7mbgU2@uni-berlin.de>
David Golden <············@oceanfree.net> wrote:
> Christopher C. Stacy wrote:

> > For example, I think most people would even agree that SQL
> > is the best language for manipulating SQL databases as such.
>  

> Yeah, but it sure sucks for relational database work ;-)

And it does not handle the interactions with the user interface.
What I'm asking for are the abstraction layers in between.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2hrq71FfuovsU1@uni-berlin.de>
Stefan Ram <···@zedat.fu-berlin.de> wrote:
>   Pico Lisp was built specifically for such tasks, so a fair

Yes, and what I'm looking for are _other_ systems optimized for such
tasks.

>   comparison with other languages should include other tasks as
>   well.

The spec has to be as simple as possible. You cannot put many diverging
tasks into such a posting.

Also, I don't want to compare languages, but APIs.


>     - a small graphical editor for entity-relationship-diagrams
>       (say, it should be possible to insert, delete, label, move 
>       and join boxes and directed arrows between them)

This is completely the opposite direction. Pico Lisp is text based,
so, for example, the following line

   (rel mate   (+List +Joint) mate (+Person))      # Spouse(s)

completely specifies the bi-directional Spouse relation. What does it
help here to draw arrows, except to make it less succinct?


>     - a programm to patch a directory of HTML files
> ...

No meaning in the case of Pico. There is not a single HTML-File involved,
everything is generated dynamically from execution of Lisp sexprs.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9b0vm$da2@library1.airnews.net>
"Alexander Burger" <···@software-lab.de> wrote
> There are endless discussions about the best and most powerful
> progrmming environment. The subject is mostly a matter of taste, and can
> usually not be measured in absolute terms. But perhaps is it possible in
> some certain, well-defined fields?

The problem is that it depends what you are the most interested in.

> I don't doubt that other people have tried to solve these problems before,
so
> there should be other environments with equal or higher succinctness (and
thus
> programming power). To make the systems somehow comparable, I specified a
very
> simple application with certain typical features, and posted it as a
challenge
> to the Lisp community:
>
>    http://software-lab.de/succinctness.html

I also do lots of web applications but I view the SQL only as a back-end I
don't leave it influence my design.
In fact my framework is mainly CLOS based and I use HTML instead of Java for
the GUI. (and yes I have controls on each field and no submit button. ;-)
So I can't do exactly the same application but I can solve the same problem
with a different approach and the same succinctness.

Marc
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2htgjrFg7mbgU1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:

> "Alexander Burger" <···@software-lab.de> wrote
> > There are endless discussions about the best and most powerful
> > progrmming environment. The subject is mostly a matter of taste, and can
> > usually not be measured in absolute terms. But perhaps is it possible in
> > some certain, well-defined fields?

> The problem is that it depends what you are the most interested in.

Or, more precisely, what your customers request you to do.


> In fact my framework is mainly CLOS based and I use HTML instead of Java for
> the GUI. (and yes I have controls on each field and no submit button. ;-)

The problem with plain HTML is that you can't provide for life
interactivity as it is necessary for business-type applications. There
is no clean way to do input-validation and -aid, and also no
satisfactory multi-user synchronization.

But the physical appearance of the GUI doesn't matter. I'm only
interested in the functionality and behavior of the resulting
application.


> So I can't do exactly the same application but I can solve the same problem
> with a different approach and the same succinctness.

The same application is not necessary, or even desired. But it would
be nice if you take some time and post your approach.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Edi Weitz
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <87iseewevd.fsf@bird.agharta.de>
On 30 May 2004 07:25:49 GMT, Alexander Burger <···@software-lab.de> wrote:

>> The problem is that it depends what you are the most interested in.
>
> Or, more precisely, what your customers request you to do.
>
> [...]
>
> The problem with plain HTML is that you can't provide for life
> interactivity as it is necessary for business-type
> applications. There is no clean way to do input-validation and -aid,
> and also no satisfactory multi-user synchronization.

There are enough customers out there that only allow plain HTML
because they have security constraints.

Edi.
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2hthldFg7mbgU4@uni-berlin.de>
Edi Weitz <···@agharta.de> wrote:
> There are enough customers out there that only allow plain HTML
> because they have security constraints.

Sure, therefore many of our installations are restricted to a LAN.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: David Steuber
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <87d64lkg74.fsf@david-steuber.com>
Edi Weitz <···@agharta.de> writes:

> There are enough customers out there that only allow plain HTML
> because they have security constraints.

Indeed.

I think it is ok to use JavaScript in a web page, but its use should
be restricted to form validation to reduce traffic back and forth
between the client and server.  The application should not rely on the
JavaScript being turned on.

I've seen many sites where links call JavaScript functions.  They
don't seem to do it for any particular reason other than that they
can.  I think this should be a crime.

In many ways, going with pure HTML simplifies UI design for web
applications.  You no longer have to worry about the annoying
differences between JavaScript implementations.  You are just
generating text for your output, not code.  It's a practical
application of Occam's razor.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Chris Capel
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <10bked5i3buhs1b@corp.supernews.com>
David Steuber wrote:

> I've seen many sites where links call JavaScript functions.  They
> don't seem to do it for any particular reason other than that they
> can.  I think this should be a crime.

This is the default (perhaps only) behavior in ASP.NET applications. So, the
blame falls squarely on Microsoft. There are a number of other
"interesting" things in ASP.NET, like "textarea" fields that render
properly only in MS IE, when the /obvious/ way to code them would render
properly in Mozilla-and-related browsers as well.

It's /almost/ as if Microsoft were /intentionally/ introducing compatibility
problems. Imagine that! :-O

Chris Capel
From: David Steuber
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <877jus7hcg.fsf@david-steuber.com>
Chris Capel <·····@ibanktech.net> writes:

> David Steuber wrote:
> 
> > I've seen many sites where links call JavaScript functions.  They
> > don't seem to do it for any particular reason other than that they
> > can.  I think this should be a crime.
> 
> This is the default (perhaps only) behavior in ASP.NET applications. So, the
> blame falls squarely on Microsoft. There are a number of other
> "interesting" things in ASP.NET, like "textarea" fields that render
> properly only in MS IE, when the /obvious/ way to code them would render
> properly in Mozilla-and-related browsers as well.
> 
> It's /almost/ as if Microsoft were /intentionally/ introducing compatibility
> problems. Imagine that! :-O

That again.  I know a cure to the problem.  I don't think anyone would
miss Redmond, WA should it be, um, nuked.  I expect the
environmentalists would complain though.  Then again, when they start
getting less spam, perhaps they will shut up.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2hugirFh5lb6U1@uni-berlin.de>
Stefan Ram <···@zedat.fu-berlin.de> wrote:
>   Input-validation on the client can be faked or circumvented by

I'm not sure if we are talking about the same thing. With
Input-validation I mean that the user can only enter information into
a GUI-field which is correct in the current application context (e.g.
a reference to another database object).


>   the client/user. For security reasons, it needs to be done on
>   the server anyway.

That's the way the Pico Lisp GUI works. It is handled by dynamically
generated Java-Applets which keep a permanent connection to the
server. The application logic executes on the server. AFAIK there is
no other way to do this portably in a browser except with Java
(perhaps Flash?).

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9d1ps$cua@library1.airnews.net>
"Alexander Burger" <···@software-lab.de> wrote
> Marc Battyani <·············@fractalconcept.com> wrote:

> > The problem is that it depends what you are the most interested in.
>
> Or, more precisely, what your customers request you to do.

Well I try to choose them so that they are interested in what interest me.
;-)

> > In fact my framework is mainly CLOS based and I use HTML instead of Java
for
> > the GUI. (and yes I have controls on each field and no submit button.
;-)
>
> The problem with plain HTML is that you can't provide for life
> interactivity as it is necessary for business-type applications. There
> is no clean way to do input-validation and -aid, and also no
> satisfactory multi-user synchronization.

This is quite wrong. I do have real time control of all the values of all
the fields and that validation is server based.
The choice of HTML (+ jscript) was done mainly because, as Edi wrote, most
of my customers only allow plain HTML
because they have security constraints. As it's plain HTML  it works for
banks which have zillions of firewalls and proxies for instance.

> But the physical appearance of the GUI doesn't matter. I'm only
> interested in the functionality and behavior of the resulting
> application.

If you come to the Oslo Lisp workshop, I will show you the framework ;-)
BTW if you are interested I can send you the paper I wrote for the ILC2002.

Marc
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2hum89FgvgokU1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:
> "Alexander Burger" <···@software-lab.de> wrote
> > Marc Battyani <·············@fractalconcept.com> wrote:

> > > The problem is that it depends what you are the most interested in.
> >
> > Or, more precisely, what your customers request you to do.

> Well I try to choose them so that they are interested in what interest me.
> ;-)

Oh nice! You are a lucky man :-)


> > The problem with plain HTML is that you can't provide for life
> > interactivity as it is necessary for business-type applications. There
> > is no clean way to do input-validation and -aid, and also no
> > satisfactory multi-user synchronization.

> This is quite wrong. I do have real time control of all the values of all
> the fields and that validation is server based.

Hm, actually I also implemented a plain HTML version. If you replace
"lib/gui.l" on the command line with "lib/htm.l", you get a Java-less
version. I did never complete the implementation, but it basically
works by placing each TextField in its own HTML-form, so that hitting
Return during text input generates the necessary interactivity. The
focus is set with JavaScript (if enabled). I found this method too
limiting, however, and did not research about any further. Perhaps you
have a better solution?


> If you come to the Oslo Lisp workshop, I will show you the framework ;-)

Unfortunately, I had to cancel my trip two weeks ago.

> BTW if you are interested I can send you the paper I wrote for the ILC2002.

Please do so. Many thanks.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9d9lb$mdg@library1.airnews.net>
"Alexander Burger" <···@software-lab.de> wrote
> Marc Battyani <·············@fractalconcept.com> wrote:

> > This is quite wrong. I do have real time control of all the values of
all
> > the fields and that validation is server based.
>
> Hm, actually I also implemented a plain HTML version. If you replace
> "lib/gui.l" on the command line with "lib/htm.l", you get a Java-less
> version. I did never complete the implementation, but it basically
> works by placing each TextField in its own HTML-form, so that hitting
> Return during text input generates the necessary interactivity. The
> focus is set with JavaScript (if enabled). I found this method too
> limiting, however, and did not research about any further. Perhaps you
> have a better solution?

Sure: Hidden frame or IFRAME.

> > If you come to the Oslo Lisp workshop, I will show you the framework ;-)
>
> Unfortunately, I had to cancel my trip two weeks ago.

:(

> > BTW if you are interested I can send you the paper I wrote for the
ILC2002.
>
> Please do so. Many thanks.

Sent.

Marc
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i05t4Fhg8ojU1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:
> Sure: Hidden frame or IFRAME.

Hm, I'm still not convinced of the interactivity of the resulting
application.

Plain HTML (with or without server- or browser-based scripting) does
not allow a life connection between the client and the server, so the
GUI handling of the resulting applications is always limited.

For example, our customers are used to applications
- where keyboard input is expanded automatically from the database
- immediate responses to function keys acting on the database
- pop-up dialogs and menus which handle database contents
- unlimited table scrolling through the database

For a more complete application than the simple person database take a
loot at "http://bws.software-lab.biz", which is a scaled-down version
of a real application. It may not be fully functional because we were
too lazy to generate all necessary test data, but you'll get an idea.
Login with "test" and "test" and play around a little.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i07daFhice6U1@uni-berlin.de>
> For example, our customers are used to applications
> - where keyboard input is expanded automatically from the database
> - immediate responses to function keys acting on the database
> - pop-up dialogs and menus which handle database contents
> - unlimited table scrolling through the database

I forgot one of the more important points:

- enable/disable GUI components depending on the current state of the
  database and the activities of other users

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9f0qn$98s@library1.airnews.net>
"Alexander Burger" <···@software-lab.de> wrote
> Marc Battyani <·············@fractalconcept.com> wrote:
> > Sure: Hidden frame or IFRAME.
>
> Hm, I'm still not convinced of the interactivity of the resulting
> application.

You should. It puzzles all the Java/Zope/PHP web application developpers
I've met ;-)

> Plain HTML (with or without server- or browser-based scripting) does
> not allow a life connection between the client and the server, so the
> GUI handling of the resulting applications is always limited.
>
> For example, our customers are used to applications

Here is what I do in my framework:

> - where keyboard input is expanded automatically from the database

No.

> - immediate responses to function keys acting on the database

Yes.

> - pop-up dialogs and menus which handle database contents

Yes.

> - unlimited table scrolling through the database

Yes.

> I forgot one of the more important points:
>
> - enable/disable GUI components depending on the current state of the
>   database and the activities of other users

Yes, of course!

And also :
Simultaneous update of all the views for all the users when a value changes.
On the fly pdf generation with cl-pdf and cl-typesetting,
It works trough firewalls and proxies.
(cf the ILC2002 paper for details)

> For a more complete application than the simple person database take a
> loot at "http://bws.software-lab.biz", which is a scaled-down version
> of a real application. It may not be fully functional because we were
> too lazy to generate all necessary test data, but you'll get an idea.
> Login with "test" and "test" and play around a little.

OK I've played a little with it (though I don't speak German)
It's a nice Java database application, not really a web application.
Obviously each framework designer will prefer it's own one, otherwise he
would have done it in another way  ;-)

Marc
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i0gpqFhldi5U1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:
> Here is what I do in my framework:
> > - immediate responses to function keys acting on the database
> > - pop-up dialogs and menus which handle database contents
> > - unlimited table scrolling through the database
> > - enable/disable GUI components depending on the current state of the

Interesting. I still don't see how you do it in a portable way without
Java, because no other technology gives you a permanent connection to
the server in a portable way. Sorry, I could not find that information
in your paper :-(

I was trying many times to get away from Java (that's also the reason
for the experiments in "lib/htm.l" I mentioned before), not because of
security reasons, but because of poor Java support across many
platforms.


> And also :
> Simultaneous update of all the views for all the users when a value changes.
> On the fly pdf generation with cl-pdf and cl-typesetting,

Besides pdf, we also generate plain PS and LaTeX in some cases.

> It works trough firewalls and proxies.

Firewalls and proxies are not so much a problem, because it only
concerns connections in one direction (from client to server, as the
applet connects backwards). And Pico Lisp also supports a tunneling
protocol.


> > For a more complete application than the simple person database take a
> > loot at "http://bws.software-lab.biz", which is a scaled-down version
> > of a real application. It may not be fully functional because we were
> > too lazy to generate all necessary test data, but you'll get an idea.
> > Login with "test" and "test" and play around a little.

> OK I've played a little with it (though I don't speak German)
> It's a nice Java database application, not really a web application.
> Obviously each framework designer will prefer it's own one, otherwise he
> would have done it in another way  ;-)

Yes, we agreed on that before :-)

As you said, it depends very much on the purpose. A web application is
probably easier for an un-initiated user, but for people who have to
work with it 8 hours a day a dedicated application might be preferred.

It would be nice if you could post a solution to the simple person
database of my original posting, using your framework.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9fgpk$g6j@library1.airnews.net>
"Alexander Burger" <···@software-lab.de> wrote
> Marc Battyani <·············@fractalconcept.com> wrote:
> > Here is what I do in my framework:
> > > - immediate responses to function keys acting on the database
> > > - pop-up dialogs and menus which handle database contents
> > > - unlimited table scrolling through the database
> > > - enable/disable GUI components depending on the current state of the
>
> Interesting. I still don't see how you do it in a portable way without
> Java, because no other technology gives you a permanent connection to
> the server in a portable way. Sorry, I could not find that information
> in your paper :-(

I could tell you, but after that I would have to ask Tim B. to send you his
black helicopters. ;-)
More serioulsy, I just use an hidden frame for behind the scene
communication.
Look at the table of content on the left of
http://msdn.microsoft.com/library/ to see what I mean (and you can look at
the javascript)

> I was trying many times to get away from Java (that's also the reason
> for the experiments in "lib/htm.l" I mentioned before), not because of
> security reasons, but because of poor Java support across many
> platforms.

Yes, one of my first framework version used a Java applet too, but nobody
accepted this.

> > And also :
> > Simultaneous update of all the views for all the users when a value
changes.
> > On the fly pdf generation with cl-pdf and cl-typesetting,
>
> Besides pdf, we also generate plain PS and LaTeX in some cases.
>
> > It works trough firewalls and proxies.
>
> Firewalls and proxies are not so much a problem, because it only
> concerns connections in one direction (from client to server, as the
> applet connects backwards). And Pico Lisp also supports a tunneling
> protocol.

OK.

> > > For a more complete application than the simple person database take a
> > > loot at "http://bws.software-lab.biz", which is a scaled-down version
> > > of a real application. It may not be fully functional because we were
> > > too lazy to generate all necessary test data, but you'll get an idea.
> > > Login with "test" and "test" and play around a little.
>
> > OK I've played a little with it (though I don't speak German)
> > It's a nice Java database application, not really a web application.
> > Obviously each framework designer will prefer it's own one, otherwise he
> > would have done it in another way  ;-)
>
> Yes, we agreed on that before :-)
>
> As you said, it depends very much on the purpose. A web application is
> probably easier for an un-initiated user, but for people who have to
> work with it 8 hours a day a dedicated application might be preferred.

Hm, I assume you mean a dialog based application as the web applications are
dedicated too.

> It would be nice if you could post a solution to the simple person
> database of my original posting, using your framework.

Here it is: (I made some modifs to show some disable predicates, added a
maried status to show interaction with the spouse value, if you change sex
or your spouse gets maried to somebody else you are automatically un-maried,
etc.)
As you can see I don't rely on any database to make the controls though it
would be possible.

(defclass person nil
  ((name :value-type string :user-name #T(:en "Name" :fr "Nom" :de "" :sp ""
:it "") :disable-predicate 'locked-name)
   (locked-name :value-type boolean :user-name #T(:en "Lock name" :fr
"Verouiller nom" :de "" :sp "" :it ""))
   (sex :value-type symbol :user-name #T(:en "Sex" :fr "Sexe" :de "" :sp ""
:it "") :initform :male)
   (bithdate :value-type :date :user-name #T(:en "Birth date" :fr "Date de
naissance" :de "" :sp "" :it ""))
   (father :value-type person :user-name #T(:en "Father" :fr "P�re" :de ""
:sp "" :it "") :get-object-func 'choose-father)
   (mother :value-type person :user-name #T(:en "Mother" :fr "M�re" :de ""
:sp "" :it "") :get-object-func 'choose-mother)
   (maried :value-type boolean :user-name #T(:en "Maried" :fr "Mari�" :de ""
:sp "" :it ""))
   (spouse :value-type person :user-name #T(:en "Spouse" :fr "Conjoint" :de
"" :sp "" :it "") :disable-predicate '(not maried) :get-object-func
'choose-spouse))
  (:user-name #T(:en "Person" :fr "Personne" :de "" :sp "" :it "") :guid
39944127642591635827640405902 :short-description 'name))

(defun choose-father (obj)
  (remove obj
     (remove :female (persons *all-persons*) :key 'sex)))

(defun choose-mother (obj)
  (remove obj
     (remove :male (persons *all-persons*) :key 'sex)))

(defun choose-spouse (obj)
  (nset-difference
   (remove (sex obj)(persons *all-persons*) :key 'sex)
   (list obj (father obj)(mother obj))))

(defmethod (setf spouse) :around (spouse (obj person))
  (let ((prev-spouse (spouse obj)))
    (unless (eq prev-spouse spouse)
      (call-next-method)
      (when prev-spouse
 (setf (maried prev-spouse) nil))
      (when spouse
 (setf (maried spouse) t
       (spouse spouse) obj)))))

(defmethod (setf maried) :before (maried (obj person))
  (let ((spouse (spouse obj)))
    (when (not maried)
      (setf (spouse obj) nil))))

(defmethod (setf sex) :before (value (obj person))
  (unless (eq value (sex obj))
    (setf (maried obj) nil)))

 Marc
[Who should really be working on real work!]
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i18vsFhv3aeU1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:
> > As you said, it depends very much on the purpose. A web application is
> > probably easier for an un-initiated user, but for people who have to
> > work with it 8 hours a day a dedicated application might be preferred.

> Hm, I assume you mean a dialog based application as the web applications are
> dedicated too.

Sorry, perhaps "dedicated" was the wrong word. I wanted to indicate
the difference to "web" applications, as in my case the browser and
web technology are not of central importance, just a portable means
for zero-install clients.


> > It would be nice if you could post a solution to the simple person
> > database of my original posting, using your framework.

> Here it is: (I made some modifs to show some disable predicates, added a

Many thanks.

> maried status to show interaction with the spouse value, if you change sex
> or your spouse gets maried to somebody else you are automatically un-maried,
> etc.)

So you assume exactly one spouse during a person's lifetime, of
opposite sex? I intended to handle it more tolerantly ;-)

But for the purpose of demonstration, this is Ok for me, though
similar mechanisms exist with the parent <-> kid relations.


As far as I see, however, this is only the database part, not the
whole application. How about the definition and behavior of the GUI?

Also, my original request was primarily for an API as abstracted as
possible. Similar to the 'ucw' solution of Marco Baringer you coded
the mechanics of the relations on-the-fly. Can you abstract it more,
in a way that is usable for all other applications of this kind (e.g.
when you have customers, suppliers and articles instead of persons)?

Then I'd ask for your permission to include it in the
reader-contributed solutions on my page.


> [Who should really be working on real work!]

Sorry ...
But perhaps these abstractions will be useful for you later, too :-)

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9g214$4uu@library1.airnews.net>
"Alexander Burger" <···@software-lab.de> wrote
> Marc Battyani <·············@fractalconcept.com> wrote:
>>> It would be nice if you could post a solution to the simple person
>>> database of my original posting, using your framework.
>
>>Here it is: (I made some modifs to show some disable predicates, added a
>
>Many thanks.
>
>>maried status to show interaction with the spouse value, if you change sex
>>or your spouse gets maried to somebody else you are automatically
un-maried,
>>etc.)
>
> So you assume exactly one spouse during a person's lifetime, of
> opposite sex? I intended to handle it more tolerantly ;-)

Not one spouse, you can change when you want. But one at a time and of the
opposite sex. As I do web applications for banks (for the technical
infrastructure) I have
to make them compatible with the law ;-)

> But for the purpose of demonstration, this is Ok for me, though
> similar mechanisms exist with the parent <-> kid relations.
>
> As far as I see, however, this is only the database part, not the
> whole application. How about the definition and behavior of the GUI?

This is the whole application!
The GUI and web navigation are SQL storage are for free. They are 100% auto
generated from this.

> Also, my original request was primarily for an API as abstracted as
> possible. Similar to the 'ucw' solution of Marco Baringer you coded
> the mechanics of the relations on-the-fly. Can you abstract it more,
> in a way that is usable for all other applications of this kind (e.g.
> when you have customers, suppliers and articles instead of persons)?

Hey, it's a succinctness challenge not an abstraction challenge.
I don't even see what you want.
It's plain Lisp here. The interest of the framework is that I just write
plain Lisp code and then it manages to provide a nice GUI and a persistent
storage in the SQL database (Postgresql through CLSQL). Generally the
objects are much more complicated and can't easily be represented in SQL
tables.
And I don't think there is an interest to make a reusable abstraction for 42
lines of code.

> Then I'd ask for your permission to include it in the
> reader-contributed solutions on my page.

No problem, but I don't have any other one to submit.
If I find some time I will try to put it on the web and I will send you an
email with the URL.

Marc
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i2utuFihepiU1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:
> > As far as I see, however, this is only the database part, not the
> > whole application. How about the definition and behavior of the GUI?

> This is the whole application!
> The GUI and web navigation are SQL storage are for free. They are 100% auto
> generated from this.

Ok. So you generate the GUI completely and exclusively from the data
model, always displaying exactly one complete object at a time, with
all fields of fixed size in a fixed order?


> Hey, it's a succinctness challenge not an abstraction challenge.
> I don't even see what you want.

Succinctness is the _result_ of abstraction.


> And I don't think there is an interest to make a reusable abstraction for 42
> lines of code.

It has no meaning to count lines of code. But what I meant with
abstraction is not to code the behavior of spouses, parents and kids
into the application logic, but to have general concepts of relations
in the framework. For example, in Pico Lisp the whole spouse relation
is defined in a single line (see the link in my original posting):

   (rel mate   (+List +Joint) mate (+Person))      # Spouse(s)

This means that the 'mate' attribute of one person is connected to the
'mate' attribute of another person (by the '+Joint' class), and it's a
n-to-n relation (specified by the '+List' class). These classes
generate daemon objects which at runtime handle all the application
logic, database consistency, validation and GUI behavior (but not
visual appearance) of that relation.

A typical application has hundreds of such relations, so it makes very
much sense to abstract them as much as possible.


> > Then I'd ask for your permission to include it in the
> > reader-contributed solutions on my page.

> No problem, but I don't have any other one to submit.

No, that's fine, thank you.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9hm8n$ocv@library1.airnews.net>
"Alexander Burger" <···@software-lab.de> wrote
> Marc Battyani <·············@fractalconcept.com> wrote:
>
> > This is the whole application!
> > The GUI and web navigation are SQL storage are for free. They are 100%
auto
> > generated from this.
>
> Ok. So you generate the GUI completely and exclusively from the data
> model, always displaying exactly one complete object at a time, with
> all fields of fixed size in a fixed order?

Well, this is what automated views are for :)
I can also do semi-automatic views where I say which fields I want in what
order etc. and fully automated views where I manually design a view. (In
fact by manually I mean in Lisp with a rather high level with html
generation macros, I don't write HTML directly.) Of course the choice of the
view depends on the user, the state of the object, the authorizations, etc.
In real applications 80% of the views are automatic views 20% semi-automatic
ones and 0 to 2 are manual ones.

> It has no meaning to count lines of code. But what I meant with
> abstraction is not to code the behavior of spouses, parents and kids
> into the application logic, but to have general concepts of relations
> in the framework. For example, in Pico Lisp the whole spouse relation
> is defined in a single line (see the link in my original posting):
>
>    (rel mate   (+List +Joint) mate (+Person))      # Spouse(s)
>
> This means that the 'mate' attribute of one person is connected to the
> 'mate' attribute of another person (by the '+Joint' class), and it's a
> n-to-n relation (specified by the '+List' class). These classes
> generate daemon objects which at runtime handle all the application
> logic, database consistency, validation and GUI behavior (but not
> visual appearance) of that relation.

OK you want to see a list that's it ?
In the case of spouse here is how you say a slot is a list of objects:

You just  add :list-of-values t

(spouse :value-type person :list-of-values t :user-name #T(:en "Spouse" :fr
"Conjoint" :de "" :sp "" :it "") :disable-predicate '(not maried)
:get-object-func 'choose-spouse)

This will handle all the aspects of the list from the GUI to the database.

> A typical application has hundreds of such relations, so it makes very
> much sense to abstract them as much as possible.

Sure, but I still don't see how you can have more abstraction than this.
Remember that my framework is object based, not relational at all. So I deal
with objects not relations.

Marc
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i3e85Fis9jdU1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:
> OK you want to see a list that's it ?

No, I did not care about whether the spouses are lists or not. This is
just a matter of example anyway.


> (spouse :value-type person :list-of-values t :user-name #T(:en "Spouse" :fr
> "Conjoint" :de "" :sp "" :it "") :disable-predicate '(not maried)
> :get-object-func 'choose-spouse)

> This will handle all the aspects of the list from the GUI to the database.

This corresponds roughly to the single line I posted just before.

> Sure, but I still don't see how you can have more abstraction than this.

I don't want to nit-pick, because I think your solution is Ok, just
because we got into the details now:

What I meant to be abstracted more was the bunch of method defintions
following your data model, which look to me to describe the behavior
of these objects (handling side-effects of DB-operations), and what is
all handled by Pico in the single line above.


> Remember that my framework is object based, not relational at all. So I deal
> with objects not relations.

Same with Pico Lisp. There isn't even SQL and/or a relational database
underneath. But objects have "relations", of course (also in your
case, I think :-)

Database objects in Pico Lisp are a first-class data type, a special
kind of persistent symbols, which can have any relations between them
as supported by the underlying Lisp language.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <cahrb2$esq@library1.airnews.net>
#| Sorry for the long reply delay, I was really overbooked :( |#

"Alexander Burger" <···@software-lab.de> wrote
> Marc Battyani <·············@fractalconcept.com> wrote:
> I don't want to nit-pick, because I think your solution is Ok, just
> because we got into the details now:
>
> What I meant to be abstracted more was the bunch of method defintions
> following your data model, which look to me to describe the behavior
> of these objects (handling side-effects of DB-operations), and what is
> all handled by Pico in the single line above.

The few lines are for adding a more complex behavior which is not covered
IMO by your code.
For instance:

(defmethod (setf sex) :before (value (obj person))
  (unless (eq value (sex obj))
    (setf (married obj) nil)))

This states that if a married person have a sex change, then this person
gets un-married. (a reasonable behavior at least for me... :)

(defmethod (setf married) :before (married (obj person))
  (unless married
    (setf (spouse obj) nil)))

Here if a person gets un-married then the spouse also gets unmarried and she
or he has no spouse.
etc.

Obviously in a real application this kind of behavior would be more complex.

>>Remember that my framework is object based, not relational at all. So I
deal
>>with objects not relations.
>
> Same with Pico Lisp. There isn't even SQL and/or a relational database
> underneath. But objects have "relations", of course (also in your
> case, I think :-)

Hum, not really.At least I don't view them as such. For me they are just
slot values and lists.

Marc
(From the Oslo Lisp Workshop :)
From: Gareth McCaughan
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <871xkj6ur7.fsf@g.mccaughan.ntlworld.com>
Marc Battyani wrote:

> For instance:
> 
> (defmethod (setf sex) :before (value (obj person))
>   (unless (eq value (sex obj))
>     (setf (married obj) nil)))
> 
> This states that if a married person have a sex change, then this person
> gets un-married. (a reasonable behavior at least for me... :)

In the UK, it is possible for a married person to
change sex and remain married. I don't know how it
is in other jurisdictions.

-- 
Gareth McCaughan
.sig under construc
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2j56kmFtn1d9U1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:

> #| Sorry for the long reply delay, I was really overbooked :( |#

No hurry :)

> "Alexander Burger" <···@software-lab.de> wrote
> > What I meant to be abstracted more was the bunch of method defintions
> > following your data model, which look to me to describe the behavior
> > of these objects (handling side-effects of DB-operations), and what is
> > all handled by Pico in the single line above.

> The few lines are for adding a more complex behavior which is not covered
> IMO by your code.
> ...
> This states that if a married person have a sex change, then this person
> gets un-married. (a reasonable behavior at least for me... :)
> ...
> Here if a person gets un-married then the spouse also gets unmarried and she
> or he has no spouse.

Well, you introduced a flag for a "marriage" status. This is not
necessary, and was not part of the specification. Also, it is redundant,
because a test for the list 'spouse' (or 'mate' in the Pico Lisp
solution) is sufficient (depending on how you define "marriage" and all
its consequences, see also other posts in this thread).


But then, concerning another part of the spec: How do you handle the
relations between parents and children? If you change the sex of a
person, let's say from male to female, the 'father' attribute of that
person's children must be changed to 'mother'.

Is this done by 'choose-father' and 'choose-mother'? If so, where is the
definition of the 'persons' function? But anyway, such basic
manipulations of relations between objects is what I meant when I said
they have to be abstracted out of the application code.

Such things are common to all kinds of applications. If you have, say,
an 'invoice' object, with a link to a 'person', and a list of
'positions', with a link to an 'article' in each of them, etc., then the
Pico Relation Daemon objects handle it all without further code. Believe
me, it's my daily work :) We are writing applications like ERP, CRM,
logistics, and accounting systems with it (we also wrote page layout,
image processing and 3D-graphics systems with Pico Lisp, but there was
no database involved and is not relevant for this disucssion).

Of course, these above applications _do_ contain further code, but there
is a common set of operations which is needed by all of them. And they
have to be encapsulated in an abstracted framework. You may look for a
better description of the underlying mechanisms in:

   "http://software-lab.de/dbui.html".


And how do you get a list of children for a given person? You have no
'children' attribute in your data model. Do you search for them with
that 'persons' function? If so, how is it if you have one million
persons in your database?

How to remove or change a child from the list of children of a given
person? In ERP applications, this corresponds to deleting or changing an
article in the position list in an invoice. You don't want to code such
mechanisms every time. When the child is removed or changed, the
father/mother properties of all involved objects have to be adjusted.

Where is the code that allows the user to search for a person by name?
Do you pop up a dialog? In a previous post you wrote

> > - pop-up dialogs and menus which handle database contents
> Yes.
> > - unlimited table scrolling through the database
> Yes.

(Aside: how do you search for a person in a dialog, if that dialog has
no persistent connection to the server (JavaScript)? Can you scroll
interactively when there one million persons? Ok, this is 'aside'
because I originally did not want to talk about the physical GUI)


Where is the main entry function of the application? How to call it
(e.g. on the command line)?

Where is the initialization of the database with 'Adam' and 'Eve'?

How does your automatically generated GUI provide components like for
searching, creating and deleting database objects? Are there some
buttons?


> Obviously in a real application this kind of behavior would be more complex.

Yes. And that's why we need abstractions, to be able to concentrate on
the application-specific details.


> >>Remember that my framework is object based, not relational at all. So I
> deal
> >>with objects not relations.
> >
> > Same with Pico Lisp. There isn't even SQL and/or a relational database
> > underneath. But objects have "relations", of course (also in your
> > case, I think :-)

> Hum, not really.At least I don't view them as such. For me they are just
> slot values and lists.

Yes, for me too. On the implementation level. I mean, I do not restrict
"relations" to relational databases, but to relations between objects in
the general sense.



> Marc
> (From the Oslo Lisp Workshop :)

I hope you enjoy it! :-)

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marco Baringer
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <m2aczns8xc.fsf@convey.it>
Alexander Burger <···@software-lab.de> writes:

> It has no meaning to count lines of code. But what I meant with
> abstraction is not to code the behavior of spouses, parents and kids
> into the application logic, but to have general concepts of relations
> in the framework. For example, in Pico Lisp the whole spouse relation
> is defined in a single line (see the link in my original posting):
>
>    (rel mate   (+List +Joint) mate (+Person))      # Spouse(s)
>
> This means that the 'mate' attribute of one person is connected to the
> 'mate' attribute of another person (by the '+Joint' class), and it's a
> n-to-n relation (specified by the '+List' class). These classes
> generate daemon objects which at runtime handle all the application
> logic, database consistency, validation and GUI behavior (but not
> visual appearance) of that relation.

i take issue with the idea that a line like this enough to handle
application logic, database consistency, validation and GUI
behavior. Are your relations really so simple that it's enough enough
to say "attribute Y is a list of objects of type X?" Even in your
trivial spec things weren't this simple. that line doesn't say
anything about what should happen when we want to make someone a mate
of themselves, nor does it say what should happen when we want to
remove someone's spouse, nor does it say what to do when we try to
mate parents with their children or sisters with brothers.

once upon a time i believed that relational algebra was enough to
describe the real world, once upon a long forgotten time. some things
can be expressed that way, but they're a small subset of the problems
i've seen in the Real World. the real world is arbitrary, the real
world likes to "fudge" things for no reason other than "because
that's the way it is."

i believe that the language used to describe a problem should be as
simple as possible, but no simpler (and never put correctness below
simplicity). basically i don't think the "abstractions" which you talk
about exist. if i were forced to enumerate them i'd only be describing
a small subset of what i must work with, and i'd spend as much time
working around them as i gained from using them.

imho.

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i3mgcFiv1bcU1@uni-berlin.de>
Marco Baringer <··@bese.it> wrote:
> Alexander Burger <···@software-lab.de> writes:

> > is defined in a single line (see the link in my original posting):
> >
> >    (rel mate   (+List +Joint) mate (+Person))      # Spouse(s)
> >
> > This means that the 'mate' attribute of one person is connected to the
> > 'mate' attribute of another person (by the '+Joint' class), and it's a
> > n-to-n relation (specified by the '+List' class). These classes
> > generate daemon objects which at runtime handle all the application
> > logic, database consistency, validation and GUI behavior (but not
> > visual appearance) of that relation.

> i take issue with the idea that a line like this enough to handle
> application logic, database consistency, validation and GUI
> behavior. Are your relations really so simple that it's enough enough
> to say "attribute Y is a list of objects of type X?" Even in your

Did you try to run the demo application? It should do anything you
expect.

I should add that one more Lisp expression is necessary to completely
specify the GUI (again, see "simple.l"):

      (gui '(+E/R +ListChart) '(mate : home obj) 4 '("Partner")
         '((gui '(+Obj +TextField) '(nm +Person) "" 15)) )

This generates the single-column, four-row table on the middle left
side in the form.

But the classes +E/R and +Obj simply pass the responsibility for the
above items simply to the +List and +Joint objects, so my above
statement is true. In fact, this is all very easy. If you take the
time to look at the source code of the above classes (in "lib/db.l"
and "lib/gui.l"), you'll see that there are just a hand full of code
lines involved.

It takes much longer to describe in English what's going on:

Let's say you type the name of a person into the first TextField in
that table. The +Obj type of that TextField takes care of locating a
person with that name in the database (it knows from the '(nm +Person)
argument what to look for), possibly proposing matching names while
you type, allowing the F2-key to select matching names, rejecting
invalid input (e.g. not a person), and switching the focus to that
person if you double-click on that field.

So the TextField received a person object. It passes this information
up to the surrounding table (of +ListChart class). A table makes a
list of the contents of its fields. The +E/R prefix knows that the
list in this table wants to be assigned to the 'mate' property of an
object, in this case the 'obj' property of the surrounding form.

The +E/R in turn asks the +Joint daemon object to handle the
assignment.

The +Joint says that when person A holds a link to person B, then
person B also holds a link to person A. So when A gets assigned a new
'mate', the +Joint sets a link (in fact, simply a symbol property) to
B, and then also sets a link to A in B. Because of the +List prefix
class, each added link does not replace any previous links but adds
them to a list.


If you want just a single spouse (don't allow more than one), just
change the 'rel' line to

      (rel mate   (+Joint) mate (+Person))            # Spouse

and change the GUI from a table to a single field:

      (gui '(+Obj +TextField) '(nm +Person) "" 15)

Voila. You'll see that the behavior completely changes. If, for
example, there a four persons, with A being a spouse of B, and C being
a spouse of D, then assigning C as a new spouse of A, both B and C
will be without spouses :-(

Just download Pico Lisp and try it for yourself.


> anything about what should happen when we want to make someone a mate
> of themselves, nor does it say what should happen when we want to

This is Ok. If you assign someone itself as a mate, it will contain a
link to itself. This is no contradiction in the data model, and may be
part of the higher application logic. I did not want to make the
example too complicated. You can add either a method to the +Person
class, or a GUI check. For example, extending the last expression with
another prefix class:

      (gui '(+Chk +Obj +TextField)
         '(or
            (extra)
            (and
               (== (: home obj) (val> This))
               "Can't be a spouse" ) )
         '(nm +Person) "" 15 )

(that is, the +Chk prefix class takes a Lisp expression to evaluate)

Then you'll not be able to enter a self-referential spouse-link.


> remove someone's spouse, nor does it say what to do when we try to

If you remove someone's spouse, the operation will be performed by
+Joint in the same bi-directional way.


> mate parents with their children or sisters with brothers.

Same. It depends on the application if you allow that or not.


> once upon a time i believed that relational algebra was enough to
> describe the real world, once upon a long forgotten time. some things
> can be expressed that way, but they're a small subset of the problems
> i've seen in the Real World. the real world is arbitrary, the real
> world likes to "fudge" things for no reason other than "because
> that's the way it is."

Yes, and that's why we need a lot of abstractions to make our life as
a programmer easier. In a real application I would probably make a new
class +SpouseField, containing the above check and probably more:

   (class +SpouseField  +Chk +Obj +TextField)
   ...


> i believe that the language used to describe a problem should be as
> simple as possible, but no simpler (and never put correctness below
> simplicity). basically i don't think the "abstractions" which you talk
> about exist. if i were forced to enumerate them i'd only be describing

I'm sure they do. I use these mechanisms in many real-world
applications since 1996. Of course, +Joint and friends cannot handle
the logic that is specific to the application, but they do the part
which is fundamental to all these kinds of relations, so you never
have to care about them as a programmer, and can concentrate on the
specific details.

> imho.

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <cahrb3$esq@library1.airnews.net>
#| Sorry for the long reply delay, I was really overbooked :( |#

"Marco Baringer" <··@bese.it> wrote
> Alexander Burger <···@software-lab.de> writes:
>
> >    (rel mate   (+List +Joint) mate (+Person))      # Spouse(s)
> >
> > This means that the 'mate' attribute of one person is connected to the
> > 'mate' attribute of another person (by the '+Joint' class), and it's a
> > n-to-n relation (specified by the '+List' class). These classes
> > generate daemon objects which at runtime handle all the application
> > logic, database consistency, validation and GUI behavior (but not
> > visual appearance) of that relation.
>
> i take issue with the idea that a line like this enough to handle
> application logic, database consistency, validation and GUI
> behavior. Are your relations really so simple that it's enough enough
> to say "attribute Y is a list of objects of type X?" Even in your
> trivial spec things weren't this simple. that line doesn't say
> anything about what should happen when we want to make someone a mate
> of themselves, nor does it say what should happen when we want to
> remove someone's spouse, nor does it say what to do when we try to
> mate parents with their children or sisters with brothers.

I agree with you there. As I wrote in another post, you need to add code to
the mere definitions of the relations to make them work properly.

> once upon a time i believed that relational algebra was enough to
> describe the real world, once upon a long forgotten time. some things
> can be expressed that way, but they're a small subset of the problems
> i've seen in the Real World. the real world is arbitrary, the real
> world likes to "fudge" things for no reason other than "because
> that's the way it is."

Agreed. It's like static typing, functional programming, OO, etc.
The world is complex enough that we need all the paradigms + several more to
be able to write useful programs in an efficient way.

> i believe that the language used to describe a problem should be as
> simple as possible, but no simpler (and never put correctness below
> simplicity). basically i don't think the "abstractions" which you talk
> about exist. if i were forced to enumerate them i'd only be describing
> a small subset of what i must work with, and i'd spend as much time
> working around them as i gained from using them.

Yes. In particular if your abstraction are at a too high level, you often
end up with ugly hacks to be able to get the behavior you want as soon as
you want one that is not exactly covered by the abstraction.

Marc
(From the Oslo Lisp Workshop :)
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2j5abdFspoacU1@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:
> "Marco Baringer" <··@bese.it> wrote
> > Alexander Burger <···@software-lab.de> writes:
> >
> > >    (rel mate   (+List +Joint) mate (+Person))      # Spouse(s)
> > >
> > > This means that the 'mate' attribute of one person is connected to the
> > > 'mate' attribute of another person (by the '+Joint' class), and it's a
> > > n-to-n relation (specified by the '+List' class). These classes
> > > generate daemon objects which at runtime handle all the application
> > > logic, database consistency, validation and GUI behavior (but not
> > > visual appearance) of that relation.
> >
> > i take issue with the idea that a line like this enough to handle
> > application logic, database consistency, validation and GUI
> > behavior. Are your relations really so simple that it's enough enough
> > to say "attribute Y is a list of objects of type X?" Even in your
> > trivial spec things weren't this simple. that line doesn't say
> > anything about what should happen when we want to make someone a mate
> > of themselves, nor does it say what should happen when we want to
> > remove someone's spouse, nor does it say what to do when we try to
> > mate parents with their children or sisters with brothers.

> I agree with you there. As I wrote in another post, you need to add code to
> the mere definitions of the relations to make them work properly.

It depends what you consider "properly". As I wrote in answers to your
and Marco's post, the underlying mechanisms are both necessary and
sufficient to handle all database structure aspects.

Additional interpretations of the _meaning_ of that data, of course,
cannot be part of a general framework. But Pico Lisp has that "Prefix
Classes" mechanism which allows to write succinct Lisp expressions
directly within the entity/relation and GUI definitions.

That's the advantage of the Lisp philosophy: The formal equivalence of
code and data.

You don't have to go somewhere else and define classes, methods and
functions, but just write the behavior directly where you need it
(Locality Principle). In the Pico example app, the behavior is
interspersed with the GUI data. Take a look at the 'person' function (in
"www.software-lab.de/simple.l") it generates the GUI during execution,
and stores lots of little Lisp expressions in data structures (GUI
objects) to be executed at appropriate times. These expressions can be
anything, an easy to understand example (without a prefix class, though)
is perhaps:

         (gui '(+Button) "Choose/Create" "Man"
            '(choDialog "Man" '(nm +Man)) )

The button is labeled "Choose/Create" and titled "Man" (that's data),
and executes the function 'choDialog' (that's code) when pressed.


To give an example for a prefix class, let's assume that the button
should be enabled only when some condition is met:

         (gui '(+Able +Button)
            '(test-for-condition 'xyz)
            "Choose/Create" "Man"
            '(choDialog "Man" '(nm +Man)) )

Here '+Able' is a prefix class, with a test expression as an argument.



> Agreed. It's like static typing, functional programming, OO, etc.
> The world is complex enough that we need all the paradigms + several more to
> be able to write useful programs in an efficient way.

I think that prefix classes, combined with mixing of Lisp code and Lisp
data structures, is such a paradigm. Unfortunately, most Lisp
programmers don't seem to use these advantages very much.


> Yes. In particular if your abstraction are at a too high level, you often
> end up with ugly hacks to be able to get the behavior you want as soon as
> you want one that is not exactly covered by the abstraction.

Exactly. Thus, with Pico Lisp's prefix classes you can "surgically"
modify the behavior, and get an enormous flexibility.

> Marc

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: David Steuber
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <87d64k7hrd.fsf@david-steuber.com>
"Marc Battyani" <·············@fractalconcept.com> writes:

> If you come to the Oslo Lisp workshop, I will show you the framework ;-)
> BTW if you are interested I can send you the paper I wrote for the ILC2002.

I would appreciate a copy of this paper also if you don't mind.

The ability to make an interactive application with a pure HTML
interface (no JavaScript) that approaches the interactivity of a local
desktop application is something I find very appealing at this time.

There is of course the academic (or perhaps not so academic) curiosity
that I have about the future being server based applications, a place
where I could use Lisp or any other language I want.  There is also a
more practical problem that I am working on where a desktop app looks
like the only way to produce the required interactivity, but I am not
so sure and would love to do it as a pure web based app.

Brian Mastenbrook demoed a web based IRC application.  It's not as
good as a "real" IRC client, but it will run on a web enabled phone
without having to install any special software on the phone.  It was
really cool.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Marc Battyani
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <c9fjqb$cd3@library1.airnews.net>
"David Steuber" <·····@david-steuber.com> wrote
> "Marc Battyani" <·············@fractalconcept.com> writes:
>
> > If you come to the Oslo Lisp workshop, I will show you the framework ;-)
> > BTW if you are interested I can send you the paper I wrote for the
ILC2002.
>
> I would appreciate a copy of this paper also if you don't mind.

Sent.

> The ability to make an interactive application with a pure HTML
> interface (no JavaScript) that approaches the interactivity of a local
> desktop application is something I find very appealing at this time.

I was probably not clear enough but I use JavaScript.

Marc
From: Dave Roberts
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <lPUuc.35453$n_6.25845@attbi_s53>
Marc Battyani wrote:

> 
> "David Steuber" <·····@david-steuber.com> wrote
>> "Marc Battyani" <·············@fractalconcept.com> writes:
>>
>> > If you come to the Oslo Lisp workshop, I will show you the framework
>> > ;-) BTW if you are interested I can send you the paper I wrote for the
> ILC2002.
>>
>> I would appreciate a copy of this paper also if you don't mind.
> 
> Sent.
> 
>> The ability to make an interactive application with a pure HTML
>> interface (no JavaScript) that approaches the interactivity of a local
>> desktop application is something I find very appealing at this time.
> 
> I was probably not clear enough but I use JavaScript.
> 
> Marc

Marc,

I'd love a copy, too. If you are getting overrun with requests, please post
a copy someplace and we can all just download it.

Also, please send to <·····@droberts.com>. KNode is going to send this with
a bogus return address because of my "identity" for news posting.

Thanks,

-- Dave

-- 
Dave Roberts, ·············@re-move.droberts.com
Slowly but surely, the programming world is finding Lisp...
http://www.findinglisp.com/blog
From: Dave Roberts
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <VRUuc.23518$3x.3659@attbi_s54>
Dave Roberts wrote:

> Also, please send to <..snip...>. KNode is going to send this
> with a bogus return address because of my "identity" for news posting.

Okay, that was dumb. Supposed to be a private message. Here comes the
spam... grumble... ;-)

-- 
Dave Roberts, ·············@re-move.droberts.com
Slowly but surely, the programming world is finding Lisp...
http://www.findinglisp.com/blog
From: Alexander Burger
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <2i3mjlFiv1bcU2@uni-berlin.de>
Marc Battyani <·············@fractalconcept.com> wrote:

> I was probably not clear enough but I use JavaScript.

Wow, you worry about security issues with Java, and then
depend on using JavaScript?

- Alex

-- 

   Software Lab. Alexander Burger
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Rahul Jain
Subject: Re: A Succinctness Challenge
Date: 
Message-ID: <87llj6o4aj.fsf@nyct.net>
Alexander Burger <···@software-lab.de> writes:

> Marc Battyani <·············@fractalconcept.com> wrote:
>
>> I was probably not clear enough but I use JavaScript.
>
> Wow, you worry about security issues with Java, and then
> depend on using JavaScript?

I think he meant that banks do that (at least I hope). All he's really
done is require a specific platform to run his code that runs on top of
some other platforms which could run his code just as well, but are for
some reason forbidden from being used without said other platform on top
of it if said code isn't written by a few approved vendors. The security
differences between the two platforms in practice are miniscule,
especially when given a particularly naive user.

:)

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist