From: sharkfish
Subject: newbie needs some direction
Date: 
Message-ID: <pt9La.39750$Ab2.67572@sccrnsc01>
Hi all.  I've been Googling for a while now and I've come up with Franz
Allegro CL, AllegroServe as great options for learning and writing CLisp
code.

I eventually would like to write a web application with CLisp, however, I
know I will have trouble convincing anyone to allow me to adopt this
language without a proof of concept.

My current development environment is all Microsoft...ASP/VB/SQL.  I have a
lot of experience with Java as well, but we are not currently using it.

How can I serve up a CLisp application via Microsoft's IIS web server (ugh,
I know) and ASP.NET web pages? I just want to be able to pass form data from
the web site to be processed by CLisp programs on the server.  I need to
share session information from the current apps (ASP) to the CLisp apps.  My
company is just about convinced that dotNET with VB.NET or C# is the way to
go.  Can I run CLisp applications within the .NET CLR....is there a real
CLisp compiler for the CLR besides that simple example MS provides in their
sample code?

I also noticed there is an "LSP" open source initiative that is similar to
ASP or JSP.  Is this a good option?

Thanks in advance.

From: Pascal Costanza
Subject: Re: newbie needs some direction
Date: 
Message-ID: <costanza-369495.10365028062003@news.netcologne.de>
In article <·····················@sccrnsc01>,
 "sharkfish" <·····@bidness.com> wrote:

> Hi all.  I've been Googling for a while now and I've come up with Franz
> Allegro CL, AllegroServe as great options for learning and writing CLisp
> code.
> 
> I eventually would like to write a web application with CLisp, however, I
> know I will have trouble convincing anyone to allow me to adopt this
> language without a proof of concept.


I don't know if this helps, but Yahoo Store was completely written in 
CLisp, and its main author, Paul Graham, has written some very 
interesting articles about it. See the respective entry in http://alu.cliki.net/Success%20Stories

Also interesting are http://alu.cliki.net/Industry%20Application, http://alu.cliki.net/Evaluate%20Lisp and the rest of that site - http://alu.cliki.net/index


Pascal
From: Steven M. Haflich
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3EFD96D4.4090604@alum.mit.edu>
Pascal Costanza wrote:

> I don't know if this helps, but Yahoo Store was completely written in 
> CLisp

I'm not so sure about this.  IIRC, it was only the store _editor_ server
that was written in Lisp.  The store server (less complex behavior, but
much higher traffic volume) used standard server technology.  I don't
remember where I get this info, however.

Also, didn't Paul use GCL, not CLisp?
From: Marco Baringer
Subject: Re: newbie needs some direction
Date: 
Message-ID: <m2ptkyw57u.fsf@bese.it>
"Steven M. Haflich" <·················@alum.mit.edu> writes:

> Pascal Costanza wrote:
> 
> > I don't know if this helps, but Yahoo Store was completely written
> > in CLisp
> 
> I'm not so sure about this.  IIRC, it was only the store _editor_ server
> that was written in Lisp.  The store server (less complex behavior, but
> much higher traffic volume) used standard server technology.  I don't
> remember where I get this info, however.

this example keeps coming up, and everytime the info is different...
 
> Also, didn't Paul use GCL, not CLisp?

no, he used CLISP. asking google far c.l.l articles with "paul graham
yahoo store" gives this as the second result:

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=2%3Di%3DPnzEdDw%3D%3DafoP6c%3DqFyf1vLk%404ax.com&prev=/groups%3Fq%3Dpaul%2Bgraham%2Bclisp%2Bgroup:comp.lang.lisp.*%26hl%3Den%26lr%3D%26ie%3DUTF-8%26group%3Dcomp.lang.lisp.*%26selm%3D2%253Di%253DPnzEdDw%253D%253DafoP6c%253DqFyf1vLk%25404ax.com%26rnum%3D1

from the footnote of http://www.paulgraham.com/avg.html we have:

---
[1] Viaweb at first had two parts: the editor, written in Lisp, which
people used to build their sites, and the ordering system, written in
C, which handled orders.  The first version was mostly Lisp, because
the ordering system was small.  Later we added two more modules, an
image generator written in C, and a back-office manager written mostly
in Perl.

