From: Bruce Tobin
Subject: A modest proposal
Date: 
Message-ID: <4sj2ft$22j@triglav.iwaynet.net>
  Lately I've been getting interested in Lisp as a language for developing 
ordinary
workaday business applications.  You know, read a couple of tables from an 
RDBMS,
display them in some kind of fancy GUI screen, write back any changes, and 
generate
reports.  Why Lisp when there are so many specialized tools for doing this 
kind of
thing? Well,

1. It's portable.
2. It's an ANSI standard.
3. It's fast.
4. It's easy to learn (IMHO, and only if it's taught in the right way).
5. Businesses are starting to get very concerned about the need to adjust 
their
   software to rapidly changing requirements.
6. Lisp's ability to adapt itself to the task at hand offers all kinds
   of possibilities for this sort of work:
  a.  Transparent manipulation of database info by field name.
  b.  An embedded modeling language which generates data structures used 
by the app to
      configure itself at runtime.
  c.  An embedded report-generation language.

I suspect a lot of people who read this group are like me: we use Lisp at 
home, and
we play with it at work, but our real jobs involve coding in C/C++, 
Pascal, or various
4GL tools.  I for one would love to be able to write Lisp code and get 
paid for it,
and I think there would be a lot of benefits for my employer as well.

Unfortunately, businesspeople are herd animals.  If you want to get some 
of them to
graze in a certain pasture, you need to convince them that the rest of the 
herd is
going to join them there shortly.  How to get them to nibble at Lisp?

One possibility is to generate some publicity surrounding Lisp business 
programming by
entering (and preferably winning) a contest like the annual Developer's 
Competition
sponsored by Droege Computing Services.  This year Droege has teamed with 
DCI, the
well-known trade show organization , to hold three competitions in 
conjunction
with three DCI shows (yeah, I know this is starting to sound like an ad, 
but it
isn't-- I'm not affiliated with any company involved in these shows in any
way): Database and Client/Server World in Chicago on Dec 10-12 1996 will 
feature a
RAD competition, Internet Expo in San Jose February 17-19 1997 will 
feature an
Internet application developer's competition, and Database and 
Client/Server World
in Boston on May 20-22 will feature a Client/Server application 
development competition.

These sorts of events are generally won by teams using table-based RAD 
tools
like Magic or GSE, and I suspect that will be the case this year as well, 
but
a respectable finish (ahead of well-known tools like Powerbuilder, Gupta, 
VB
etc) would, I think, generate a lot of interest.

So my question is this: is there any interest in the Lisp community in
fielding a team at one or more of these events?  It costs money: $1200 in
entrance fees for a two-person team, which seems to be the optimum size, 
plus
there would be expenses involved in getting the team to the site and 
keeping
them fed, sheltered and equipped.  I am not offering to be the treasurer, 
I
thought perhaps someone with some kind of community recognition would be
willing  to perform that function.  I would be interested in contributing,
say, $200 as seed money, and in helping to code the toolset. I don't think 
I'd
be a good choice for the actual team; I don't code that fast.

  If you are interested in this plan, drop me a line: ······@iwaynet.net 
is
probably the best place. I'll post a summary of responses in a week.  
Thanks
for your attention.

Bruce Tobin
Claremont Technology Group
111 W Liberty St
Columbus, OH 43215
(614)628-4945
Currently on site at:
(614)244-1653
fax:
(614)628-4801
······@iwaynet.net

** The opinions expressed in this post are my own, not those of my 
employer or
any of my clients **

From: Roly Perera
Subject: Re: A modest proposal
Date: 
Message-ID: <01bb7b03$41549080$118549c2@my-computer>
>   Lately I've been getting interested in Lisp as a language for
developing 
> ordinary
> workaday business applications.  You know, read a couple of tables from
an 
> RDBMS,
> display them in some kind of fancy GUI screen, write back any changes,
and 
> generate
> reports.  Why Lisp when there are so many specialized tools for doing
this 
> kind of
> thing? Well,

I won't be able to contribute to a team at any of the events you mentioned
(though I think it's a great idea - it's just that my Lisp skills aren't
good enough [yet]).  But I would like to offer one explanation for why Lisp
still hasn't had much interest from the business community, despite its
suitability to RAD and its ability to adapt quickly to business process
change.

Part of the problem is that it's not very good at executing as a _server_
process.  Modern business systems usually use a client/server or
peer-to-peer distributed architecture where a given process may have to
handle multiple, asynchronous client requests simultaneously.  Common Lisp
doesn't support the notion of a thread, and pretty much allocates all
storage on the heap, making it unsuitable for this kind of thing.

It's a shame because I'd like to see Lisp used much more in 'the real
world'.  I'm aware of a few parallel Lisp implementations but they're not
widely available.
 
> 1. It's portable.
> 2. It's an ANSI standard.
> 3. It's fast.
> 4. It's easy to learn (IMHO, and only if it's taught in the right way).
> 5. Businesses are starting to get very concerned about the need to adjust

> their
>    software to rapidly changing requirements.
> 6. Lisp's ability to adapt itself to the task at hand offers all kinds
>    of possibilities for this sort of work:
>   a.  Transparent manipulation of database info by field name.
>   b.  An embedded modeling language which generates data structures used 
> by the app to
>       configure itself at runtime.
>   c.  An embedded report-generation language.

Oh well :-)

-- 
Roly Perera
----
Interactive Computers Ltd
3 Cumberland Road
Acton
London  W3 6EX
Phone: +44 (956) 414 395
Phax:  +44 (181) 932 2490
Email: ·····@private.nethead.co.uk
----
From: Robert Munyer
Subject: Re: A modest proposal
Date: 
Message-ID: <4tm2uc$gki@Venus.mcs.com>
In article <··························@my-computer>,
Roly Perera <·····@private.nethead.co.uk> wrote:

> I would like to offer one explanation for why Lisp still hasn't
> had much interest from the business community, despite its suitability
> to RAD and its ability to adapt quickly to business process change.
>
> Part of the problem is that it's not very good at executing as a
> _server_ process.  Modern business systems usually use a client/server
> or peer-to-peer distributed architecture where a given process may
> have to handle multiple, asynchronous client requests simultaneously.
> Common Lisp doesn't support the notion of a thread, and pretty much
> allocates all storage on the heap, making it unsuitable for this
> kind of thing.

It is not unsuitable.  Here are three reasons:

1. Traditional Lisp programming style is more amenable to multiple
   threads than traditional C style, because of the comparative
   lack of side effects.

2. Allocating structures on the heap is no problem for multi-threading,
   since these structures are referenced via pointers on a stack.
   In fact this can even make it easier to keep track of which data
   are shared by multiple threads and which are not.

3. Automatic garbage collection is a big win for threaded programs,
   because you don't have to co-ordinate your storage allocation
   strategies between multiple threads.
   
So I guess I don't get your point.

The big problem with multi-threading in Lisp is that there is no
universal standard API.  Is there one for multi-threading in C?

-- Robert
From: Marty Hall
Subject: Re: A modest proposal
Date: 
Message-ID: <DvGKuK.JF5@aplcenmp.apl.jhu.edu>
In article <··········@Venus.mcs.com> ······@MCS.COM (Robert Munyer) writes:
>In article <··························@my-computer>,
>Roly Perera <·····@private.nethead.co.uk> wrote:
>>
>> Part of the problem is that it's not very good at executing as a
>> _server_ process.  Modern business systems usually use a client/server
>> or peer-to-peer distributed architecture where a given process may
>> have to handle multiple, asynchronous client requests simultaneously.
>> Common Lisp doesn't support the notion of a thread, and pretty much
>> allocates all storage on the heap, making it unsuitable for this
>> kind of thing.
>
>It is not unsuitable.  Here are three reasons:
[...]
>2. Allocating structures on the heap is no problem for multi-threading,
[...]
>The big problem with multi-threading in Lisp is that there is no
>universal standard API.

Java allocates all object instances on the heap, and has a standard
threading API. So I agree that heap allocation is not a problem for
threading, and that the problem in Lisp is not that threading is not
possible, just that it is not standard.
						- Marty