In January 2003, Yahoo released a new version of the editor written in
C++ and Perl.  It's hard to say whether the program is no longer
written in Lisp, though, because to translate this program into C++
they literally had to write a Lisp interpreter: the source files of
all the page-generating templates are still, as far as I know, Lisp
code.  (See Greenspun's Tenth Rule .)
---

-- 
-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: Pascal Costanza
Subject: Re: newbie needs some direction
Date: 
Message-ID: <costanza-766826.22190328062003@news.netcologne.de>
In article <··············@bese.it>, Marco Baringer <··@bese.it> wrote:

> "Steven M. Haflich" <·················@alum.mit.edu> writes:
> 
> > Pascal Costanza wrote:
> > 
> > > I don't know if this helps, but Yahoo Store was completely written
> > > in CLisp
> > 
> > I'm not so sure about this.

> 
> this example keeps coming up, and everytime the info is different...

Oops, obviously I have exaggerated a bit. Thanks for the correction.


Pascal
From: Henrik Motakef
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.06.28.09.36.44.65563@henrik-motakef.de>
On Sat, 28 Jun 2003 06:12:53 +0000, sharkfish wrote:

> Hi all.  I've been Googling for a while now and I've come up with Franz
> Allegro CL, AllegroServe as great options for learning and writing CLisp
> code.

This sounds a little funny, because CLISP is itself a Common Lisp
implementation, just as Allegro CL is (http://clisp.sf.net).

It is therefore not a good idea to abbreviate "Common Lisp" as "CLisp"
- "CL" is generally considered less confusing, and it's shorter, too ;-)

Additionally, you might be interested to hear the Portable AllegroServe,
an AServe fork that works on more Lisps than just Allegro CL, seems to
have some support for CLISP, and for some other Lisps, some free, some
commercial. See http://portableaserve.sf.net

> I eventually would like to write a web application with CLisp, however, I
> know I will have trouble convincing anyone to allow me to adopt this
> language without a proof of concept.

I guess you are looking for general examples of using Lisp for web
applications?

Pascal already mentioned ViaWeb/Yahoo! Store. Others include OnShore
Developments WebCheckout (http://www.onshored.com), built on their free
IMHO toolkit. Araneida (http://araneida.telent.net) has been used for a
ticket agency (http://web.metacircles.com/stargreen) and the cliki
(http://www.cliki.net, read this!) among other things. Lots of people use
CL-HTTPD (http://www.ai.mit.edu/projects/iiip/doc/cl-http/home-page.html)
for real work - there was a message on the mailing list recently that
asked for CL-HTTPD savy volunteers for http://www.deanforamerica.com, for
example. Marc Battyani, author of mod_lisp, will hold a talk about a CL
web framework at the libre software meeting in Metz next month which
sounds promising
(http://libresoftwaremeeting.org/program/view_topic.php?topic_id=23#lecture74)

There are, of course, more examples. You might want to ask on the lispweb
mailing list, see http://www.red-bean.com/lispweb/. It is quite
low-traffic (but not as dead as the archives imply), but if you ask, I'm
sure you will receive answers. You should also browse http://www.cliki.net
and http://alu.cliki.net.

> My current development environment is all Microsoft...ASP/VB/SQL.  I have
> a lot of experience with Java as well, but we are not currently using it.
> 
> How can I serve up a CLisp application via Microsoft's IIS web server
> (ugh, I know) and ASP.NET web pages? I just want to be able to pass form
> data from the web site to be processed by CLisp programs on the server.  I
> need to share session information from the current apps (ASP) to the CLisp
> apps.  My company is just about convinced that dotNET with VB.NET or C# is
> the way to go.  Can I run CLisp applications within the .NET CLR....is
> there a real CLisp compiler for the CLR besides that simple example MS
> provides in their sample code?

As far as I know, there is no usable Lisp that targets the CLR. However, I
seem to recall someone writing COM components with Lispworks (maybe
Allegro CL or Corman Lisp can do that, too), I guess it should be possible
to use those in IIS. The other options are using CGI (typically not a good
idea, scince the startup overhead of Lisp apps can be significant, and,
frankly, CGI is weird anyway) or communicating with a Lisp process over
sockets. Unfortunately there is no SOAP toolkit for CL that would allow
you plug-and-play integration with .NET, but there are XML-RPC toolkits
you could use, or the protocol used by mod_lisp, which shouldn't be too
hard to reimplement on the .NET side. Or plain HTTP, or APJ (used by
servlet containers like Apache Tomcat, Lisp client implemented by IMHO)
or just invent your own protocol ;-)

Good Luck!
From: Yarden Katz
Subject: Re: newbie needs some direction
Date: 
Message-ID: <86y8zmjmg7.fsf@underlevel.net>
Henrik Motakef <······@henrik-motakef.de> writes:

[snip great, informative post]
> Unfortunately there is no SOAP toolkit for CL that would allow
> you plug-and-play integration with .NET, but there are XML-RPC toolkits
> you could use, 

Just for the SOAP side of things: there's actually a simple-soap.lisp
module included in CL-XML, but I've yet to hear of someone who
actually got it to work.  I've been working on a SOAP interface as
well, but it's pretty specific to my project and it is not my
intention to implement anything even close to the majority of the SOAP
spec (scary).  Whatever comes out of it will be public, but the OP
should probably still check out what's in CL-XML.

Best wishes,
-- 
Yarden Katz <····@underlevel.net>  |  Mind the gap
From: Mark Hurd
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3efe6bec_1@news.iprimus.com.au>
sharkfish wrote:
>  Can I run CLisp applications within the .NET CLR....is there a real
> CLisp compiler for the CLR besides that simple example MS provides in their
> sample code?

As a "newbie" you probably don't need to know this, but Rich Hickey has a Lisp
(not CL) built for the .Net Framework.

http://www.richhickey.com/dotlisp.htm

Although it is an interpreter, performance is still rather good when most of
the code is just gluing framework routines together. He provides a component
interface so you could have an ASP.NET page that includes or reads lisp source
and passes it to the DotLisp interpreter.

I have written some extensions (purely in DotLisp) to allow declaring
"Platform Invoke" methods so you can access the whole of the Win32 API as
well.
-- 
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.06.29.05.06.01.715919@consulting.net.nz>
Hi Mark Hurd,

> sharkfish wrote:
>>  Can I run CLisp applications within the .NET CLR....is there a real
>> CLisp compiler for the CLR besides that simple example MS provides in their
>> sample code?
> 
> As a "newbie" you probably don't need to know this, but Rich Hickey has a Lisp
> (not CL) built for the .Net Framework.
> 
> http://www.richhickey.com/dotlisp.htm

It's so superficially Lisp. Even the "little" things don't appear to work
like Common Lisp (although Rich Hickey claims his philosophy is "retaining
the essence of Lisp as a language"). Could part of that essence be adding
two integers and providing the wrong result?

    1, 2, -3

Integers (System.Int32)

<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemint32classtopic.asp>
"Represents a 32-bit signed integer."

So how do Common Lisp and DotLisp compare when performing this
calculation: (+ 2000000000 1000000000)

(This is not rhetorical, I don't run a Microsoft .Net/DotLisp environment
and would like to confirm the answer).

Thanks,
Adam
From: Mark Hurd
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3eff2e0e$1_1@news.iprimus.com.au>
Adam Warner wrote:
> Hi Mark Hurd,
> > sharkfish wrote:
> > >  Can I run CLisp applications within the .NET CLR....is there a real
> > > CLisp compiler for the CLR besides that simple example MS provides in
> > > their sample code?
> >
> > As a "newbie" you probably don't need to know this, but Rich Hickey has a
> > Lisp (not CL) built for the .Net Framework.
> >
> > http://www.richhickey.com/dotlisp.htm
>
> It's so superficially Lisp. Even the "little" things don't appear to work
> like Common Lisp (although Rich Hickey claims his philosophy is "retaining
> the essence of Lisp as a language"). Could part of that essence be adding
> two integers and providing the wrong result?
>
>     1, 2, -3
>
> Integers (System.Int32)
>
>
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/f
rlrfsystemint32classtopic.asp>
> "Represents a 32-bit signed integer."
>
> So how do Common Lisp and DotLisp compare when performing this
> calculation: (+ 2000000000 1000000000)
>
> (This is not rhetorical, I don't run a Microsoft .Net/DotLisp environment
> and would like to confirm the answer).

Yes, it definitely isn't Common Lisp. Note that the source was from a Scheme
dialect.
And if it was to be CL, it'd need to be a Lisp-2, for a start.

DotLisp:
> (+ 2000000000 1000000000)
-1294967296
> (+ (Decimal:Parse "2000000000") (Decimal:Parse "1000000000"))
3000000000

The above shows that the .NET Framework has Decimals which have a larger range
than Long, but Rich's current implementation only stores to longs.

This is what I've seen in general, that the .NET Framework provides much of
the functionality that sample Lisp code I have found on the 'net expects to be
provided by Lisp libraries (as you would expect -- the .NET Framework is
designed to be a suitable base for any programming language). For example, I
have found that the .NET Framework Hashtables and ArrayLists provide
functionality that matches association lists (and Lisp Hashtables, of course).
-- 
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
From: Edi Weitz
Subject: Re: newbie needs some direction
Date: 
Message-ID: <87el1chem3.fsf@bird.agharta.de>
"Mark Hurd" <········@ozemail.com.au> writes:

> This is what I've seen in general, that the .NET Framework provides
> much of the functionality that sample Lisp code I have found on the
> 'net expects to be provided by Lisp libraries (as you would expect
> -- the .NET Framework is designed to be a suitable base for any
> programming language).

People who've looked closer don't share your opinion:

  <http://groups.google.com/groups?selm=47kp4j52c.fsf%40beta.franz.com>

Edi.
From: ·············@attbi.com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <adc08w0i.fsf@attbi.com>
Edi Weitz <···@agharta.de> writes:

> "Mark Hurd" <········@ozemail.com.au> writes:
>
>> This is what I've seen in general, that the .NET Framework provides
>> much of the functionality that sample Lisp code I have found on the
>> 'net expects to be provided by Lisp libraries (as you would expect
>> -- the .NET Framework is designed to be a suitable base for any
>> programming language).
>
> People who've looked closer don't share your opinion:
>
>   <http://groups.google.com/groups?selm=47kp4j52c.fsf%40beta.franz.com>

For what it is worth, Franz's opinion is a bit dated (the article is
one year old, and it quotes information from two years before that).

The .NET Framework is designed for any programming language as long as
that programming language is Visual Basic or Java^H^H^H^H C#.  But
there are enough `escape' mechanisms to get around problems raised in
that article.  I'll address them in the reverse order:

  `3.  Method dispatch was compile-time only.'

No longer true.  Aside from `virtual' dispatch, you may also invoke
methods that are discovered through the reflection mechanism.  Thus
runtime method dispatch is quite easy.

  `2.  The type hierarchy is more tree-like than net and didn't allow
       for multiple inheritance.'

This is true, but somewhat irrelevant.  CLOS types would not generally
be mapped directly into .NET types.  There is an implementation of
Eiffel for .NET that supports multiple inheritence just fine.  The
technique used by Eiffel would work for CLOS as well.

  `1.  There was no way to specify a varying number of arguments in a
       call.'  

Again, the reflection mechanism will allow that.

Additionally, it is possible to dynamically replace the `JIT'
compiler.  The .NET Smalltalk implementation does just that in order
to achieve reasonable performance.

So it certainly would be *possible* to implement Common Lisp on the
.NET framework, but the framework as is does not provide *enough*
functionality to make it easy.
From: Mark Hurd
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3eff974a_1@news.iprimus.com.au>
Edi Weitz wrote:
> "Mark Hurd" <········@ozemail.com.au> writes:
>
> > This is what I've seen in general, that the .NET Framework provides
> > much of the functionality that sample Lisp code I have found on the
> > 'net expects to be provided by Lisp libraries (as you would expect
> > -- the .NET Framework is designed to be a suitable base for any
> > programming language).
>
> People who've looked closer don't share your opinion:
>
>   http://groups.google.com/groups?selm=47kp4j52c.fsf%40beta.franz.com

Sorry, in private communication Rich Hickey explained these deficiencies and I
agree with them. NB the post above mentions it was based upon early (perhaps
alpha) versions of .NET, but the issues are still present in the RTM 1.1
version. (Loosing varargs is a spectacular loss, even for C programmers -- 
it's possible but performance is bad and VB users know that is a de facto
obsolition flag!)

What I was referring to above was that the .NET Framework provides a rich (or
at least useful enough) runtime library.

Perhaps you could see DotLisp as Lisp scripting language for .NET. Like
VBScript, it has a similar syntax to its namesake, but not "complete"
compatibility.

I suppose the summary is that I have found it to be rather useful -- always a
good measure of a language...
-- 
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.06.30.01.20.37.428518@consulting.net.nz>
Hi Mark Hurd,

>> > http://www.richhickey.com/dotlisp.htm
>>
>> It's so superficially Lisp. Even the "little" things don't appear to
>> work like Common Lisp (although Rich Hickey claims his philosophy is
>> "retaining the essence of Lisp as a language"). Could part of that
>> essence be adding two integers and providing the wrong result?
>>
>>     1, 2, -3
>>
>> Integers (System.Int32)
>>
>>
> <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/f
> rlrfsystemint32classtopic.asp>
>> "Represents a 32-bit signed integer."
>>
>> So how do Common Lisp and DotLisp compare when performing this
>> calculation: (+ 2000000000 1000000000)
>>
>> (This is not rhetorical, I don't run a Microsoft .Net/DotLisp
>> environment and would like to confirm the answer).
> 
> Yes, it definitely isn't Common Lisp. Note that the source was from a
> Scheme dialect.
> And if it was to be CL, it'd need to be a Lisp-2, for a start.

I wouldn't classify it as a Lisp. Lisps attempt to do the right thing
for at least some reasonable boundaries of right. To my mind not even
returning the correct result for integer arithmetic puts it out of
contention.

Note that most Scheme dialects more or less adhere to RxRS. In particular:
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2.1

   Although an implementation of Scheme may use fixnum, flonum, and
   perhaps other representations for numbers, this should not be apparent
   to a casual programmer writing simple programs.

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2.3

   Implementations are encouraged, but not required, to support exact
   integers and exact rationals of practically unlimited size and
   precision, and to implement the above procedures and the / procedure in
   such a way that they always return exact results when given exact
   arguments. If one of these procedures is unable to deliver an exact
   result when given exact arguments, then it may either report a
   violation of an implementation restriction or it may silently coerce
   its result to an inexact number. Such a coercion may cause an error
   later.

> DotLisp:
>> (+ 2000000000 1000000000)
> -1294967296

As predicted we just get a hopeless answer.

>> (+ (Decimal:Parse "2000000000") (Decimal:Parse "1000000000"))
> 3000000000
>
> 
> The above shows that the .NET Framework has Decimals which have a larger
> range than Long, but Rich's current implementation only stores to longs.

Thanks I appreciate the reply and information. The above also shows a
philosophy of doing the wrong thing fast and fixing the program afterwards. 
I'd rather do the right thing first and optimise afterwards.

Note that Common Lisp doesn't default to arguably doing the right thing in
preserving the accuracy of real numbers in source code. If I write
1234.00005678 in source code there's probably a reason that I included all
those significant figures. Yet it will be read in as a short float:

* 1234.00005678

1234.0

Arguably doing the right thing would read this in as a double float by
default so if one forgets a d0 at the end of the number the calculations
aren't less accurate than intended:

* 1234.00005678d0

1234.00005678d0

All I'm recognising is that there is different information in the
text representation of a number like 1.00000 compared to the number
1.0000000000.

I'd like to see a super-intelligent Lisp consider choosing an internal
level of accuracy that can print back the number identically to the same
number of significant figures as the number in the source code, up to the
level of accuracy supported by the implementation. To override one would
just have to include s0 after numbers with more significant figures but
still intended to be short reals. Then the default is to do the right
thing first, optimise afterwards.

Also consider larger numbers. There is still different information
provided by the text representation 1000000000.0 compared to 1.0e9. The
first number can only be printed back identically as a double float. The
second can be printed back identically when stored as a single float.

It just seems a shame that Common Lisp has useful contagion rules that
don't get an opportunity to work if numbers aren't first read in to a high
enough accuracy.

Regards,
Adam
From: Kalle Olavi Niemitalo
Subject: Re: newbie needs some direction
Date: 
Message-ID: <87vfun3old.fsf@Astalo.kon.iki.fi>
Adam Warner <······@consulting.net.nz> writes:

> I wouldn't classify it as a Lisp. Lisps attempt to do the right thing
> for at least some reasonable boundaries of right. To my mind not even
> returning the correct result for integer arithmetic puts it out of
> contention.

Emacs Lisp gives a wrong result, too.
From: Thomas F. Burdick
Subject: Re: newbie needs some direction
Date: 
Message-ID: <xcv3chrv3ot.fsf@famine.OCF.Berkeley.EDU>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Adam Warner <······@consulting.net.nz> writes:
> 
> > I wouldn't classify it as a Lisp. Lisps attempt to do the right thing
> > for at least some reasonable boundaries of right. To my mind not even
> > returning the correct result for integer arithmetic puts it out of
> > contention.
> 
> Emacs Lisp gives a wrong result, too.

True, but the ancient Lisps that it patterendd itself after didn't.
And in many ways, Emacs Lisp is an unholy hybrid of Lisp and C/Unix.
In fact, its lack of support for a reasonable numeric tower is one of
the main reasons I find Emacs unsuitable for use as a real proramming
platform: you know, something other than editing-related programs.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.06.30.10.10.22.55448@consulting.net.nz>
Hi Kalle Olavi Niemitalo,

>> I wouldn't classify it as a Lisp. Lisps attempt to do the right thing
>> for at least some reasonable boundaries of right. To my mind not even
>> returning the correct result for integer arithmetic puts it out of
>> contention.
> 
> Emacs Lisp gives a wrong result, too.

"High on the list of things Lisp offers that most other languages botch is
the idea that (+ x 1) for any integer x should return a number bigger than
x in all cases.  It seems like such a small point, but it's often quite
useful."
                                            Kent M Pitman, 16 October 2001

Cheers,
Adam
From: Rich Hickey
Subject: Re: newbie needs some direction
Date: 
Message-ID: <bdq61m$vjb$1@sun-news.laserlink.net>
The behavior reported by Mark is a bug (Int32 arithmetic was not 
'checked', all other arithmetic was, as were all conversions). The 
current (fixed) behavior for your example is:

DotLisp:
 > (+ 2000000000 1000000000)
!Exception: Arithmetic operation resulted in an overflow.

A cleaner way to work with large integers than he suggested:

DotLisp:
 > (+ (Decimal. 2000000000) (Decimal. 1000000000))
3000000000

DotLisp is not Common Lisp and makes no claims to be compatible. The 
fact that Common Lisp may be in every way superior in no way diminishes 
the utility of DotLisp for those working in a .Net environment.

My experience is that .Net programmers understand and accept the 
limitations of Int32 arithmetic and desire it as the default, and can 
easily reach for Int64 or Decimal  when the need arises, which, for many 
applications, is never, and for them the current behavior is the right 
thing and will never require fixing. Note that I am not arguing against 
the virtues of unlimited size integers; however, none are provided by 
.Net and there are interoperability issues when each language comes up 
with its own implementation. Working with known-size integers has its 
merits in an interoperability context, which is the context for DotLisp. 
I could, for instance, easily handle the overflow exception and promote 
the Int32's to Int64 or Decimal, but I think the .Net programmer would 
to prefer to see the problem on overflow, rather than on the narrowing 
conversion that comes about when trying to pass the result to another 
function which expects Int32. DotLisp does support a kind of contagion, 
i.e. Int32 + Int64 => Int64, Int32 + Double => Double.

It certainly is an experiment to try to build a Lisp with the 
fundamental types supplied by the .Net environment, i.e. to separate the 
types and the library from the language. That is what DotLisp is about, 
and it involves compromises. If you consider the result only 
"superficially Lisp", oh well.

My turnabout (rhetorical ;-) question is: how can one easily 
interoperate with CLR libraries and applications from Common Lisp? Since 
you don't have the evironment, I'll give you the answer - one can't. I 
don't see how Common Lisp is doing is the right thing, or anything, for 
people with that need. If Xanalys or anyone else comes up with a 
solution, I'll gladly pay.

Regards,

Rich

Adam Warner wrote:
> Hi Mark Hurd,
> 
> 
>>>>http://www.richhickey.com/dotlisp.htm
>>>
>>>It's so superficially Lisp. Even the "little" things don't appear to
>>>work like Common Lisp (although Rich Hickey claims his philosophy is
>>>"retaining the essence of Lisp as a language"). Could part of that
>>>essence be adding two integers and providing the wrong result?
>>>
>>>    1, 2, -3
>>>
>>>Integers (System.Int32)
>>>
>>>
>>
>><http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/f
>>rlrfsystemint32classtopic.asp>
>>
>>>"Represents a 32-bit signed integer."
>>>
>>>So how do Common Lisp and DotLisp compare when performing this
>>>calculation: (+ 2000000000 1000000000)
>>>
>>>(This is not rhetorical, I don't run a Microsoft .Net/DotLisp
>>>environment and would like to confirm the answer).
>>
>>Yes, it definitely isn't Common Lisp. Note that the source was from a
>>Scheme dialect.
>>And if it was to be CL, it'd need to be a Lisp-2, for a start.
> 
> 
> I wouldn't classify it as a Lisp. Lisps attempt to do the right thing
> for at least some reasonable boundaries of right. To my mind not even
> returning the correct result for integer arithmetic puts it out of
> contention.
> 
> Note that most Scheme dialects more or less adhere to RxRS. In particular:
> http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2.1
> 
>    Although an implementation of Scheme may use fixnum, flonum, and
>    perhaps other representations for numbers, this should not be apparent
>    to a casual programmer writing simple programs.
> 
> http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2.3
> 
>    Implementations are encouraged, but not required, to support exact
>    integers and exact rationals of practically unlimited size and
>    precision, and to implement the above procedures and the / procedure in
>    such a way that they always return exact results when given exact
>    arguments. If one of these procedures is unable to deliver an exact
>    result when given exact arguments, then it may either report a
>    violation of an implementation restriction or it may silently coerce
>    its result to an inexact number. Such a coercion may cause an error
>    later.
> 
> 
>>DotLisp:
>>
>>>(+ 2000000000 1000000000)
>>
>>-1294967296
> 
> 
> As predicted we just get a hopeless answer.
> 
> 
>>>(+ (Decimal:Parse "2000000000") (Decimal:Parse "1000000000"))
>>
>>3000000000
>>
>>
>>The above shows that the .NET Framework has Decimals which have a larger
>>range than Long, but Rich's current implementation only stores to longs.
> 
> 
> Thanks I appreciate the reply and information. The above also shows a
> philosophy of doing the wrong thing fast and fixing the program afterwards. 
> I'd rather do the right thing first and optimise afterwards.
> 
> Note that Common Lisp doesn't default to arguably doing the right thing in
> preserving the accuracy of real numbers in source code. If I write
> 1234.00005678 in source code there's probably a reason that I included all
> those significant figures. Yet it will be read in as a short float:
> 
> * 1234.00005678
> 
> 1234.0
> 
> Arguably doing the right thing would read this in as a double float by
> default so if one forgets a d0 at the end of the number the calculations
> aren't less accurate than intended:
> 
> * 1234.00005678d0
> 
> 1234.00005678d0
> 
> All I'm recognising is that there is different information in the
> text representation of a number like 1.00000 compared to the number
> 1.0000000000.
> 
> I'd like to see a super-intelligent Lisp consider choosing an internal
> level of accuracy that can print back the number identically to the same
> number of significant figures as the number in the source code, up to the
> level of accuracy supported by the implementation. To override one would
> just have to include s0 after numbers with more significant figures but
> still intended to be short reals. Then the default is to do the right
> thing first, optimise afterwards.
> 
> Also consider larger numbers. There is still different information
> provided by the text representation 1000000000.0 compared to 1.0e9. The
> first number can only be printed back identically as a double float. The
> second can be printed back identically when stored as a single float.
> 
> It just seems a shame that Common Lisp has useful contagion rules that
> don't get an opportunity to work if numbers aren't first read in to a high
> enough accuracy.
> 
> Regards,
> Adam
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <smpq1ff0.fsf@ccs.neu.edu>
Rich Hickey <··········@nnosspamrichhickey.com> writes:

> My experience is that .Net programmers understand and accept the
> limitations of Int32 arithmetic 

I bet they know and understand that certain operations on Int32
produce answers that are outside the representation space, but I doubt
they fully understand the ramifications of that.  I bet they know the
rule of thumb that Int32 provides a fairly reasonable model for
integers with absolute value much, much smaller than 2^31.

> and desire it as the default, 

I seriously doubt this.  All other things being equal, why would
anyone prefer an approximation to integers?  Int32 works like
integers, except that errors can be thrown during add, subtract, and
multiply as well as divide.  More exceptions means more work for the
programmer.

I know that in some cases you would like to perform operations on a
subset of integers.  For instance, suppose you have a 5-bit field and
wish to do arithmetic mod 32.  While Int32 will throw an error if your
intermediate results are wildly out of bounds, but `Int5' is a far
better model.

Unless you are working *specifically* with 32-bit signed integers,
Int32 is not what you want.
 
> and can easily reach for Int64 or Decimal when the need arises,
> which, for many applications, is never, and for them the current
> behavior is the right thing and will never require fixing.

Int32 will suffice in a great many cases.  And if it is all you have,
well, cross your fingers and hope it won't require fixing.  But if you
use integers, then you don't have to cross your fingers if you perhaps
underestimated how wide that integer needed to be.

> Note that I am not arguing against the virtues of unlimited size
> integers; however, none are provided by .Net and there are
> interoperability issues when each language comes up with its own
> implementation.

There are *always* interoperability issues.  Bignums are just one of
them, and far easier to deal with than, say, classes and structures.

> I could, for instance, easily handle the overflow exception and
> promote the Int32's to Int64 or Decimal, but I think the .Net
> programmer would to prefer to see the problem on overflow, rather
> than on the narrowing conversion that comes about when trying to
> pass the result to another function which expects Int32.  DotLisp
> does support a kind of contagion, i.e. Int32 + Int64 => Int64, Int32
> + Double => Double.

I'd prefer to not see a problem with overflow *or* narrowing.

> My turnabout (rhetorical ;-) question is: how can one easily
> interoperate with CLR libraries and applications from Common Lisp?
> Since you don't have the evironment, I'll give you the answer - one
> can't.  

Oh?  News to me.  Here's how I create a new .NET type dynamically from
Scheme (yeah, it ain't CL, but the principle is the same).

(define (make-hello)
  (with-dotnet-type-builder (type-builder '|Runtime| nil '())
      (let* ((method-builder (.DefineMethod type-builder 
                                            '|Hello|
                                            (clr/enumerate-union
                                             System.Reflection.MethodAttributes.Public$
                                             System.Reflection.MethodAttributes.Static$)
                                            System.Object.class
                                            (vector System.String.class)))
             (il-generator   (.GetILGenerator method-builder)))
        (.Emit il-generator '|Nop|)
        (.Emit il-generator '|Nop|)
        (.Emit il-generator '|Ldarg_0|)
        (.EmitString il-generator "Ldstr" "Hello world.")
        (.EmitInt32 il-generator "Ldc_I4" 42)
        (.Emit il-generator '|Ret|))))

I'm rather upset that this code can't work.  I wonder what was
printing out `hello world'?

> I don't see how Common Lisp is doing is the right thing, or
> anything, for people with that need.  If Xanalys or anyone else comes
> up with a solution, I'll gladly pay.

How much?
From: Rich Hickey
Subject: Re: newbie needs some direction
Date: 
Message-ID: <bdsnbm$aqd$1@sun-news.laserlink.net>
Joe Marshall wrote:

(snip)

> Unless you are working *specifically* with 32-bit signed integers,
> Int32 is not what you want.

Actually, it is what I want for DotLisp (but not CL)

(snip)

> I'd prefer to not see a problem with overflow *or* narrowing.

If at the end of the day you need to call an API that takes an Int32 as 
input there is no way to avoid it.

> 
> 
>>My turnabout (rhetorical ;-) question is: how can one easily
>>interoperate with CLR libraries and applications from Common Lisp?
>>Since you don't have the evironment, I'll give you the answer - one
>>can't.  
> 
> 
> Oh?  News to me.  Here's how I create a new .NET type dynamically from
> Scheme (yeah, it ain't CL, but the principle is the same).

(snip)

Actually it is not at all the same, but very cool nonetheless. What 
implementation of Scheme are you using?

>>I don't see how Common Lisp is doing is the right thing, or
>>anything, for people with that need.  If Xanalys or anyone else comes
>>up with a solution, I'll gladly pay.
> 
> 
> How much?

$1000 more than their regular price.
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <brwe11c4.fsf@ccs.neu.edu>
Rich Hickey <··········@nnosspamrichhickey.com> writes:

>>> My turnabout (rhetorical ;-) question is: how can one easily
>>> interoperate with CLR libraries and applications from Common Lisp?
>>> Since you don't have the evironment, I'll give you the answer - one
>>> can't.

> Joe Marshall wrote:
> 
> > Oh?  News to me.  Here's how I create a new .NET type dynamically
> > from
> 
> > Scheme (yeah, it ain't CL, but the principle is the same).
> 
> (snip)
> 
> Actually it is not at all the same, but very cool nonetheless. What
> implementation of Scheme are you using?

PLT Scheme available at www.drscheme.org

Note that the code you saw only runs on my hacked version, not the
general release, and I have no plans to release it (it is scaffolding
code pending the completion of the Scheme->.NET compiler).

> >>I don't see how Common Lisp is doing is the right thing, or
> >>anything, for people with that need.  If Xanalys or anyone else comes
> >>up with a solution, I'll gladly pay.
> > How much?
> 
> $1000 more than their regular price.

A whole $1000 bucks, eh?
From: Daniel Barlow
Subject: Re: newbie needs some direction
Date: 
Message-ID: <877k71w4v4.fsf@noetbook.telent.net>
Rich Hickey <··········@nnosspamrichhickey.com> writes:

> Joe Marshall wrote:
>
> (snip)
>
>> Unless you are working *specifically* with 32-bit signed integers,
>> Int32 is not what you want.
>
> Actually, it is what I want for DotLisp (but not CL)

OK, it's what _you_ want.  I'm going to reword Joe's statement very
slightly to say

  Unless one is working *specifically* with 32-bit signed integers,
  Int32 is not what one wants.

and with the kind of blatant chutzpah that's only legal for use by
holders of full Usenet driving licenses, claim that this assertion is
generally true of the Lisp community.  I cite the other responses in
this thread as support - if you want to know whether something is
really X or only superficially X, I think that canvassing the opinions
of X users is (at leats in this case) a pretty good method.  The
Masses Have Spoken.

>> I'd prefer to not see a problem with overflow *or* narrowing.
>
> If at the end of the day you need to call an API that takes an Int32
> as input there is no way to avoid it.

If you only need to call the API at the end of the day, why are you
doing the cast at lunchtime?  It's not inconveivable that intermediate
values may overflow Int32 but that the final result still fits inside
it

Yes, I know there are efficiency concerns with that approach.  It's an
efficiency/correctness tradeoff, and (in my opinion, which I believe
is widely shared) one in which the Lisp way is to come down on the
correctness side.


-dan

-- 

   http://www.cliki.net/ - Link farm for free CL-on-Unix resources 
From: Rich Hickey
Subject: Re: newbie needs some direction
Date: 
Message-ID: <bdunor$qto$1@sun-news.laserlink.net>
I appreciate your and everyone else's input. I am emphatically not 
making a general argument against unlimited size integers and think it 
is one of the great features of CL.

It is a matter of convenience, not correctness, that overflow is avoided 
by consuming memory rather than reported via exception (I have at no 
point condoned truncation or wraparound in DotLisp, my bug 
notwithstanding). And of course, nothing is unlimited in software. 
Common Lisp is full of limits.

Your point about intermediate out-of-range but resulting in-range values 
taken, DotLisp lives in a statically typed world absolutely permeated 
with hard numeric limits. Its users are most interested in interacting 
with the .Net Framework API in which every other function specifies 
Int32. They are the masses for whom it is designed and whose opinion 
matters. Of course, they are great, unwashed, and Lisp ignorant, and I 
only mention them to highlight that neither your masses, mine, you or me 
are 'right'. Not that I am against debates in the pursuit of some 
abstract notion of right, but this one seems to have run its course. 
Design involves tradeoffs made in a context, and I've made a different 
decision than you (all ;-) would have.

I would like to note that the arithmetic operators +, -, * etc are 
(built on top of) generic functions in DotLisp, and if a user wants to 
build a bignum class and provide methods for it they are free to do so.

Regards,

Rich

Daniel Barlow wrote:
> Rich Hickey <··········@nnosspamrichhickey.com> writes:
> 
> 
>>Joe Marshall wrote:
>>
>>(snip)
>>
>>
>>>Unless you are working *specifically* with 32-bit signed integers,
>>>Int32 is not what you want.
>>
>>Actually, it is what I want for DotLisp (but not CL)
> 
> 
> OK, it's what _you_ want.  I'm going to reword Joe's statement very
> slightly to say
> 
>   Unless one is working *specifically* with 32-bit signed integers,
>   Int32 is not what one wants.
> 
> and with the kind of blatant chutzpah that's only legal for use by
> holders of full Usenet driving licenses, claim that this assertion is
> generally true of the Lisp community.  I cite the other responses in
> this thread as support - if you want to know whether something is
> really X or only superficially X, I think that canvassing the opinions
> of X users is (at leats in this case) a pretty good method.  The
> Masses Have Spoken.
> 
> 
>>>I'd prefer to not see a problem with overflow *or* narrowing.
>>
>>If at the end of the day you need to call an API that takes an Int32
>>as input there is no way to avoid it.
> 
> 
> If you only need to call the API at the end of the day, why are you
> doing the cast at lunchtime?  It's not inconveivable that intermediate
> values may overflow Int32 but that the final result still fits inside
> it
> 
> Yes, I know there are efficiency concerns with that approach.  It's an
> efficiency/correctness tradeoff, and (in my opinion, which I believe
> is widely shared) one in which the Lisp way is to come down on the
> correctness side.
> 
> 
> -dan
> 
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003jul26-004@Yahoo.Com>
{{Date: Wed, 02 Jul 2003 09:51:00 -0400
  From: Rich Hickey <··········@nnosspamrichhickey.com>
  if a user wants to build a bignum class and provide methods for it
  they are free to do so.}}

This would take us back to before MacLISP. In another thread, somebody
answered the major reason why Common LISP is so large, why it defines
so many useful functions instead of defining just a subset and letting
programmers add the rest via optional modules. In the MacLISP days,
that's exactly what happened, where five different programmers would
implement a similar idea five different ways, and then code that used
these five modules would not be interoperable. Common LISP assures that
a particular common thing will always have the same definition, so that
all programs can use the same thing, and all programs will be
interoperable at that level. What Rich proposes would take us back to
where not only the stuff that was bad in MacLISP would be bad again,
but stuff that MacLISP had already fixed would be bad too. Furthermore,
in this particular case, BIGNUM arithmetic is not something trivial to
get correct and decently efficient (via FFT-like algorithms).
From: Pascal Costanza
Subject: Re: newbie needs some direction
Date: 
Message-ID: <bduie9$vrc$1@f1node01.rhrz.uni-bonn.de>
Daniel Barlow wrote:
> Rich Hickey <··········@nnosspamrichhickey.com> writes:
> 
>>Joe Marshall wrote:
>>
>>(snip)
>>
>>
>>>Unless you are working *specifically* with 32-bit signed integers,
>>>Int32 is not what you want.
>>
>>Actually, it is what I want for DotLisp (but not CL)
> 
> 
> OK, it's what _you_ want.  I'm going to reword Joe's statement very
> slightly to say
> 
>   Unless one is working *specifically* with 32-bit signed integers,
>   Int32 is not what one wants.
> 
> and with the kind of blatant chutzpah that's only legal for use by
> holders of full Usenet driving licenses, claim that this assertion is
> generally true of the Lisp community.  I cite the other responses in
> this thread as support - if you want to know whether something is
> really X or only superficially X, I think that canvassing the opinions
> of X users is (at leats in this case) a pretty good method.  The
> Masses Have Spoken.

For the sake of completeness, one should note that reasonable arguments 
had been put forward in the past that criticize the Common Lisp approach 
of "Do The Right Thing" (tm), especially in the case of arithmetics. See 
http://www.dreamsongs.com/NewFiles/clcrit.pdf [1]

This is to say that Rich's approach is not that stupid, especially 
because he points out on his website that he wants to "provide a 
framework for language experimentation". At least I hope this means that 
his design is not finalized.

Furthermore, a reasonable next step could be to implement correct 
arithmetics on top of Int32 and Int64, as classes expressed in DotLisp, 
right?


(And to make this absolutely clear: I highly prefer Common Lisp's 
approach wrt correct arithmetics.)


Pascal

[1] Of course, Common Lisp implementations have advanced a lot since the 
publication of that paper. So not all of the criticism in that paper is 
still valid.

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.07.02.13.04.18.785090@consulting.net.nz>
Hi Pascal Costanza,

> For the sake of completeness, one should note that reasonable arguments
> had been put forward in the past that criticize the Common Lisp approach
> of "Do The Right Thing" (tm), especially in the case of arithmetics. See
> http://www.dreamsongs.com/NewFiles/clcrit.pdf [1]

How much substance is there in this criticism?

   4. Common Lisp is Bad

   4.1 Generic Arithmetic

   One of the major ways that COMMON LISP falls down is that all
   arithmetic is generic. Although this might be a good idea for people
   whose use of arithmetic involves adding a couple of numbers every
   several hundred million instructions, it is not a good idea for those
   who want to write a lot of numeric code for non-Lisp machines.

   Currently there is no computer that excels at both Lisp processing and
   numeric processing. For people who want to do number-crunching in Lisp
   on such machines, writing type-specific numeric code requires wordy
   type-declarations. To write an addition of two integers requires
   writing either:

                                (DECLARE (integer x y))
                                (+ x y)
      or:

                            (+ (the integer x) (the integer y))

   Neither of these is esthetically pleasing, nor is it likely that the
   average Lisp programmer is going to bother all the time.

   Micro-coded machines have an advantage in that they can leave until
   runtime decisions about what the types of objects are. For example, one
   could write (+ x y) in COMMON LISP and a micro-coded machine could
   determine the types of x and y on the fly.


Can someone please confirm whether it is legal to create macros that
also generate their own declarations. If declarations are such an
aesthetic problem why can't I provide a solution by:

(defmacro integer+ (x y)
  `(+ (the integer ,x) (the integer ,y)))

Or more generally:

(defmacro integer+ (&rest args)
  `(+ ,@(loop for x in args collect `(the integer ,x))))

(macroexpand '(integer+ x y z))
(+ (the integer x) (the integer y) (the integer z))

There must be something I'm missing because I can't imagine Brooks and
Gabriel could so easily overlook macrology.

Regards,
Adam
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <d6gtc9np.fsf@ccs.neu.edu>
Adam Warner <······@consulting.net.nz> writes:

> Can someone please confirm whether it is legal to create macros that
> also generate their own declarations. If declarations are such an
> aesthetic problem why can't I provide a solution by:
> 
> (defmacro integer+ (x y)
>   `(+ (the integer ,x) (the integer ,y)))
> 

This is legal.  However, it may not optimize completely.

This will more likely turn into a machine add instruction:
 
(defmacro fix+ (x y)
  `(the fixnum (+ (the fixnum ,x) (the fixnum ,y))))

For a project I worked on I created a `FIXNUM-ARITHMETIC' package that
shadowed the standard numeric operators.  In other code, you could
either refer to the operators explicitly:

   (let ((foo (fix:+ a b)))
      ...)

or SHADOWING-IMPORT from the package.

Incidentally, there are some more tricks that you would want to do.
Suppose I wrote this code:  (fix:+ (the (integer 0 (10)) x) y)

I don't want the fixnum math package to `override' my declaration, so fix:+ 
ought to check that whether its argument is a THE form and act
accordingly. 

> There must be something I'm missing because I can't imagine Brooks and
> Gabriel could so easily overlook macrology.

Well, it is a bit harder than what macrology can do alone, but some
decent macrology can get you 90% of the way there.  Macros can only do
a crude amount of type inference and really ought to have help from
the compiler.  They also have no (portable) access to the current set
of declarations at the call site.
From: Christophe Rhodes
Subject: Re: newbie needs some direction
Date: 
Message-ID: <sq65mlqazs.fsf@lambda.jcn.srcf.net>
Joe Marshall <···@ccs.neu.edu> writes:

> Incidentally, there are some more tricks that you would want to do.
> Suppose I wrote this code:  (fix:+ (the (integer 0 (10)) x) y)
>
> I don't want the fixnum math package to `override' my declaration, so fix:+ 
> ought to check that whether its argument is a THE form and act
> accordingly. 

What's wrong with
  (the fixnum (+ (the fixnum (the (integer 0 (10)) x))
                 (the fixnum y)))
?  It looks straightforwardly correct to me.  The outer declarations
shouldn't in any sense `override' the inner ones.

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <1xx9c8k0.fsf@ccs.neu.edu>
Christophe Rhodes <·····@cam.ac.uk> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
> 
> > Incidentally, there are some more tricks that you would want to do.
> > Suppose I wrote this code:  (fix:+ (the (integer 0 (10)) x) y)
> >
> > I don't want the fixnum math package to `override' my declaration, so fix:+ 
> > ought to check that whether its argument is a THE form and act
> > accordingly. 
> 
> What's wrong with
>   (the fixnum (+ (the fixnum (the (integer 0 (10)) x))
>                  (the fixnum y)))
> ?  It looks straightforwardly correct to me.  The outer declarations
> shouldn't in any sense `override' the inner ones.

When you have a form like this  (the fixnum <any form>)
you are saying to the compiler: ` forget what you *think* you know, the
result is a fixnum.'  This is true even if the inner form is something
like (the (integer 0 (10)) x).

So suppose that we had written  

(defun foo (x y z)
  (declare (type (integer 0 (10)) x y z))
  (+ x (+ y z)))

The compiler can prove that (+ y z) is of type (integer 0 (19)), thus
the outer addition can be a fixnum add.  If, however, we wrote this:

(defun foo (x y z)
  (declare (type (integer 0 (10)) x y z))
  (+ x (fix:+ y z)))

By unconditionally instructing the compiler that the result is an
unspecified FIXNUM, it can no longer prove that the outer result is a
fixnum, and it has to check for overflow and such.  Our `improvement'
to the code made it worse.

So we only want to wrap `(THE FIXNUM ...) around a form if the type of
the form is less restrictive than FIXNUM.  Otherwise, we want to leave
it alone.  We can do this with macros in many cases, but not all.
From: Christophe Rhodes
Subject: Re: newbie needs some direction
Date: 
Message-ID: <sq1xx9q9dq.fsf@lambda.jcn.srcf.net>
Joe Marshall <···@ccs.neu.edu> writes:

> Christophe Rhodes <·····@cam.ac.uk> writes:
>
>> What's wrong with
>>   (the fixnum (+ (the fixnum (the (integer 0 (10)) x))
>>                  (the fixnum y)))
>> ?  It looks straightforwardly correct to me.  The outer declarations
>> shouldn't in any sense `override' the inner ones.
>
> When you have a form like this  (the fixnum <any form>)
> you are saying to the compiler: ` forget what you *think* you know, the
> result is a fixnum.'

Really?  What makes you say that?  I'd have thought that
  (the fixnum <any form>)
meant `the result is of the type of the intersection of FIXNUM and
whatever you know.'

> By unconditionally instructing the compiler that the result is an
> unspecified FIXNUM, it can no longer prove that the outer result is a
> fixnum, and it has to check for overflow and such.  Our `improvement'
> to the code made it worse.
>
> So we only want to wrap `(THE FIXNUM ...) around a form if the type of
> the form is less restrictive than FIXNUM.  Otherwise, we want to leave
> it alone.  We can do this with macros in many cases, but not all.

(defun foo (x y)
  (+ (the fixnum (the (integer 0 (10)) x))
     (the fixnum (the (integer 0 (10)) y))))

when compiled under sbcl, yields

* (sb-kernel:extract-fun-type #'foo)

#<SB-KERNEL:FUN-TYPE (FUNCTION (T T) (VALUES (MOD 19) &OPTIONAL))>

Which compilers don't behave in this way?

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <vfukbu9o.fsf@ccs.neu.edu>
Christophe Rhodes <·····@cam.ac.uk> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
> 
> > Christophe Rhodes <·····@cam.ac.uk> writes:
> >
> >> What's wrong with
> >>   (the fixnum (+ (the fixnum (the (integer 0 (10)) x))
> >>                  (the fixnum y)))
> >> ?  It looks straightforwardly correct to me.  The outer declarations
> >> shouldn't in any sense `override' the inner ones.
> >
> > When you have a form like this  (the fixnum <any form>)
> > you are saying to the compiler: ` forget what you *think* you know, the
> > result is a fixnum.'
> 
> Really?  What makes you say that?  I'd have thought that
>   (the fixnum <any form>)
> meant `the result is of the type of the intersection of FIXNUM and
> whatever you know.'

I see your point.  Given that it is only legal for the inner form to
be of type (integer 0 (10)), and only legal for the outer form to be
fixnum, the only conforming values would have to be the intersection.
From: Kalle Olavi Niemitalo
Subject: Re: newbie needs some direction
Date: 
Message-ID: <87vfulf1kc.fsf@Astalo.kon.iki.fi>
Joe Marshall <···@ccs.neu.edu> writes:

> Suppose I wrote this code:  (fix:+ (the (integer 0 (10)) x) y)
>
> I don't want the fixnum math package to `override' my declaration, so fix:+ 
> ought to check that whether its argument is a THE form and act
> accordingly. 

I would expect (the TYPE-1 (the TYPE-2 FORM)) to mean the same
as (the (and TYPE-1 TYPE-2) FORM).  Because (integer 0 (10)) is a
subtype of FIXNUM, the right thing should happen automatically.
From: Mark Hurd
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f027f71_1@news.iprimus.com.au>
Rich Hickey wrote:
> Joe Marshall wrote:
>
> (snip)
>
> > Unless you are working *specifically* with 32-bit signed integers,
> > Int32 is not what you want.
>
> Actually, it is what I want for DotLisp (but not CL)

Yes, it comes back to the intended, expected or targeted users. Is it CL users
or Microsoft users? We've had the Int16+Int16 overflow issue with all VB
versions.

> (snip)
>
> > I'd prefer to not see a problem with overflow *or* narrowing.
>
> If at the end of the day you need to call an API that takes an Int32 as
> input there is no way to avoid it.

Yes, similar to what I've said above.

Note however, that (nth N (circular 'a 'b 'c)) -- as discussed in another
recent thread -- has an issue when N is greater than Int32.MaxValue (but the
error message when you use a value greater than Int32.MaxValue is good).

DotLisp:
> (def (circular &rest list) (let (c list)(set (rest (last c)) c)))
{Closure ((list REST ) )}
> (nth 1 (circular 'a 'b 'c))
b
> (nth 10 (circular 'a 'b 'c))
b
> (nth 100 (circular 'a 'b 'c))
b
> (nth 10000000 (circular 'a 'b 'c))
b
> (nth 100000000 (circular 'a 'b 'c))
b
> (nth 1000000000 (circular 'a 'b 'c))
b
> (nth 10000000000 (circular 'a 'b 'c))
c
> (nth 100000000000 (circular 'a 'b 'c))
c
> (nth 1000000000000 (circular 'a 'b 'c))
a
> (nth 10000000000000 (circular 'a 'b 'c))
b
> 10000000
10000000
> 100000000
100000000
> 1000000000
1000000000
> 10000000000
1410065408
> 100000000000
1215752192
> 1000000000000
-727379968
> 10000000000000
1316134912
> (Int64. 10000000000000)
1316134912
> (Int64. "10000000000000")
10000000000000
> (nth (Int64. "10000000000000") (circular 'a 'b 'c))
!Exception: Value was either too large or too small for an Int32.
> (nth (Int64. "10000000000") (circular 'a 'b 'c))
!Exception: Value was either too large or too small for an Int32.
> (nth (Int32. "10000000000") (circular 'a 'b 'c))
!Exception: Value was either too large or too small for an Int32.
>


> > > My turnabout (rhetorical ;-) question is: how can one easily
> > > interoperate with CLR libraries and applications from Common Lisp?
> > > Since you don't have the evironment, I'll give you the answer - one
> > > can't.
> >
> > Oh?  News to me.  Here's how I create a new .NET type dynamically from
> > Scheme (yeah, it ain't CL, but the principle is the same).
>
> (snip)

See the end of this post for DotLisp code doing the same thing -- as far as I
can guess was the intention.

> Actually it is not at all the same,

I believe Rich is refering to implementing class concepts in an interpreted,
or at least interactive, environment. Note that even Microsoft dropped the
immediate mode from VB.NET when no application was running.

That is, design a "defclass" where the method bodies are in Lisp, not IL
opcodes. Again this /is/ doable, but if you're in an interactive environment,
behind the scenes each time (defclass ClassName (...)) is processed you'll
have to build a new type and the old type is still present, or you get
"Duplicate type name within an assembly." exceptions as I did debugging the
code below.

> but very cool nonetheless.

Here's a DotLisp version:

;; This is a messy mix of styles -- I've tried to duplicate
;; the earlier post's original algorithm, but I've had to
;; guess the intent of some of it.
;;
(def *runtime-type-assembly* nil)
(def *runtime-type-module* nil)

;; This is a quick variation from Rich's boot.lisp code for generating
Delegate types.
(def-macro (with-dotnet-type-builder (builder-var type-name base-type) &rest
body)
`(block
   (when (nil? *runtime-type-assembly*)
     (set *runtime-type-assembly*
       (let (assembly-name (AssemblyName.))
        (set assembly-name.Name "HelloAssembly")
        (AppDomain:CurrentDomain.DefineDynamicAssembly assembly-name
          AssemblyBuilderAccess:Run))))
   (when (nil? *runtime-type-module*)
     (set *runtime-type-module* (*runtime-type-assembly*.DefineDynamicModule
"HelloModule")))
   (let (~builder-var (*runtime-type-module*.DefineType ~type-name
                                                       (bit-or
TypeAttributes:Class TypeAttributes:Public) ~base-type))
    ·@body
    (.CreateType ~builder-var))))

;; Not sure how the original code actually did anything other
;; than loading values on the stack, so I've coded the equivalent
;; of: (String:Format "{0}: {1}  {2}" MethodArg "Hello, world!" 42)
;; I changed it from a static to and instance method to simplfy the
;; demo, so it's Ldarg_1 to skip the Me/this reference.
(def (make-hello)
  (with-dotnet-type-builder (type-builder "HelloWorld" System.Object. )
      (lets (method-builder (.DefineMethod type-builder
                                            "Hello"

System.Reflection.MethodAttributes:Public
                                            System.Object.
                                            (vector-of System.Type.
System.String.))
             il-generator   (.GetILGenerator method-builder))
        (.Emit il-generator OpCodes:Ldstr "{0}: {1}  {2}")
        (.Emit il-generator OpCodes:Ldarg_1)
        (.Emit il-generator OpCodes:Ldstr "Hello, world!")
        (.Emit il-generator OpCodes:Ldc_I4 (Int32. 42))
        (.Emit il-generator OpCodes:Box Int32.)
        (.Emit il-generator OpCodes:Call (.GetMethod String. "Format"
(vector-of Type. String. Object. Object. Object.)))
        (.Emit il-generator OpCodes:Ret))))

;; lets == let*
;; prns prints a string, with a newline
;; InternType informs the interpreter of the new type,
;; allowing the "Last Test" to work below.
(def (hw-demo)
 (lets (hw-type (make-hello)
       hw1     (hw-type)
       hw2     (hw-type))
  (prns (.Hello hw1 "Test"))
  (prns (hw2.Hello "test2"))
  (interpreter.InternType hw-type)
  hw-type))

#|
Loading this: (Using my own REPL that prints string results without escapes &
quotes.)
F:\DOTNET\dotlisp\My Stuff>REPL ..\boot.lisp dyntype.lisp
loaded: ..\boot.lisp
loaded: dyntype.lisp
> (hw-demo)
Test: Hello, world!  42
test2: Hello, world!  42
HelloWorld
> (.Hello (HelloWorld.) "Last Test")
Last Test: Hello, world!  42
>
|#
-- 
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <isqlcacx.fsf@ccs.neu.edu>
"Mark Hurd" <········@ozemail.com.au> writes:

> I believe Rich is refering to implementing class concepts in an interpreted,
> or at least interactive, environment.  Note that even Microsoft dropped the
> immediate mode from VB.NET when no application was running.
> 
> That is, design a "defclass" where the method bodies are in Lisp, not IL
> opcodes.  Again this /is/ doable, but if you're in an interactive environment,
> behind the scenes each time (defclass ClassName (...)) is processed you'll
> have to build a new type and the old type is still present, or you get
> "Duplicate type name within an assembly." exceptions as I did debugging the
> code below.

The code I posted wasn't to illustrate that you could use lisp to emit
IL (although that's what it accomplished), it was to illustrate that
you can use and interact with .NET class instances from lisp (in this
case the IL reflection mechanism).

As a different example, I can type this at the prompt:

=> (setq *excel-application* (Microsoft.Office.Interop.Excel.ApplicationClass.))
     ... lots of disk whirring ...
#<Microsoft.Office.Interop.Excel.Application CA72230>

=> (setf (.Visible$ *excel-application*) 't)
  ... an excel window appears ...
t

=> (setq *excel-workbooks* (.Workbooks$ *excel-application*))
#<Microsoft.Office.Interop.Excel.Workbooks CA72280>

=> (setq *excel-workbook* (.Add *excel-workbooks*))
#<Microsoft.Office.Interop.Excel.Workbook CA72320>

=> (setq *excel-worksheets* (.Worksheets$ *excel-workbook*))
#<Microsoft.Office.Interop.Excel.Worksheets CA72350>

=> (setq *excel-active-sheet* (.ActiveSheet$ *excel-workbook*))
#<Microsoft.Office.Interop.Excel.Worksheet CA72370>

=> (defun get-cell (row col) (.Item$ (.Cells$ *excel-active-sheet*) row col))
GET-CELL

=> (setf (.Color$ (.Interior$ (get-cell 2 3))) 1184270)
 ... the cell changes color ...

and hack away at Excel spreadsheets.

The system I have uses the .NET reflection mechanism heavily in order
to discover .NET classes, fields, and methods `on the fly'.  In the
above example, when the system starts, it knows nothing about Excel
classes or methods.  When I called
Microsoft.Office.Interop.Excel.ApplicationClass. (the constructor), my
system queried .NET in order to resolve the class descriptor.  The
class descriptor was then examined to discover the fields and methods.
One of the fields was the `Visible' field.  Since it is not a
read-only field, a SETF method was generated for it.  The .NET type
system was reflected into Tiny CLOS via the Tiny CLOS MOP, so the .NET
methods and fields became lisp generic functions.

This all currently works, incidentally.
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003jul26-003@Yahoo.Com>
{{Date: Tue, 01 Jul 2003 15:31:42 -0400
  From: Rich Hickey <··········@nnosspamrichhickey.com>
  > I'd prefer to not see a problem with overflow *or* narrowing.
  If at the end of the day you need to call an API that takes an Int32
  as input there is no way to avoid it.}}

IMO: The right way is not to corrupt the entire language so that every
integer anywhere in the program is restricted to Int32 and suffers
silent overflow trashing in random places. The right way is to keep
full precision right up to the point where we know a particular value
needs to be sent to an Int32 port on the API, and at that point if the
value can't be coerced to Int32 because it's out of range then issue a
clear error message explaining which Int32 port had the out of range
value, and where in the user program this problem occurred, possibly
with backtrace from the point of failure up to whatever event handler
was running. For example, something like this, where val is the
floating-point or other value coming in from the LISP program:
  (let* ((fixval (round val))
         (apival (if (typep fixval '(signed-byte 32))
                     (coerce-unboxmumble fixval '(signed-byte 32))
                   (error "Value out of range, to pass to API:..."))))
    (API:whatever apival)))
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.07.01.02.46.11.919350@consulting.net.nz>
Hi Rich Hickey,

> The behavior reported by Mark is a bug (Int32 arithmetic was not
> 'checked', all other arithmetic was, as were all conversions). The
> current (fixed) behavior for your example is:
> 
> DotLisp:
>  > (+ 2000000000 1000000000)
> !Exception: Arithmetic operation resulted in an overflow.

Glad to have been of assistance in uncovering the data corruption.

> A cleaner way to work with large integers than he suggested:
> 
> DotLisp:
>  > (+ (Decimal. 2000000000) (Decimal. 1000000000))
> 3000000000

This is only cleaner because one knows in advance that there is going to
be a signed integer overflow so one can choose a larger representation. In
reality one would need to rewrite the program to handle the exception
and/or handle the return of larger integers.

(snip)

> My experience is that .Net programmers understand and accept the
> limitations of Int32 arithmetic and desire it as the default, and can
> easily reach for Int64 or Decimal when the need arises, which, for many
> applications, is never, and for them the current behavior is the right
> thing and will never require fixing.

And exactly how do you know this? Until a few hours ago some integer
arithmetic was being silently corrupted in DotLisp programs.

But I take your point: .Net programmers who understand and accept the
limitations of lower level programming languages don't want to deal with a
Lisp style of programming.

(snip)

> DotLisp does support a kind of contagion, i.e. Int32 + Int64 => Int64,
> Int32 + Double => Double.

But not when adding 1000000000 and 2000000000 since they are both signed
32-bit integers.

> It certainly is an experiment to try to build a Lisp with the
> fundamental types supplied by the .Net environment, i.e. to separate the
> types and the library from the language. That is what DotLisp is about,
> and it involves compromises. If you consider the result only
> "superficially Lisp", oh well.

It's the path of least resistance. Building syntactic sugar upon (virtual)
machine-level data types.
 
> My turnabout (rhetorical ;-) question is: how can one easily
> interoperate with CLR libraries and applications from Common Lisp? Since
> you don't have the evironment, I'll give you the answer - one can't. I
> don't see how Common Lisp is doing is the right thing, or anything, for
> people with that need. If Xanalys or anyone else comes up with a
> solution, I'll gladly pay.

Yet you fulfil a need by supplying a non-commercial-use-only program with
an arbitrary (non-CL or Scheme specified language) built on top of a
runtime environment thats only claim to fame over Java is that one can use
any programming language upon it (in exchange for the Microsoft CLR
running upon Windows and Windows). Yet all those programming languages
mirror many of the limitations of C#.

Rich, some of us are yet to drink the Kool Aid. My answer to your
question, "how can one easily interoperate with CLR libraries and
applications from Common Lisp": I simply don't care. But I do care about
the qualities of implementations calling themselves Lisp and I do not
agree that you have retained "the essence of Lisp as a language".

Regards,
Adam
From: Rich Hickey
Subject: Re: newbie needs some direction
Date: 
Message-ID: <bdrb2o$aiv$1@sun-news.laserlink.net>
Adam Warner wrote:
> Hi Rich Hickey,
> 
(snip)

> Glad to have been of assistance in uncovering the data corruption.

Jeez - there was no data corruption. There was a bug, which prior to 
being revealed in a theoretical test case, likely affected no one. But 
thanks.

(snip)

>> My experience is that .Net programmers understand and accept the
>> limitations of Int32 arithmetic and desire it as the default, and can
>> easily reach for Int64 or Decimal when the need arises, which, for many
>> applications, is never, and for them the current behavior is the right
>> thing and will never require fixing.


> And exactly how do you know this? Until a few hours ago some integer
> arithmetic was being silently corrupted in DotLisp programs.

Aargh. It does not follow from the fact that arithmetic could have been 
corrupted that it in fact arithmetic was being corrupted, and stating so 
in a newsgroup is just histrionics. You've never used DotLisp and should 
avoid stating what it was or wasn't doing. I seriously doubt any DotLisp 
programmers were overflowing Int32s - if they were they would have seen 
and reported the problem, and that proves my point - they are working 
within the range of Int32 when they use Int32.

> 
> But I take your point: .Net programmers who understand and accept the
> limitations of lower level programming languages don't want to deal with a
> Lisp style of programming.

I don't think you got the point at all. There are APIs in the world 
outside of Common Lisp that cannot take a bignum as input, so silently 
creating one in an effort to avoid overflow isn't helping the guy who's 
got to stuff it into a fixed sized integer at the end of the day.

>>DotLisp does support a kind of contagion, i.e. Int32 + Int64 => Int64,
>>Int32 + Double => Double.
> 
> 
> But not when adding 1000000000 and 2000000000 since they are both signed
> 32-bit integers.

I thought contagion was about operations between different types.

(snip)

> Yet you fulfil a need by supplying a non-commercial-use-only program with
> an arbitrary (non-CL or Scheme specified language) built on top of a
> runtime environment thats only claim to fame over Java is that one can use
> any programming language upon it (in exchange for the Microsoft CLR
> running upon Windows and Windows). Yet all those programming languages
> mirror many of the limitations of C#.

Yup. But I'm not an apologist for .Net or the CLR. I agree it is a 
runtime designed to support C# and languages not much different from it, 
although the SML.Net compiler from Microsoft Research 
(http://www.cl.cam.ac.uk/Research/TSG/SMLNET/) has greatly challenged 
that view. .Net has platform liabilities etc. Nevertheless, Windows and 
.Net are a given for many developers, and they could use a fun 
interactive scripting language.

(snip)

> But I do care about
> the qualities of implementations calling themselves Lisp and I do not
> agree that you have retained "the essence of Lisp as a language".

I'm glad you care and believe it is a question worth pursuing. You are 
certainly entitled to your opinion. Is there a language other than 
Common Lisp that you would consider a Lisp? Do you think Paul Graham's 
Arc (http://www.paulgraham.com/arc.html) is a Lisp?

Regards,

Rich
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.07.01.08.35.24.794832@consulting.net.nz>
Hi Rich Hickey,

> Adam Warner wrote:
>> Hi Rich Hickey,
>> 
> (snip)
> 
>> Glad to have been of assistance in uncovering the data corruption.
> 
> Jeez - there was no data corruption. There was a bug, which prior to
> being revealed in a theoretical test case, likely affected no one. But
> thanks.
> 
> (snip)
> 
>>> My experience is that .Net programmers understand and accept the
>>> limitations of Int32 arithmetic and desire it as the default, and can
>>> easily reach for Int64 or Decimal when the need arises, which, for
>>> many applications, is never, and for them the current behavior is the
>>> right thing and will never require fixing.
> 
> 
>> And exactly how do you know this? Until a few hours ago some integer
>> arithmetic was being silently corrupted in DotLisp programs.
> 
> Aargh. It does not follow from the fact that arithmetic could have been
> corrupted that it in fact arithmetic was being corrupted, and stating so
> in a newsgroup is just histrionics. You've never used DotLisp and should
> avoid stating what it was or wasn't doing. I seriously doubt any DotLisp
> programmers were overflowing Int32s - if they were they would have seen
> and reported the problem, and that proves my point - they are working
> within the range of Int32 when they use Int32.

Histrionics? "Insincere, exaggeratedly emotional or overly dramatical
speech or behavior performed to create an impression rather than as an
expression of true feeling; feigned emotion." (The Collaborative
International Dictionary of English v.0.48). If it is not clear Rich I was
not feigning any emotion nor feeling.

There is a correct answer to the addition of two positive integers and
that is the sum of the integers. Silently returning a negative number
instead is a data corrupting situation. Let's consider a functional model:
initial data => apply function => new data. If I feed data into a
function and it sometimes corrupts the data then the new data may or may
not be corrupt. But we know with certainty that some data will be
corrupted. Even though I have never used DotLisp I:

  (a) Guessed this would happen simply by reading your web page and
      consulting some Microsoft documentation.
  (b) Asked for confirmation using a test example in this newsgroup.
  (c) Received this confirmation from Mark.
  (d) Received confirmation from you that an exception is now being
      flagged.

Yet you now have the cheek to tell me "You've never used DotLisp and should
avoid stating what it was or wasn't doing." It's abundantly clear what
DotLisp was doing Rich. And the fact no one reported it does not prove your
point.

Regards,
Adam
From: Rich Hickey
Subject: Re: newbie needs some direction
Date: 
Message-ID: <bdruch$8dr$1@sun-news.laserlink.net>
Adam Warner wrote:
> Hi Rich Hickey,

(snip)

> Histrionics? "Insincere, exaggeratedly emotional or overly dramatical
> speech or behavior performed to create an impression rather than as an
> expression of true feeling; feigned emotion." (The Collaborative
> International Dictionary of English v.0.48). If it is not clear Rich I was
> not feigning any emotion nor feeling.
> 

What you wrote falls into the overly dramatical category. If you wrote a 
program that contained a bug that, for some combination of inputs, would 
erase the hard disk, would I be correct and appropriate in stating 
online that your program had erased hard disks, if it had not in fact 
erased mine or anyone else's?

Regards,

Rich
From: Kent M Pitman
Subject: Re: newbie needs some direction
Date: 
Message-ID: <sfwhe66uyvr.fsf@shell01.TheWorld.com>
Rich Hickey <··········@nnosspamrichhickey.com> writes:

> Adam Warner wrote:
> > Hi Rich Hickey,
> 
> (snip)
> 
> > Histrionics? "Insincere, exaggeratedly emotional or overly dramatical
> > speech or behavior performed to create an impression rather than as an
> > expression of true feeling; feigned emotion." (The Collaborative
> > International Dictionary of English v.0.48). If it is not clear Rich I was
> > not feigning any emotion nor feeling.
> >
> 
> What you wrote falls into the overly dramatical category. If you wrote
> a program that contained a bug that, for some combination of inputs,
> would erase the hard disk, would I be correct and appropriate in
> stating online that your program had erased hard disks, if it had not
> in fact erased mine or anyone else's?

I think Rich raises a reasonable point.

But this message is only a tangentially related aside...

If I recall correctly, it's called "bartonizing a disk", named for Ed
Barton, who had the ill fortune to find that Maclisp at the time used
null or missing entries as wildcards in the days when files were named
by what were little more than lists of components.  (It was more
Maclisp's bug than his bug, I hasten to add, but that didn't make him
feel much better about it.)  As the tale went, assuming my memory has
not further deteriorated the details, his call to do the deletion was
taking so long to execute that he eventually interrupted it and
realized it was iterating over all the files in the system... and so
didn't actually manage to delete ALL the files on the disk.  I think
that subsequent to this, Maclisp was changed to not auto-iterate in
DELETEF (the file deletion function) when there were missing
components.

This story is muddled in my mind because there is also a "DWIM horror
story" (TM) from the InterLisp world, probably apocryphal, though quite
plausible if you understand DWIM, that says that someone who didn't know
how to use the declaration facility in DWIM typed in (DECL) to InterLisp,
which spell-checked the input and rewrote it as (DEL) [the file deletion
operation, so goes the story--I didn't check]. Next, as the story goes,
DWIM realized there were missing args and supplied NIL, which was said
to be a wildcard for DEL.  And you can see where it goes from there.
But somehow I think this particular story never happened in InterLisp
and instead was some rewrite of the Maclisp problem that Barton had
experienced.

If anyone who was around in that era remembers either of these stories
differently, I hope they'll freely join in with corrections.

Cautionary tales like this were common to keep us in line, since we
worked on a computer that had very few safeguards, and in particular
had no file read or deletion protection whatsoever.
From: Oudeis
Subject: Re: newbie needs some direction
Date: 
Message-ID: <9cca45d2.0307011313.6c762a50@posting.google.com>
Kent M Pitman <······@world.std.com> wrote in message news:<···············@shell01.TheWorld.com>...
...
> If anyone ... remembers either of these stories
> differently, I hope they'll freely join in with corrections.
...

Quoting from http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?DWIM:

Warren Teitelman originally wrote DWIM to fix his typos and spelling
errors, so it was somewhat idiosyncratic to his style, and would often
make hash of anyone else's typos if they were stylistically different.
Some victims of DWIM thus claimed that the acronym stood for "Damn
Warren's Infernal Machine!'.

In one notorious incident, Warren added a DWIM feature to the command
interpreter used at Xerox PARC. One day another hacker there typed
"delete *$" to free up some disk space. (The editor there named backup
files by appending "$" to the original file name, so he was trying to
delete any backup files left over from old editing sessions.) It
happened that there weren't any editor backup files, so DWIM helpfully
reported "*$ not found, assuming you meant 'delete *'". It then
started to delete all the files on the disk! The hacker managed to
stop it with a Vulcan nerve pinch after only a half dozen or so files
were lost.

The disgruntled victim later said he had been sorely tempted to go to
Warren's office, tie Warren down in his chair in front of his
workstation, and then type "delete *$" twice.

DWIM is often suggested in jest as a desired feature for a complex
program; it is also occasionally described as the single instruction
the ideal computer would have. Back when proofs of program correctness
were in vogue, there were also jokes about "DWIMC" (Do What I Mean,
Correctly). A related term, more often seen as a verb, is DTRT (Do The
Right Thing); see Right Thing.
From: Kent M Pitman
Subject: Re: newbie needs some direction
Date: 
Message-ID: <sfwwuf198uu.fsf@shell01.TheWorld.com>
····@hotmail.com (Oudeis) writes:

[Interesting supplemental info omitted.]

> DWIM is often suggested in jest as a desired feature for a complex
> program; it is also occasionally described as the single instruction
> the ideal computer would have. Back when proofs of program correctness
> were in vogue, there were also jokes about "DWIMC" (Do What I Mean,
> Correctly). A related term, more often seen as a verb, is DTRT (Do The
> Right Thing); see Right Thing.

People used to also sometimes refer to DWIM as DWTM (Do What Teitelman Meant).
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.07.01.13.59.17.605806@consulting.net.nz>
Hi Rich Hickey,

> Adam Warner wrote:
>> Hi Rich Hickey,
> 
> (snip)
> 
>> Histrionics? "Insincere, exaggeratedly emotional or overly dramatical
>> speech or behavior performed to create an impression rather than as an
>> expression of true feeling; feigned emotion." (The Collaborative
>> International Dictionary of English v.0.48). If it is not clear Rich I
>> was not feigning any emotion nor feeling.
>> 
>> 
> What you wrote falls into the overly dramatical category. If you wrote a
> program that contained a bug that, for some combination of inputs, would
> erase the hard disk, would I be correct and appropriate in stating
> online that your program had erased hard disks, if it had not in fact
> erased mine or anyone else's?

No. I would only be correct in stating that the program had a data
corrupting bug. You seem to be discussing this earlier sentence, also
obliquely addressed in the snipped part of my reply:

   Rich:
   > My experience is that .Net programmers understand and accept the
   > limitations of Int32 arithmetic and desire it as the default, and can
   > easily reach for Int64 or Decimal when the need arises, which, for
   > many applications, is never, and for them the current behavior is the
   > right thing and will never require fixing.

   And exactly how do you know this? Until a few hours ago some integer
   arithmetic was being silently corrupted in DotLisp programs.

I can see the misunderstanding and I apologise for it. It's a fact that
some integer arithmetic was being silently corrupted. And it's also a fact
that this occurred in the DotLisp implementation. But I mentioned programs
instead of the implementation, and this gives rise to an interpretation
that I was talking about existing DotLisp programs instead of talking
about DotLisp programs in the abstract.

Though I still hope you can see what I was trying to express. Here's
another attempt: You state in the paragraph above that anything more than
signed 32-bit integer arithmetic for many applications is never required.
Yet part of this experience may be based upon programs that didn't flag an
integer overflow when they should have. So once your implementation is
flagging them correctly you may get a better idea how useful seamless
integer arithmetic might be and reevaluate whether your position is the
"right thing and will never require fixing" (and I appreciated your later
point about integrating with fixed integer APIs).

I hope you can see there has been a valid misunderstanding and what
appeared to be histrionics was a poorly worded reply.

It might be valuable investigating how Common Lisps manage to integrate
with foreign libraries. Each have their own methods and there is also a
Universal Foreign Function Interface:
<http://uffi.med-info.com/manual/x63.html>

Regards,
Adam
From: Adam Warner
Subject: Re: newbie needs some direction
Date: 
Message-ID: <pan.2003.06.30.06.34.26.109111@consulting.net.nz>
I recently wrote:

> Note that Common Lisp doesn't default to arguably doing the right thing
> in preserving the accuracy of real numbers in source code. If I write
> 1234.00005678 in source code there's probably a reason that I included
> all those significant figures. Yet it will be read in as a short float:
> 
> * 1234.00005678
> 
> 1234.0

Thanks Paul. That should have read _single_ float, not short (I made the
same mistake later in the message). What are short floats good for, pseudo
random answer generation?

Paul also mentioned that ANSI CL has provision to read all unspecified
floats as a certain type. Refer *READ-DEFAULT-FLOAT-FORMAT*

Regards,
Adam
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003jul26-002@Yahoo.Com>
{{Date: Mon, 30 Jun 2003 13:20:40 +1200
  From: Adam Warner <······@consulting.net.nz>
  Lisps attempt to do the right thing for at least some reasonable
  boundaries of right. To my mind not even returning the correct result
  for integer arithmetic puts it out of contention.}}

I agree. If a programming language/runtime can't even do integer
arithmetic correctly, it's crap and not worth using for anything,
certainly not a valid LISP. But see what I plan to post later about how
even LISP doesn't do what I would like regarding floating-point
arithmetic. (Hint: Producing a number that is "close to" but not
exactly the correct result, with no hint how far away the correct
answer might be, such that as more and more arithmetic occurs the
correct value and computer value get further and further from each
other, until at some point the computer value is totally different from
the correct answer, and still the program provides not a clue that the
two have in any significant way diverged from each other, is not what I
want.)

{{The above also shows a philosophy of doing the wrong thing fast and
  fixing the program afterwards. I'd rather do the right thing first
  and optimise afterwards.}}

I agree completely. Remember the Pentium floating-point bug. I can
understand how that might have slipped out, after all it was hardware,
which is tricky. Yet still It was bad to let it go on market then make
up excuses when people wanted refunds or replacements. But to design
software from the start to sacrifice correctness to obtain speed is
plain wrong. If the computer takes only 5 seconds to produce garbage,
compared to an hour to compute the correct answer, an astrologer would
be not any worse to give a garbage answer. The whole idea of a computer
is to process data more accurately than humans and faster. Surely all
modern languages on all modern computers process data much faster than
humans, so there's no excuse to pick a system that gives wrong answers
in a quarter second instead of another system that gives correct
answers in a half second, when it's take a human ten years to compute
the same result manually. Correct but slightly slower than C is very
very good enough.

{{Note that Common Lisp doesn't default to arguably doing the right
  thing in preserving the accuracy of real numbers in source code. If I
  write 1234.00005678 in source code there's probably a reason that I
  included all those significant figures. Yet it will be read in as a
  short float:
  * 1234.00005678
  1234.0
  Arguably doing the right thing would read this in as a double float
  by default so if one forgets a d0 at the end of the number the
  calculations aren't less accurate than intended:}}

I never though of it in this way, although I've suffered this problem
several times. Indeed, that would be the "right" thing to do in this
case. As somebody else pointed out, you can fix this by setting the
default to always be long float. But if the input is too long even for
long float, then it should presumably make a BIGFLOAT, which however
isn't usually available except in MacSyma etc.
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <d6fupxk4.fsf@ccs.neu.edu>
··········@YahooGroups.Com writes:

> But see what I plan to post later about how
> even LISP doesn't do what I would like regarding floating-point
> arithmetic. (Hint: Producing a number that is "close to" but not
> exactly the correct result, with no hint how far away the correct
> answer might be, such that as more and more arithmetic occurs the
> correct value and computer value get further and further from each
> other, until at some point the computer value is totally different from
> the correct answer, and still the program provides not a clue that the
> two have in any significant way diverged from each other, is not what I
> want.)

That's sort of the `point' of floating point.  There's this piece of
hardware in your machine that can manipulate floating point numbers
*very* fast provided you are willing to live with some approximations.
If you have no `tolerance' for approximation, don't use floating
point.
From: John M. Adams
Subject: Re: newbie needs some direction
Date: 
Message-ID: <oqaptjun2fm.fsf@RAKTABIJA.stsci.edu>
Joe Marshall <···@ccs.neu.edu> writes:

> ··········@YahooGroups.Com writes:
> 
> > But see what I plan to post later about how
> > even LISP doesn't do what I would like regarding floating-point
> > arithmetic. (Hint: Producing a number that is "close to" but not
> > exactly the correct result, with no hint how far away the correct
> > answer might be, such that as more and more arithmetic occurs the
> > correct value and computer value get further and further from each
> > other, until at some point the computer value is totally different from
> > the correct answer, and still the program provides not a clue that the
> > two have in any significant way diverged from each other, is not what I
> > want.)
> 
> That's sort of the `point' of floating point.  There's this piece of
> hardware in your machine that can manipulate floating point numbers
> *very* fast provided you are willing to live with some approximations.
> If you have no `tolerance' for approximation, don't use floating
> point.

Here is a good reference:

What Every Computer Scientist Should Know About Floating-Point
Arithmetic
ACM Computing Surveys, Vol 23, No. 1, March 1991

-- 
John M. Adams
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003aug01-005@Yahoo.Com>
{{Date: 28 Jul 2003 09:53:31 -0400
  From: Joe Marshall <···@ccs.neu.edu>
  That's sort of the `point' of floating point.  There's this piece of
  hardware in your machine that can manipulate floating point numbers
  *very* fast provided you are willing to live with some
  approximations. If you have no `tolerance' for approximation, don't
  use floating point.}}

No, that's not the point at all. The point of floating point is to
implement "scientific notation" so that you can express very large
numbers (1.3E+42) and very-near-zero numbers (1.3E-42) all in a compact
notation instead of needing to allocate two hundred bytes to store all
the digits from 10**99 down to 10**-99 with huge amounts of leading or
trailing zeroes. It's an artifact of the way FORTRASH originally
implemented it in software and everyone else copied it into both
software and hardware, that it gives no indication whatsoever of how
much margin of error is incorporated in any given value.

I have plenty of tolerance for error. The current estimate of the age
of the Universe is 13.7E9 years plus or minus about 0.2E9 years with
high likelihood of the correct age being in the range plus or minus
0.1E9 years. Virtually every quantity measured in physics has a
tolerance, a margin for error, attached to the value. Any measurement
without an indication of the likely margin of error, is crap, and
doesn't get published in respected journals, which in my opinion is a
good thing. Even political polls include the margin of error in the
published reports nowadays, again a good thing, especially when the
range of first and second place candidates overlap hence either could
win even if the poll was entirely correct.
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <wudtmtng.fsf@ccs.neu.edu>
··········@YahooGroups.Com writes:

> {{Date: 28 Jul 2003 09:53:31 -0400
>   From: Joe Marshall <···@ccs.neu.edu>
>   That's sort of the `point' of floating point.  There's this piece of
>   hardware in your machine that can manipulate floating point numbers
>   *very* fast provided you are willing to live with some
>   approximations. If you have no `tolerance' for approximation, don't
>   use floating point.}}
>
> No, that's not the point at all. The point of floating point is to
> implement "scientific notation" so that you can express very large
> numbers (1.3E+42) and very-near-zero numbers (1.3E-42) all in a compact
> notation instead of needing to allocate two hundred bytes to store all
> the digits from 10**99 down to 10**-99 with huge amounts of leading or
> trailing zeroes. It's an artifact of the way FORTRASH originally
> implemented it in software and everyone else copied it into both
> software and hardware, that it gives no indication whatsoever of how
> much margin of error is incorporated in any given value.

The history of floating point representation in no way invalidates my
point.  Floating-point is provided in computer languages because there
is a chip that is orders of magnitude faster than the software.

I understand that the chip doesn't do everything you want it to do,
but it wasn't designed to work that way.  I suggest that there is
nothing particularly wrong with floating point, but rather that it is
not the appropriate tool for your problem.

> I have plenty of tolerance for error. The current estimate of the age
> of the Universe is 13.7E9 years plus or minus about 0.2E9 years with
> high likelihood of the correct age being in the range plus or minus
> 0.1E9 years. Virtually every quantity measured in physics has a
> tolerance, a margin for error, attached to the value. Any measurement
> without an indication of the likely margin of error, is crap, and
> doesn't get published in respected journals, which in my opinion is a
> good thing. Even political polls include the margin of error in the
> published reports nowadays, again a good thing, especially when the
> range of first and second place candidates overlap hence either could
> win even if the poll was entirely correct.

The Common Lisp number system does not provide an `estimated number'
abstraction, but nothing is preventing you from writing one.
From: Thomas F. Burdick
Subject: Re: newbie needs some direction
Date: 
Message-ID: <xcv4r0x719v.fsf@famine.OCF.Berkeley.EDU>
Joe Marshall <···@ccs.neu.edu> writes:

> ··········@YahooGroups.Com writes:
> 
> > I have plenty of tolerance for error. The current estimate of the age
> > of the Universe is 13.7E9 years plus or minus about 0.2E9 years with
> > high likelihood of the correct age being in the range plus or minus
> > 0.1E9 years. Virtually every quantity measured in physics has a
> > tolerance, a margin for error, attached to the value. Any measurement
> > without an indication of the likely margin of error, is crap, and
> > doesn't get published in respected journals, which in my opinion is a
> > good thing. Even political polls include the margin of error in the
> > published reports nowadays, again a good thing, especially when the
> > range of first and second place candidates overlap hence either could
> > win even if the poll was entirely correct.
> 
> The Common Lisp number system does not provide an `estimated number'
> abstraction, but nothing is preventing you from writing one.

Of course, it's not easy, and you can't let your "scinums" get out to
other Lisp code [although (scinum:+ scinum fixnum) -> scinum,
(cl:+ scinum fixnum) -> error].  A couple years ago, I got part way
through implementing something like this.  I suspect it would be
easier for a mathematician, who would also be more likely to get it
right.  Anyway, saying "you can write one yourself" is like saying
that C doesn't have bignums, but you can add them yourself: not
really, in any meaningful way.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Russell Wallace
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f27f694.95894858@news.eircom.net>
On Sat, 26 Jul 2003 13:59:34 -0700, ··········@YahooGroups.Com wrote:

>I agree completely. Remember the Pentium floating-point bug. I can
>understand how that might have slipped out, after all it was hardware,
>which is tricky. Yet still It was bad to let it go on market then make
>up excuses when people wanted refunds or replacements. But to design
>software from the start to sacrifice correctness to obtain speed is
>plain wrong. If the computer takes only 5 seconds to produce garbage,
>compared to an hour to compute the correct answer, an astrologer would
>be not any worse to give a garbage answer.

In general I agree, but floating point is widely used for things that
take e.g. a month to compute. The correct alternative is exact
rationals, but those tend to be slower by many orders of magnitude; a
hopefully more or less right answer in a month is more useful than an
exact answer in ten thousand years.

(Besides, most applications of floating point are more limited by
space/time granularity than arithmetic precision; solving that problem
exactly would take an infinite amount of computing power.)

However, if exact rational numbers are fast enough for what you're
doing, then certainly you should use them.

>{{Note that Common Lisp doesn't default to arguably doing the right
>  thing in preserving the accuracy of real numbers in source code. If I
>  write 1234.00005678 in source code there's probably a reason that I
>  included all those significant figures. Yet it will be read in as a
>  short float:
>  * 1234.00005678
>  1234.0
>  Arguably doing the right thing would read this in as a double float
>  by default so if one forgets a d0 at the end of the number the
>  calculations aren't less accurate than intended:}}

I agree completely, defaulting to low precision is crazy.

-- 
"Sore wa himitsu desu."
To reply by email, remove
the small snack from address.
http://www.esatclear.ie/~rwallace
From: Raymond Toy
Subject: Re: newbie needs some direction
Date: 
Message-ID: <4ny8yf7vj3.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Russell" == Russell Wallace <················@eircom.net> writes:

    Russell> In general I agree, but floating point is widely used for things that
    Russell> take e.g. a month to compute. The correct alternative is exact
    Russell> rationals, but those tend to be slower by many orders of magnitude; a

What are you supposed to do if the required computation says multiply
by the square root of 2? :-)
 
    >> {{Note that Common Lisp doesn't default to arguably doing the right
    >> thing in preserving the accuracy of real numbers in source code. If I
    >> write 1234.00005678 in source code there's probably a reason that I
    >> included all those significant figures. Yet it will be read in as a
    >> short float:
    >> * 1234.00005678
    >> 1234.0
    >> Arguably doing the right thing would read this in as a double float
    >> by default so if one forgets a d0 at the end of the number the
    >> calculations aren't less accurate than intended:}}

    Russell> I agree completely, defaulting to low precision is crazy.

Change your default then?  There is a real cost to defaulting to
double-float instead of single-float.  I guess the single-float people
won that argument.

I'm more annoyed that (sqrt <integer>) (and other special functions)
returns a single-float instead of double-float.

Ray
From: Russell Wallace
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f280f20.102179596@news.eircom.net>
On Wed, 30 Jul 2003 13:51:28 -0400, Raymond Toy <···@rtp.ericsson.se>
wrote:

>What are you supposed to do if the required computation says multiply
>by the square root of 2? :-)

Exactly. (Pun intended :))

>Change your default then?  There is a real cost to defaulting to
>double-float instead of single-float.

No there isn't, for isolated operations double-float and single-float
are the same speed. For large-scale vector operations single-float
saves memory bandwidth, though it's only usable in very limited
applications; but honestly, if you're worried enough about speed that
you can't afford double-float, the question won't be what Lisp's
default should be, it'll be whether C is fast enough or the inner loop
needs to be in Fortran or assembler.

>I'm more annoyed that (sqrt <integer>) (and other special functions)
>returns a single-float instead of double-float.

?!?! That's off the wall! What do you do when you want a usable sqrt
function?... Oh, convert to double-float first, I guess, and God help
you if you forget. It's still off the wall.

-- 
"Sore wa himitsu desu."
To reply by email, remove
the small snack from address.
http://www.esatclear.ie/~rwallace
From: Raymond Toy
Subject: Re: newbie needs some direction
Date: 
Message-ID: <4nn0ev7rhq.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Russell" == Russell Wallace <················@eircom.net> writes:

    Russell> No there isn't, for isolated operations double-float and single-float
    Russell> are the same speed. For large-scale vector operations single-float

That might be true on x86, but I think sparc has different times.

    Russell> saves memory bandwidth, though it's only usable in very limited
    Russell> applications; but honestly, if you're worried enough about speed that
    Russell> you can't afford double-float, the question won't be what Lisp's
    Russell> default should be, it'll be whether C is fast enough or the inner loop
    Russell> needs to be in Fortran or assembler.

Oh, I always use doubles.  I just never want to deal with the limited
precision and range of single-floats.  (Not that it usually matters,
but I have been bitten by it before.)

Ray
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003aug02-003@Yahoo.Com>
{{Date: Wed, 30 Jul 2003 18:38:08 GMT
  From: ················@eircom.net (Russell Wallace)
  For large-scale vector operations single-float saves memory
  bandwidth, though it's only usable in very limited applications; but
  honestly, if you're worried enough about speed that you can't afford
  double-float, the question won't be what Lisp's default should be,
  it'll be whether C is fast enough or the inner loop needs to be in
  Fortran or assembler.}}

It's my understanding that if you compile your tight loops in LISP with
safety 0 and speed 3, the resultant inline code is essentially the same
machine operations as you'd get with C or Fortran.

But if you're doing such a long chain of floating point calculations
that it takes a lot of time even on modern high-speed computers,
chances are the result will be a random number somewhere within an
order of magnitude of the correct answer, meaningless.
From: Russell Wallace
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f2d2655.117092889@news.eircom.net>
On Sat, 02 Aug 2003 22:43:16 -0700, ··········@YahooGroups.Com wrote:

>But if you're doing such a long chain of floating point calculations
>that it takes a lot of time even on modern high-speed computers,
>chances are the result will be a random number somewhere within an
>order of magnitude of the correct answer, meaningless.

That can happen if you don't know what you're doing, but the people
who do such calculations for a living find the results are usually
accurate - predictions match experimental results, and physical
objects designed with floating point calculation work when they're
built.

-- 
"Sore wa himitsu desu."
To reply by email, remove
the small snack from address.
http://www.esatclear.ie/~rwallace
From: Raymond Toy
Subject: Re: newbie needs some direction
Date: 
Message-ID: <4nn0ep1pqp.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "RobertMaas" == RobertMaas  <··········@YahooGroups.Com> writes:

    RobertMaas> {{Date: Wed, 30 Jul 2003 18:38:08 GMT
    RobertMaas>   From: ················@eircom.net (Russell Wallace)
    RobertMaas>   For large-scale vector operations single-float saves memory
    RobertMaas>   bandwidth, though it's only usable in very limited applications; but
    RobertMaas>   honestly, if you're worried enough about speed that you can't afford
    RobertMaas>   double-float, the question won't be what Lisp's default should be,
    RobertMaas>   it'll be whether C is fast enough or the inner loop needs to be in
    RobertMaas>   Fortran or assembler.}}

    RobertMaas> It's my understanding that if you compile your tight loops in LISP with
    RobertMaas> safety 0 and speed 3, the resultant inline code is essentially the same
    RobertMaas> machine operations as you'd get with C or Fortran.

    RobertMaas> But if you're doing such a long chain of floating point calculations
    RobertMaas> that it takes a lot of time even on modern high-speed computers,
    RobertMaas> chances are the result will be a random number somewhere within an
    RobertMaas> order of magnitude of the correct answer, meaningless.

Is that why my simulations of wireless systems takes hours, days, and
sometimes weeks to run?  And they're all meaningless?  I think you
should throw away your cell phone, and your wifi system.  It can't
possibly be working.

Ray
From: Russell Wallace
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f2810d3.102614963@news.eircom.net>
On Wed, 30 Jul 2003 13:51:28 -0400, Raymond Toy <···@rtp.ericsson.se>
wrote:

>I guess the single-float people
>won that argument.

Actually, I'll summarize my opinions on this more succintly: When I
was teaching C++ commercially, I told people "The 'float' data type is
useless. Forget that it exists. You always have to use 'double'."

-- 
"Sore wa himitsu desu."
To reply by email, remove
the small snack from address.
http://www.esatclear.ie/~rwallace
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3cgmlt87.fsf@ccs.neu.edu>
Raymond Toy <···@rtp.ericsson.se> writes:

>>>>>> "Russell" == Russell Wallace <················@eircom.net> writes:
>
>     Russell> In general I agree, but floating point is widely used for things that
>     Russell> take e.g. a month to compute. The correct alternative is exact
>     Russell> rationals, but those tend to be slower by many orders of magnitude; a
>
> What are you supposed to do if the required computation says multiply
> by the square root of 2? :-)

Use exact real arithmetic (some variants have no problem with algabraic reals).
From: Raymond Toy
Subject: Re: newbie needs some direction
Date: 
Message-ID: <4nd6fq69z6.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Joe" == Joe Marshall <···@ccs.neu.edu> writes:

    Joe> Raymond Toy <···@rtp.ericsson.se> writes:
    >>>>>>> "Russell" == Russell Wallace <················@eircom.net> writes:
    >> 
    Russell> In general I agree, but floating point is widely used for things that
    Russell> take e.g. a month to compute. The correct alternative is exact
    Russell> rationals, but those tend to be slower by many orders of magnitude; a
    >> 
    >> What are you supposed to do if the required computation says multiply
    >> by the square root of 2? :-)

    Joe> Use exact real arithmetic (some variants have no problem with algabraic reals).

Well, he did originally say exact rational arithmetic. 

Ray
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003aug01-007@Yahoo.Com>
{{Date: Wed, 30 Jul 2003 13:51:28 -0400
  From: Raymond Toy <···@rtp.ericsson.se>
  I'm more annoyed that (sqrt <integer>) (and other special functions)
  returns a single-float instead of double-float.}}

This is in software you wrote yourself, wherein you explicitly pass an
integer to such a function, right? So why not just fix your code to
coerce the integer to a double before calling the sqrt or trig
function??
From: Raymond Toy
Subject: Re: newbie needs some direction
Date: 
Message-ID: <4nr8411pva.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "RobertMaas" == RobertMaas  <··········@YahooGroups.Com> writes:

    RobertMaas> {{Date: Wed, 30 Jul 2003 13:51:28 -0400
    RobertMaas>   From: Raymond Toy <···@rtp.ericsson.se>
    RobertMaas>   I'm more annoyed that (sqrt <integer>) (and other special functions)
    RobertMaas>   returns a single-float instead of double-float.}}

    RobertMaas> This is in software you wrote yourself, wherein you explicitly pass an
    RobertMaas> integer to such a function, right? So why not just fix your code to
    RobertMaas> coerce the integer to a double before calling the sqrt or trig
    RobertMaas> function??

Yes, I know how to solve the symptoms.  However, it seems it would
have made more sense for sqrt and friends to have returned long-floats
instead of single-floats when given integer args.

But that's not what happens.

Ray
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003aug02-001@Yahoo.Com>
{{Date: Wed, 30 Jul 2003 16:52:05 GMT
  From: ················@eircom.net (Russell Wallace)
  The correct alternative is exact rationals, but those tend to be
  slower by many orders of magnitude}}

I disagree. As rational arithmetic is done through many iterations, the
number of digits in numerator and denominator increases roughly
linearily, so the total amount is roughly quadradic, and the speed
ratio between floating point and exact rational arithmetic is linear.
So if you do a million calculations after the point when rational
numbers build up to match speed of floating point, exact rational takes
about a million times as long as floating point towards the end. So
indeed that's very slow as you say.

But if you use intervals of rationals, trimming the numerator and
denominator via continued-fraction method any time they start to get
large, then interval arithmetic of exact rational arithmetic has a
fixed speed ratio compared to floating point (assuming there are no
very large numbers or very close-to-zero numbers).

Of course if you do any square root or trig functions, you can't
express the answer in exact rationals in the first place, but you
surely can express the answer as an interval of exact rationals!

Just as an example/demo/exercise, I'll do square root of 2 by Newton's
method with exact rationals converted to intervals of rationals at some
point ...
* (defun newt1 (n ap) (/ (+ ap (/ n ap)) 2))
* (newt1 2 1)
3/2
* (newt1 2 *) (float *)
17/12
1.4166666
* (newt1 2 **) (float *)
577/408
1.4142157
* (newt1 2 **) (float * 1d0) (rationalize *)
665857/470832
1.4142135623746899d0
665857/470832
* (newt1 2 *) (float * 1d0) (rationalize *)
886731088897/627013566048 ;To be discarded because num&den too big
1.4142135623730951d0
131836323/93222358 ;Latest approximation, replacing above
* (- (* * *) 2)
1/8690408031080164 ;Hence the latest approximation is an upper bound
* (setq hi **)
* (defun rat-to-cf (r)
    (if (integerp r) (list r)
      (multiple-value-bind (i f) (floor r)
        (cons i (rat-to-cf (/ 1 f))))))
* (defun cf-to-rat (cf)
    (if (cdr cf) (+ (car cf) (/ 1 (cf-to-rat (cdr cf))))
      (car cf)))
* (rat-to-cf hi)
(1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
* (subseq * 0 (+ -1 (length *)))
(1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
* (cf-to-rat *)
54608393/38613965
* (- (* * *) 2)
-1/1491038293021225 ;Hence the approximation just above is a lower bound
* (setq lo **)
* (< (* lo lo) 2 (* hi hi))
T ;Hence we didn't goof somewhere
* (list :INTERVAL lo hi)
(:INTERVAL 54608393/38613965 131836323/93222358) ;Return value
* (- hi lo)
1/3599684869029470 ;Note how very narrow the error interval is!
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003jul27-002@Yahoo.Com>
Well, I planned to post a followup somewhere in this newsgroup citing
what I personally believe would be the right thing to do about
arithmetic, which neither LISP nor any other language has done in all
the years I've been programming. I made a list of articles I wanted to
reply to, and somewhere in that list was the place I planned to make my
big statement of opinion. I sorta promised in various places that I'd
say what I thought the right thing was. But when I reached the end of
my list I hadn't yet found the spot, somehow I missed it. So here I am
going back to an article I already short-replied to, to now keep my
promise.

{{Date: Mon, 30 Jun 2003 13:20:40 +1200
  From: Adam Warner <······@consulting.net.nz>
  Note that Common Lisp doesn't default to arguably doing the right
  thing in preserving the accuracy of real numbers in source code. If I
  write 1234.00005678 in source code there's probably a reason that I
  included all those significant figures. Yet it will be read in as a
  short float:
  * 1234.00005678
  1234.0}}

I agree that's not the right thing to do.

{{Arguably doing the right thing would read this in as a double float
  by default so if one forgets a d0 at the end of the number the
  calculations aren't less accurate than intended:
  * 1234.00005678d0
  1234.00005678d0}}

I agree, generating a double-float like that but as default when the
user typed in what was shown earlier, is better than what CL does, but
I don't agree it's completely the right thing. See the specification
for the two functions rational and rationalize, the first of which
assumes the floating-point number is exactly correct and so the
rational number created should be exactly that same exact number, and
the second of which assumes the floating-point number is only an
approximation and any other number close to it is good enough, the
smaller the numerator and denominator the better. Well when inputting
raw data from the keyboard or source file, should the program assume
it's exactly correct unless told otherwise, or should the program
assume it's only close anyway so changing it to something else which is
nearby is good enough? Consider this:

* (/ 123400005678 100000000)
61700002839/50000000
;That's the exact value of the number typed by the user.

* (rational 1234.00005678d0)
5427189644423417/4398046511104
;That's what the LISP system gave the user instead.

* (float (- * **))
2.2627065e-14
;That's appx. the amount of error introduced just by READ of that number.

Yeah, the amount of error is small compared to the last significant
digit of the number typed in, but what if that was an exact value, and
the exactness of it was important, and fudging it that little bit
breaks something? And the user has no really good idea how much it was
fudged in which direction?

And what if the user provides even more accuracy, but much of it
discarded as the value is fudged to be a double-float?

* 1234.00005678112233445566778899d0
1234.0000567811223d0

My personal opinion is that any time it's not possible to represent the
exactly correct answer, an interval should be provided, lower and upper
bounds on the exactly correct answer. Further arithmetic should
continue to provide lower and upper bounds. At the end, when it's time
to look at the result, it's clear whether there's still sufficient
accuracy to produce a definitive result, or so much accuracy has been
lost that the answer is meaningless. The user doesn't have to guess
whether the answer is "correct" or "nonsense". IMO interval arithmetic
should be the default means of calculation.

So, suppose somebody like me doesn't have interval arithmetic built-in
CL and needs to emulate it somehow. For simple arithmetic, the best
I've been able to come up with is (1) using RATIONAL to convert each
floating-point argument to a ratio, (2) doing exact rational arithmetic,
(3) converting the result back to an interval of floats by something
like this crock I wrote today:

(defun rational-to-intfloat (ratval &optional (other 1.0f0))
  (prog (appx1 rat1 diff sgf exp sign fudge lo hi mid)
    (setq appx1 (float ratval other))
    (setq rat1 (rational appx1))
    (setq diff (- rat1 ratval))
    (if (zerop diff) (return appx1))
    (multiple-value-setq (sgf exp sign)
      (integer-decode-float appx1)) ;4696154375798970 // -53 // 1
    (setq fudge (scale-float (float 1 other) exp))
    (cond ((minusp diff)
           (setq lo appx1) (setq hi (+ appx1 fudge))
           (or (< ratval (rational hi)) (error "Bound not upper")))
          ((plusp diff)
           (setq lo (- appx1 fudge)) (setq hi appx1)
           (or (< (rational lo) ratval) (error "Bound not lower")))
          (t (error "Neither - nor + after known not 0")))
    (setq mid (/ (+ lo hi) 2))
    (or (eql lo mid) (eql mid hi) (error "Mid is a new number"))
    (return (list :INTERVAL lo hi))
    ))

It would be so very much more efficient if the CL system itself had
support for floating-point interval arithmetic so I wouldn't have to
write something like that myself.

As for anything beyond simple arithmetic, i.e. the trigonometric
functions, given that exact rational-number arithmetic can't express
the result, I have no idea how to implement interval arithmetic without
re-doing all the work that was put into the various floating point
routines, which could take me years to get all the branch points etc.
figured out.

Of course every CPU should itself provide interval-arithmetic
floating-point operations, sigh.

{{It just seems a shame that Common Lisp has useful contagion rules
  that don't get an opportunity to work if numbers aren't first read in
  to a high enough accuracy.}}

And also a shame that interval arithmetic isn't implemented at all.
From: Russell Wallace
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f27f8c8.96458381@news.eircom.net>
On Sun, 27 Jul 2003 16:06:07 -0700, ··········@YahooGroups.Com wrote:

>My personal opinion is that any time it's not possible to represent the
>exactly correct answer, an interval should be provided, lower and upper
>bounds on the exactly correct answer.

I was under the impression that:

- Interval arithmetic gives worst-case bounds.
- In practice, the error tends to be much less than interval
arithmetic would have one believe, because errors often cancel out.
- Thus, for some calculations, interval arithmetic would say the
result is meaningless when in fact it's a good enough approximation.
- In practice, the majority of calculations people actually want to
do, fall into this category.
- Therefore, people don't want to use interval arithmetic even if it's
available and fast, because it nearly always says "no meaningful
result" and is nearly always wrong about that.

That said, I'm no expert on numerical computing, someone correct me if
I'm wrong?

-- 
"Sore wa himitsu desu."
To reply by email, remove
the small snack from address.
http://www.esatclear.ie/~rwallace
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003aug01-006@Yahoo.Com>
{{Date: Wed, 30 Jul 2003 17:00:36 GMT
  From: ················@eircom.net (Russell Wallace)
  I was under the impression that:
  - Interval arithmetic gives worst-case bounds.}}

Yes, that's correct.

{{- In practice, the error tends to be much less than interval
  arithmetic would have one believe, because errors often cancel out.}}

False in two ways: First, you have no way to know whether errors cancel
out as you say or in fact accumulate mostly in one particular
direction, unless you do proper numerical analysis on whatever
algorithm you're using.

Second, if you carry all your intermediate calculations to very high
precision, the very large bounds implied by interval arithmetic will
still be smaller than your original uncertainties in input values,
hence not a cause of problem. The nice thing about interval arithmetic
is that if you do so very much calculations that error nevertheless
builds up, interval arithmetic will show you that big margin of error,
and all you have to do then is re-run the program with higher precision
until you get the output bounds small enough. Looking at the interval
result and making a simple yes/no decision whether it's "good enough"
is much easier than going through complicated numerical analysis where
you basically do it all manually. On today's fast machines, there's
really no reason to do manual numerical analysis instead of just having
the machine compute the bounds at sub-nanosecond speed.

{{- Thus, for some calculations, interval arithmetic would say the
  result is meaningless when in fact it's a good enough approximation.}}

If you stop there, getting an interval one way and getting some random
number with not a clue of bounds the other way, indeed both regular
floating point and interval arithmetic are equally worthless, but at
least interval arithmetic is honest in warning you the result may be
garbage. If you honestly believe that errors cancel, just take the
midpoint between low and high bounds and risk your life, the same as
you risk your life if you believe floating-point results in a case
where interval arithmetic would show a wide margin of error.

But if you re-do the calculation with higher precision interval
arithmetic, you win. But with regular floating point, you have no idea
when you have high enough precision to trust the result.

{{- In practice, the majority of calculations people actually want to
  do, fall into this category.}}

Do you have solid numerical analysis to prove this claim?

{{- Therefore, people don't want to use interval arithmetic even if
  it's available and fast, because it nearly always says "no meaningful
  result" and is nearly always wrong about that.}}

Only in the old days when computers were slow and you couldn't afford
to increase the precision of numbers beyond standard (single and
double). Also, with modern FFT-based bignum multiply/divide/exp/log
algorithms, where computing an n-digit result takes n log(n) instead of
n * n units of time, it's not a horrible burden computing some
intermediate values to several tens of digits of accuracy.

Also, whereas profiling usually shows which parts of your program are
taking up most of the CPU time or causing most of the page faults,
hence showing the few small parts that are worth "bumming", profiling
could just as easily show which parts of the program are introducing
most of the widening of error bounds, hence which parts need to be
computed with higher precision, or which cards need to be rewritten to
use a numerically more-stable algorithm. (Remember when the first
pocket calculators with trig functions came out, HP did it correct but
was expensive, whereas Sinclair was cheap but used a totally stupid
algorithm for computing SIN(X), namely computing the cosine first then
applying the rule for converting to sine (square root of one minus
cosine squared), which for X near zero was incorrect by more than an
order of magnitude?) So anyway, if you sprinkle around the main loop of
your numerical algorithm a check to make sure the error is less than
one percent, signalling an error whenever it's too wide, you can catch
when it goes bad and put more checks inside whatever function was
called just previously to see whether it's creeping up or suddenly
jumping to wide margin due to yet another function called from inside
there, and with a little work you can track down the problem and fix
it.

I just wish Common LISP implemented interval arithmetic so that I could
actually do that when I'm doing anything heavily numerical. (That hack
I invented a day or so ago, whereby I convert arguments to exact
rationals, do exact arithmetic there, then convert result to floating
point bounds, works only for simple arithmetic where rational numbers
can produce exact results. Tonight I figured out a simple hack for
doing square root with intervals too: Compute the floating point square
root, then convert back to rational and square it and compare to see
whether result is too high or too low hence which way to fudge it to
get the other bound. I haven't yet figured out any simple way to deal
with exp/log/sin/cos/etc., sigh.)
From: Russell Wallace
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f2d2853.117602689@news.eircom.net>
On Fri, 01 Aug 2003 22:59:48 -0700, ··········@YahooGroups.Com wrote:

>Second, if you carry all your intermediate calculations to very high
>precision, the very large bounds implied by interval arithmetic will
>still be smaller than your original uncertainties in input values,
>hence not a cause of problem. The nice thing about interval arithmetic
>is that if you do so very much calculations that error nevertheless
>builds up, interval arithmetic will show you that big margin of error,
>and all you have to do then is re-run the program with higher precision
>until you get the output bounds small enough.

*nod* So you're proposing a combination of interval arithmetic with
adjustable precision? Right... I think it's interval arithmetic
combined with plain 64 bit floating point that's turned out not to be
useful. Yes, I can see combined with adjustable precision it could
work well, for the reasons you give.

It wouldn't be very useful in situations where it'd make a month of
calculation extend to a couple of years, but it might often be worth
extending an hour of calculation to a day if it would enable more
confidence in the results.

-- 
"Sore wa himitsu desu."
To reply by email, remove
the small snack from address.
http://www.esatclear.ie/~rwallace
From: Joe Marshall
Subject: Re: newbie needs some direction
Date: 
Message-ID: <smohmsv8.fsf@ccs.neu.edu>
················@eircom.net (Russell Wallace) writes:

> On Sun, 27 Jul 2003 16:06:07 -0700, ··········@YahooGroups.Com wrote:
>
>>My personal opinion is that any time it's not possible to represent the
>>exactly correct answer, an interval should be provided, lower and upper
>>bounds on the exactly correct answer.
>
> I was under the impression that:
>
> - Interval arithmetic gives worst-case bounds.

Interval arithmetic is hard to do.

Suppose I have two resistors in parallel, one has resistance 9-11
ohms, the other has resitance 45-55 ohms.  Now, ignoring the
supposition that resistance is distributed on a gaussian in log space,


1/r1 + 1/r2 = 1/rsum

1/r1 = (interval 1/11 1/9)
1/r2 = (interval 1/55 1/45)
1/rsum = (interval 6/55 2/15), so rsum = (interval 7.5 9.2)

    alternatively

          r1 r2
rsum = ----------------
         r1 + r2

r1 * r2 = (interval 405 605)

r1 + r2 = (interval 54 66)

so rsum = (interval 6.14 11.2)
From: ··········@YahooGroups.Com
Subject: Re: newbie needs some direction
Date: 
Message-ID: <REM-2003aug10-001@Yahoo.Com>
{{Date: Mon, 04 Aug 2003 09:53:31 -0400
  From: Joe Marshall <···@ccs.neu.edu>
  Suppose I have two resistors in parallel, one has resistance 9-11
  ohms, the other has resitance 45-55 ohms.  Now, ignoring the
  supposition that resistance is distributed on a gaussian in log
  space,
  1/r1 + 1/r2 = 1/rsum
  1/r1 = (interval 1/11 1/9)
  1/r2 = (interval 1/55 1/45)
  1/rsum = (interval 6/55 2/15), so rsum = (interval 7.5 9.2)}}

Yes, that's the correct way to get worst-case interval result, assuming
interval input.

{{    alternatively
            r1 r2
  rsum = ----------------
           r1 + r2}}

That's the wrong way to do it. You have an input interval partially
cancelling itself, but interval arithmetic applied in reductionist mode
(interval of numerator, interval of denominator, those two falsely
considered independent when doing interval division) simply combines
worst case in one direction against worst case in other direction which
is logically impossible. For example, if r1 increases then numerator
and denominator both increase, but one effect increases rsum while the
other decreases rsum. In general you don't want the same input
parameter running in oppositive directions with respect to effect on
final result. If your mathematical form shows such an effect, you need
to transform the mathematical form so that any single input affects
output only in a single direction, as the earlier formula involving
inverse of sum of inverses did.

Note that if some kind of symbolic mathematics is available, something
like MacSyma or Reduce, the above expression could automatically be
converted to the correct form:  First, numerator and denominator are
independently converted to polynomial standard form in r1, whereupon
it's noticed that each is linear in r1. So each is divided by r1 to
make it zero degree in r1:
             r2
  rsum = -------------
           1 + r2/r1
so now the problem with r1 is gone, it affects the output in only one
direction. Now do the same with r2 and you get the inverse form given
earlier. With a more complicated formula, it might be necessary to look
at the actual interval input to determine which of the input parameters
affects numerator and denominator etc. most, and then express the
result as a first-approximation based on that one parameter combined
with a perturbation by the other parameter. The result of the analysis
might be to force the expression to be monotonic in whichever input
parameter affects the result the most, and not worry about some
cancellation caused by the other parameter which only slightly affects
the result.

If there is no reasonable mathematical transformation of some stage of
processing to avoid some input affecting output both ways
simultaneously, then divide-and-conquer may be useful, whereby the
overall interval is broken into pieces, each piece is run through
interval arithmetic to get a set of output intervals, and the union of
those output intervals is then used. If mathematical theory shows the
output response is monotonic with respect to that input parameter, then
all you need to process is the two endpoints, no interval at all with
respect to that particular input, then use the interval between the
extrema of those two results. For example if output is monotonic with
respect to X = (interval 1.7 1.9), and with respect to Y = (interval
2.7 3.1), and the expression in terms of Y has no cancellation but some
X cancellation occurs, then compute with X = 1.7 and the full Y
interval, and compute with X = 1.9 and the full Y interval, and if the
results come out (interval 42.7 49.3) and (interval 51.3 55.4), then
the result should be (interval 42.7 55.4).

If the result is not monotonic with respect to one of the inputs, i.e.
holding other inputs constant but varying that one input across the
given interval, mathematics (usually calculus, compute formal
derivative and set to zero and solve resultant equation) can find the
point where the effect on that one input changes direction, and the
overall interval can be split at that point. The mathematics need be
done only once when writing the utility for interval arithmetic for
that particular mathematical function, and can then be hardcoded into
that utility, and just used at runtime without great cost. Quadradics
and trigonometric functions are the most common cases here.

Yes, it's a bit of work to get interval arithmetic done correctly,
which is a good argument why it should be included in the API rather
than re-invented by each user who feels a need to try it. Likewise the
tools to convert a given mathematical expression to optimal form for
feeding into the interval arithmetic should also be provided by the
(lisp) system. The user need run such tools only once per application
program, then hardwire the result into the application program as the
actual data varies from run to run but stays within the range for which
the optimization had been performed.
From: sharkfish
Subject: Re: newbie needs some direction
Date: 
Message-ID: <sENMa.1975$Ix2.1265@rwcrnsc54>
This sounds very interesting.  I would be very interested in DotLisp.
I see I have to email Rich Hickey to check it out.  Your extensions are of
interest to me as well.

"Mark Hurd" <········@ozemail.com.au> wrote in message
···············@news.iprimus.com.au...
> sharkfish wrote:
> >  Can I run CLisp applications within the .NET CLR....is there a real
> > CLisp compiler for the CLR besides that simple example MS provides in
their
> > sample code?
>
> As a "newbie" you probably don't need to know this, but Rich Hickey has a
Lisp
> (not CL) built for the .Net Framework.
>
> http://www.richhickey.com/dotlisp.htm
>
> Although it is an interpreter, performance is still rather good when most
of
> the code is just gluing framework routines together. He provides a
component
> interface so you could have an ASP.NET page that includes or reads lisp
source
> and passes it to the DotLisp interpreter.
>
> I have written some extensions (purely in DotLisp) to allow declaring
> "Platform Invoke" methods so you can access the whole of the Win32 API as
> well.
> -- 
> Regards,
> Mark Hurd, B.Sc.(Ma.) (Hons.)
>
>
From: Mark Hurd
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f059015$1_1@news.iprimus.com.au>
sharkfish wrote:
> This sounds very interesting.  I would be very interested in DotLisp.
> I see I have to email Rich Hickey to check it out.  Your extensions are of
> interest to me as well.

Email me with a working address when you hear from Rich.

Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
From: Mark Hurd
Subject: Re: newbie needs some direction
Date: 
Message-ID: <3f175eb6$1_1@news.iprimus.com.au>
(I can only see the following reply on Google.)
"sharkfish" <·····@bidness.com> wrote in message
news:<·················@rwcrnsc51.ops.asp.att.net>...
> Haven't gotten a reply yet. I sent another e-mail, just in case he missed
> the first one somehow.

Rich has put DotLisp on SourceForge:

http://sourceforge.net/projects/dotlisp/

You'll find my extra.lisp with P/Invoke implementation in the patches.
-- 
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)