Lisp Resources: <http://www.apl.jhu.edu/~hall/lisp.html>
Java Resources: <http://www.apl.jhu.edu/~hall/java/>
From: Roly Perera
Subject: Re: A modest proposal
Date: 
Message-ID: <01bb80b8$740a7200$1b8549c2@my-computer>
Robert Munyer <······@MCS.COM> wrote in article 

> Roly Perera <·····@private.nethead.co.uk> wrote:
> 
> > I would like to offer one explanation for why Lisp still hasn't
> > had much interest from the business community, despite its suitability
> > to RAD and its ability to adapt quickly to business process change.
> >
> > Part of the problem is that it's not very good at executing as a
> > _server_ process.  Modern business systems usually use a client/server
> > or peer-to-peer distributed architecture where a given process may
> > have to handle multiple, asynchronous client requests simultaneously.
> > Common Lisp doesn't support the notion of a thread, and pretty much
> > allocates all storage on the heap, making it unsuitable for this
> > kind of thing.
> 
> It is not unsuitable.  Here are three reasons:

BTW, this wasn't an attack on Lisp.  I would like to use Lisp for
programming server processes, but don't see how it can be done as easily as
it can be done in (say) C++.  That's probably down to my ignorance of
advanced Lisp implementations however.

> 1. Traditional Lisp programming style is more amenable to multiple
>    threads than traditional C style, because of the comparative
>    lack of side effects.

OK, I understand this point.  I'll explain more on what I was getting at
below.
 
> 2. Allocating structures on the heap is no problem for multi-threading,
>    since these structures are referenced via pointers on a stack.
>    In fact this can even make it easier to keep track of which data
>    are shared by multiple threads and which are not.

The problem I envisage (I don't know how this is solved in real
multi-threaded Lisps) is this.  Say you have a Lisp function that refers to
some heap-based data, via, as you say, pointers on a stack.  (Let's say the
function is a closure, and this data is the environment from the function's
definition-time lexical context.)  Now, if two threads are executing this
function simultaneously, both these threads can potentially access a
binding in this environment at the same time, e.g. both could be modifying
the same list at the same time.  How do you ensure that both operations
have valid data to work on?  Is function-level locking effectively required
for every such operation, including Lisp primitives?

I realise that this problem exists with multi-threading in any language,
but Lisp tends to use lists and other heap-based data structures much more
than other languages.  Or do multi-threaded Lisp programs tend to use lists
less?
 
> 3. Automatic garbage collection is a big win for threaded programs,
>    because you don't have to co-ordinate your storage allocation
>    strategies between multiple threads.

True, but I never implied GC was a weakness of Lisp in a multi-threaded
environment.
    
> So I guess I don't get your point.

I hope you do now!  Of course I may be wrong about this being a problem. 
But if I am, please explain how multi-threaded Lisp implementations work.
 
> The big problem with multi-threading in Lisp is that there is no
> universal standard API.  Is there one for multi-threading in C?

I've no idea about C.  As far as I know not many languages provide a
multi-threaded API as such.  Some languages (e.g. Java) provide simple
synchronisation mechanisms.


-- 
Roly Perera
----
Interactive Computers Ltd
3 Cumberland Road
Acton
London  W3 6EX
Phone: +44 (956) 414 395
Phax:  +44 (181) 932 2490
Email: ·····@private.nethead.co.uk
----
From: Barry Margolin
Subject: Re: A modest proposal
Date: 
Message-ID: <4u0jcg$e48@tools.bbnplanet.com>
In article <··························@my-computer>,
Roly Perera <·····@private.nethead.co.uk> wrote:
>I realise that this problem exists with multi-threading in any language,
>but Lisp tends to use lists and other heap-based data structures much more
>than other languages.  Or do multi-threaded Lisp programs tend to use lists
>less?

In just about any language, if a data structure is being accessed by
multiple threads it's most likely on the heap.  C and C++ programs make
extensive use of heap allocation.

Lisp actually makes it relatively easy to manage shared access.  You don't
need function-level locking, you can make the locking as local as you
want.  Most multi-threaded Lisps provide some kind of WITH-LOCK macro, with
a syntax like:

(defmacro with-lock ((lock-object &key <options>) &body body) ...)

The lock is locked at entry to this block of code (the options might
specify how long to wait for a lock, whether to lock for read-only or
read-write, what to do about recursive lock attempts, etc.) and unlocked on
exit (an UNWIND-PROTECT would guarantee it).

Built on this, you could then easily implement something like ATOMIC-PUSH
for adding an element to a shared list, or ATOMIC-INCF for incrementing a
shared value.
-- 
Barry Margolin
BBN Planet, Cambridge, MA
······@bbnplanet.com -  Phone (617) 873-3126 - Fax (617) 873-6351
(BBN customers, please call (800) 632-7638 option 1 for support)
From: Robert Munyer
Subject: Re: A modest proposal
Date: 
Message-ID: <4u3cpm$oaa@Venus.mcs.com>
In article <··························@my-computer>,
Roly Perera <·····@private.nethead.co.uk> wrote:
> Robert Munyer <······@MCS.COM> wrote in article
> > Roly Perera <·····@private.nethead.co.uk> wrote:
> >
> > > Modern business systems usually use a client/server or
> > > peer-to-peer distributed architecture where a given process
> > > may have to handle multiple, asynchronous client requests
> > > simultaneously.  Common Lisp doesn't support the notion of
> > > a thread, and pretty much allocates all storage on the heap,
> > > making it unsuitable for this kind of thing.
> >
> > It is not unsuitable.  Here are three reasons:
>
> BTW, this wasn't an attack on Lisp.

I didn't think it was.  If you had been attacking Lisp, you would
have been doing it in the wrong place!  ;-)

> I would like to use Lisp for programming server processes, but
> don't see how it can be done as easily as it can be done in (say)
> C++.  That's probably down to my ignorance of advanced Lisp
> implementations however.

The source code for cl-http (Web server written in Common Lisp) is
available for downloading.  It works in a number of Common Lisp
implementations.  If you get that code and read it, I bet the
"ignorance of advanced Lisp implementations" that you mentioned
will disappear.

> > 1. Traditional Lisp programming style is more amenable to
> >    multiple threads than traditional C style, because of the
> >    comparative lack of side effects.
>
> OK, I understand this point.  I'll explain more on what I was
> getting at below.
>
> > 2. Allocating structures on the heap is no problem for
> >    multi-threading, since these structures are referenced via
> >    pointers on a stack.  In fact this can even make it easier
> >    to keep track of which data are shared by multiple threads
> >    and which are not.
>
> The problem I envisage (I don't know how this is solved in real
> multi-threaded Lisps) is this.  Say you have a Lisp function that
> refers to some heap-based data, via, as you say, pointers on a
> stack.  (Let's say the function is a closure, and this data is
> the environment from the function's definition-time lexical
> context.) Now, if two threads are executing this function
> simultaneously, both these threads can potentially access a
> binding in this environment at the same time, e.g. both could be
> modifying the same list at the same time.  How do you ensure that
> both operations have valid data to work on?  Is function-level
> locking effectively required for every such operation,

OK, I think I'm beginning to understand what you're worried about.
Correct me if I'm wrong here.  It seems you have noticed that in
Lisp you can (1) create a closure that modifies its environment by
assigning a value to a variable; (2) share this closure between
threads; and (3) forget to coordinate your threads and get in
trouble.  I think perhaps you also believe that (4) local variables
in C or C++ are stored on the stack and cannot be shared between
threads, so assigning values to them is not a problem.

In that case I would say that you are right about #1 through #3,
but wrong in thinking that they add up to a disadvantage for Lisp.
I would say that #4 is false when applied to C++, and technically
true (but misleading) when applied to C.

When you get yourself into trouble by doing #1 through #3 in Lisp,
the fate you suffer is really the same fate you would suffer in
other languages when you create a structure, share it between
threads, and modify it without proper coordination.

It is true that in a Lisp program, a statement like "(setq v x)"
can modify shared data, even if v is not a global variable.  It is
also true that in a C program, a statement like "v = x;" would not
modify shared data, because C doesn't have call by reference.  But
this is not an advantage for C; it just means that when you want
that kind of effect you have to use a different kind of statement.
You end up making v static or global, or you make it a pointer and
change the statement to "*v = x;" or "v->m = x;".  Once you do this
you are no longer safe from modifying shared data.

When you change from C to C++, you encounter new kinds of shared
data and possible thread coordination problems.  You still have
static and global variables and pointers, but now you also have
references and member variables.  In fact, a C++ member function
which assigns a value to a member variable will give you exactly
the same problems as the Lisp situation you described (a closure
which assigns a value to a variable in its environment).

Now that I think about it, all of your concerns about Lisp apply
equally well to C++.  Here is what you said, with just a few words
changed to make it apply to C++:

    The problem I envisage (I don't know how this is solved in real
    multi-threaded C++) is this.  Say you have a C++ function that
    refers to some heap-based data, via, as you say, pointers on
    a stack.  (Let's say the function is a member function, and
    the data are the instance variables from the object's class
    definition.)  Now, if two threads are executing this member
    function simultaneously, both these threads can potentially
    access an instance variable at the same time, e.g. both could
    be modifying the same object at the same time.  How do you
    ensure that both operations have valid data to work on?  Is
    method-level locking effectively required for every such
    operation, including those in the standard class library?

    I realise that this problem exists with multi-threading in any
    language, but C++ tends to use new'ed objects and other heap-based
    data structures much more than other languages.  Or do
    multi-threaded C++ programs tend to use these objects less?

I hope you don't think I'm being rude by doing a word substitution
on your paragraphs.  I'm just trying to show that the problem you
pointed out really is not specific to Lisp.

> including Lisp primitives?

Most Lisp primitives (and many other functions as well) do not have
side effects and are not a problem.  Take MAPCAR, for example.
It's possible that a particular implementation of MAPCAR might
modify its own local variables and/or parameters with SETQ.  But
that's not a problem, because each individual invocation of MAPCAR
will have its own separate set of local variables and parameters.

> I realise that this problem exists with multi-threading in any
> language, but Lisp tends to use lists and other heap-based data
> structures much more than other languages.  Or do multi-threaded
> Lisp programs tend to use lists less?

The problem is not just with heap data, it is with any kind of
shared data.  This includes static data, global data, and any kind
of data accessed through pointers or references (whether on the
heap or not).  If you think about it this way you will see that
other languages have just as much shared data as Lisp.

And furthermore, the problem with shared data only happens when
you modify data destructively.  Lisp code is usually less destructive
than code written in C or C++.  See my original point #1 above.
Programming with lists is also usually less destructive than
programming with arrays, because it's easy to add to a list (or
subtract from it) without changing the original list and interfering
with other threads that might be using it.

> > 3. Automatic garbage collection is a big win for threaded
> >    programs, because you don't have to co-ordinate your storage
> >    allocation strategies between multiple threads.
>
> True, but I never implied GC was a weakness of Lisp in a
> multi-threaded environment.

But I didn't say it just wasn't a weakness; I said it was a big
win.  In other words it could even help make up for other weaknesses,
if they were real.

GC removes allocation and deallocation from the list of side effects
that you might forget to coordinate.  That can eliminate a lot of
potential errors.

> > So I guess I don't get your point.
>
> I hope you do now!

Yes, I think maybe I do.  Let me know if I'm still missing something.

> Of course I may be wrong about this being a problem.  But if I
> am, please explain how multi-threaded Lisp implementations work.

Actually I haven't found major flaws in your understanding of Lisp.
You seem to understand how lambda works.  It's just that somehow
you haven't noticed that the same problems crop up in C and C++.
At first I thought you were a C++ hacker who writes multi-threaded
server software, and didn't know much Lisp.  But now it seems that
I was probably wrong about that.

Though I do think you might be overestimating how often you have
to modify shared data in Lisp.  Perhaps your concern comes from
contemplating code like this:

    (defun make-counter (&optional (start 0))
      (let ((value start))
        #'(lambda (&optional (delta 1))
            (setq value (max (+ value delta) 0)))))

There are a few things worth considering about this example.  (1)
Once you have created one of these counters, you can either share
it or not -- the choice is up to you.  The fact that it lives on
the heap does not mean you have to share it.  (2) This use of
closures has largely been supplanted by CLOS objects.  This is not
surprising, because the above code is really an example of a
proto-object-oriented abstraction technique.  (3) Imagine how you
would implement one of these counters in C or C++.  You would
probably make it a structure or an object, and you would end up
with sharing issues at least as bad as in Lisp.  It is true that
in C++ you could make your counter object live on the stack instead
of on the heap -- but that would not protect you from sharing
problems, because you could still take the object's address and
share that with other threads.

Well, sorry this got to be so long.  I hope it was helpful.  I hope
you will change your mind, check out cl-http, and enjoy great
success writing client/server or peer-to-peer distributed business
software in Lisp.

-- Robert
From: Dieter Menszner
Subject: Re: A modest proposal
Date: 
Message-ID: <4u1fdl$ie2@news00.btx.dtag.de>
·····@private.nethead.co.uk wrote about
 "Re: A modest proposal":


...
> > 2. Allocating structures on the heap is no problem for multi-threading,
> >    since these structures are referenced via pointers on a stack.
> >    In fact this can even make it easier to keep track of which data
> >    are shared by multiple threads and which are not.
>
> The problem I envisage (I don't know how this is solved in real
> multi-threaded Lisps) is this.  Say you have a Lisp function that refers
> to some heap-based data, via, as you say, pointers on a stack.  (Let's
> say the function is a closure, and this data is the environment from the
> function's definition-time lexical context.)  Now, if two threads are
> executing this function simultaneously, both these threads can
> potentially access a binding in this environment at the same time, e.g.
> both could be modifying the same list at the same time.  How do you
> ensure that both operations have valid data to work on?  Is function-
> level locking effectively required for every such operation, including
> Lisp primitives?
>
In Lisp you don't have explicit access to such pointers, so the situation
you describe cannot happen unintentionally. But, of course, if both
function invocations manipulate the same 'global' data there is a
synchronization problem. This is not Lisp-specific.
If you don't use functions like 'rplacd' on the list there is no problem.
You shouldn't do that anyway unless you want to exchange data between
threads.

  Dieter

                      
From: Aldy Hernandez
Subject: Re: A modest proposal
Date: 
Message-ID: <m2d91j6l55.fsf@bt313a.resburman.andrews.edu>
 > handle multiple, asynchronous client requests simultaneously.  Common Lisp
 > doesn't support the notion of a thread, and pretty much allocates all
 > storage on the heap, making it unsuitable for this kind of thing.

If a threading system is what's stopping you; writing a threading
library in lisp is wayyyy easier than writing it in C.  Especially
with catch/throw (or call-with-continuation in Scheme).

 > It's a shame because I'd like to see Lisp used much more in 'the real
 > world'.  I'm aware of a few parallel Lisp implementations but they're not
 > widely available.

A couple months ago I got the [oraperl] library (Oracle calls in Perl)
to work with Scheme.  Now I do a lot of my everyday oracle
"programming" in Scheme instead of SQL.

It would be trivial to do the same for other database systems.


Aldy
From: Tim Bradshaw
Subject: Re: A modest proposal
Date: 
Message-ID: <ey3log3s644.fsf@staffa.aiai.ed.ac.uk>
* Roly Perera wrote:

> Part of the problem is that it's not very good at executing as a _server_
> process.  Modern business systems usually use a client/server or
> peer-to-peer distributed architecture where a given process may have to
> handle multiple, asynchronous client requests simultaneously.  Common Lisp
> doesn't support the notion of a thread, and pretty much allocates all
> storage on the heap, making it unsuitable for this kind of thing.

Most or all of the commercial Common Lisps have some kind of
multitasking.  Have a look at the CL-HTTPD system, which is a classic
`server'-type system in Lisp.  I think you can find information on it
at http://www.ai.mit.edu/projects/iiip/doc/cl-http/home-page.html.

Of course the multitasking interface isn't standard, which is a pain.

--tim