From: ·······@ziplip.com
Subject: Python syntax in Lisp and Scheme
Date: 
Message-ID: <FTB2H3EKMGCKEAGFMAPUH4MJIBMHGNMOD5CLJSKP@ziplip.com>
I think everyone who used Python will agree that its syntax is
the best thing going for it. It is very readable and easy
for everyone to learn. But, Python does not a have very good
macro capabilities, unfortunately. I'd like to know if it may
be possible to add a powerful macro system to Python, while 
keeping its amazing syntax, and if it could be possible to
add Pythonistic syntax to Lisp or Scheme, while keeping all
of the functionality and convenience. If the answer is yes,
would many Python programmers switch to Lisp or Scheme if
they were offered identation-based syntax?

From: Paul Rubin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7xvfr6lvh6.fsf@ruckus.brouhaha.com>
·······@ziplip.com writes:
> If the answer is yes, would many Python programmers switch to Lisp
> or Scheme if they were offered identation-based syntax?

I don't think the syntax is that big a deal.  But programming in lisp
or scheme has a creaky feeling these days, because the traditional
runtime libraries in those languages have fallen so far behind the
times.
From: Mark Brady
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <e840346c.0310030302.6be0c378@posting.google.com>
This whole thread is a bad idea. If you like python then use python.
Personally I find Scheme and Common Lisp easier to read but that's
just me, I prefer S-exps and there seems to be a rebirth in the Scheme
and Common Lisp communities at the moment. Ironically this seems to
have been helped by python. I learned python then got interested in
it's functional side and ended up learning Scheme and Common Lisp. A
lot of new Scheme and Common Lisp developers I talk to followed the
same route. Python is a great language and I still use it for some
things.

Paul Rubin's comments are just pure fud. 

Some great scheme implementations with large modern libraries (not yet
a match for python but growing fast):
http://www.plt-scheme.org/
http://www-sop.inria.fr/mimosa/fp/Bigloo/
http://www.wikipedia.org/wiki/Gauche
http://sisc.sourceforge.net/
http://www.scheme.com/

Common Lisp has a fantastic wiki site (links to implementations and
loads of libraries) with everything you need to get started at:
http://www.cliki.net/index

Also see:
http://www.lisp.org/alu/home
http://common-lisp.net
http://www.cliki.net/YoungLispers

Many of the latest Scheme and Lisp mailing lists can be browsed from:
http://news.gmane.org/index.php?match=gmane.lisp

Develop in the language that suits you but despite the fud you do have
a choice,
Python, Scheme and Common Lisp are all fine languages with good
libraries and FFI capabilities.

Regards,
Mark.



Paul Rubin <·············@NOSPAM.invalid> wrote in message news:<··············@ruckus.brouhaha.com>...
> ·······@ziplip.com writes:
> > If the answer is yes, would many Python programmers switch to Lisp
> > or Scheme if they were offered identation-based syntax?
> 
> I don't think the syntax is that big a deal.  But programming in lisp
> or scheme has a creaky feeling these days, because the traditional
> runtime libraries in those languages have fallen so far behind the
> times.
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7wednSJ_q_L85uCiXTWJhQ@comcast.com>
"Mark Brady" <······@lycos.com> wrote in message
·································@posting.google.com...
> This whole thread is a bad idea.

I could agree that the OP's suggestion is a bad idea but do you
actually think that discussion and more publicity here for Lisp/Scheme
is bad?  You make a pretty good pitch below for more Python=>Lisp
converts.

> If you like python then use python.

As I plan to do.

> Personally I find Scheme and Common Lisp easier to read but that's
> just me, I prefer S-exps and there seems to be a rebirth in the
cheme
> and Common Lisp communities at the moment. Ironically this seems to
> have been helped by python. I learned python then got interested in
> it's functional side and ended up learning Scheme and Common Lisp. A
> lot of new Scheme and Common Lisp developers I talk to followed the
> same route. Python is a great language and I still use it for some
> things.

Other Lispers posting here have gone to pains to state that Scheme is
not a dialect of Lisp but a separate Lisp-like language.  Could you
give a short listing of the current main differences (S vs. CL)?  If I
were to decide to expand my knowledge be exploring the current
versions of one(I've read the original SICP and LISP books), on what
basis might I make a choice?

Terry J. Reedy
From: Jeremy H. Brown
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <uv6brsygx78.fsf@tenebrae.ai.mit.edu>
"Terry Reedy" <·······@udel.edu> writes:
> Other Lispers posting here have gone to pains to state that Scheme is
> not a dialect of Lisp but a separate Lisp-like language.  Could you
> give a short listing of the current main differences (S vs. CL)?  

According to the "Revised(5) Report on the Algorithmic Language
Scheme", "Scheme is a statically scoped and properly tail-recursive
dialect of the Lisp programming language..."  It's certainly not a
dialect of Common Lisp, although it is one of CL's ancestors.

I'm sure if you do some web-groveling, you can find some substantial
comparisons of the two; I personally think they have more in common
than not.  Here are a few of the (arguably) notable differences:

                        Scheme          Common Lisp
Philosophy              minimalism      comprehensiveness
Namespaces              one             two (functions, variables)
Continuations           yes             no
Object system           no              yes
Exceptions              no              yes
Macro system            syntax-rules    defmacro
Implementations         >10             ~4
Performance             "worse"         "better"
Standards               IEEE            ANSI
Reference name          R5RS            CLTL2
Reference length        50pp            1029pp
Standard libraries      "few"           "more"
Support Community       Academic        Applications writers

The Scheme community has the SRFI process for developing additional
almost-standards.  I don't know if the CL community has something
equivalent; I don't think they did a year ago.

> If I were to decide to expand my knowledge be exploring the current
> versions of one(I've read the original SICP and LISP books), on what
> basis might I make a choice?

Try them both, see which one works for you in what you're doing.

Jeremy
From: Duane Rettig
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <4pthecmq4.fsf@beta.franz.com>
·······@ai.mit.edu (Jeremy H. Brown) writes:

> "Terry Reedy" <·······@udel.edu> writes:
> > Other Lispers posting here have gone to pains to state that Scheme is
> > not a dialect of Lisp but a separate Lisp-like language.  Could you
> > give a short listing of the current main differences (S vs. CL)?  


> I'm sure if you do some web-groveling, you can find some substantial
> comparisons of the two; I personally think they have more in common
> than not.  Here are a few of the (arguably) notable differences:

This is actually a pretty good list.  I'm not commenting on
completeness, but I do have a couple of corrections:

>                         Scheme          Common Lisp
> Philosophy              minimalism      comprehensiveness
> Namespaces              one             two (functions, variables)
> Continuations           yes             no
> Object system           no              yes
> Exceptions              no              yes
> Macro system            syntax-rules    defmacro
> Implementations         >10             ~4
===========================================^

See http://alu.cliki.net/Implementation - it lists 9 commercial
implementations, and 7 opensource implementations.  There are
probably more.

> Performance             "worse"         "better"
> Standards               IEEE            ANSI
> Reference name          R5RS            CLTL2
============================================^

No, CLtL2 is definitely _not_ a reference for ANSI Common Lisp.
It was a snapshot taken in the middle of the ANSI process, and
is out of date in several areas.  References which are much closer
to the ANSI spec can be found online at 

http://www.franz.com/support/documentation/6.2/ansicl/ansicl.htm

or

http://www.lispworks.com/reference/HyperSpec/Front/index.htm

> Reference length        50pp            1029pp
> Standard libraries      "few"           "more"
> Support Community       Academic        Applications writers
> 
> The Scheme community has the SRFI process for developing additional
> almost-standards.  I don't know if the CL community has something
> equivalent; I don't think they did a year ago.

There are many grassroots defacto standards efforts to extend CL in
several areas.  Some of these are listed here:

http://alu.cliki.net/Standard

> > If I were to decide to expand my knowledge be exploring the current
> > versions of one(I've read the original SICP and LISP books), on what
> > basis might I make a choice?
> 
> Try them both, see which one works for you in what you're doing.

Agreed, but of course, I'd recommend CL :-)

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Jeremy H. Brown
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <uv665j6gqda.fsf@tenebrae.ai.mit.edu>
Duane Rettig <·····@franz.com> writes:
> ·······@ai.mit.edu (Jeremy H. Brown) writes:
> This is actually a pretty good list.  I'm not commenting on
> completeness, but I do have a couple of corrections:
...
> > Implementations         >10             ~4
> ===========================================^
> 
> See http://alu.cliki.net/Implementation - it lists 9 commercial
> implementations, and 7 opensource implementations.  There are
> probably more.

Thanks.  I hadn't realized the spread was that large.

> > Performance             "worse"         "better"
> > Standards               IEEE            ANSI
> > Reference name          R5RS            CLTL2
> ============================================^
> 
> No, CLtL2 is definitely _not_ a reference for ANSI Common Lisp.
> It was a snapshot taken in the middle of the ANSI process, and
> is out of date in several areas.  References which are much closer
> to the ANSI spec can be found online at 
> 
> http://www.franz.com/support/documentation/6.2/ansicl/ansicl.htm
> 
> or
> 
> http://www.lispworks.com/reference/HyperSpec/Front/index.htm

Thanks again.

> > 
> > Try them both, see which one works for you in what you're doing.
> 
> Agreed, but of course, I'd recommend CL :-)

I've arrived at the conclusion that it depends both on your task/goal
and your personal inclinations.

Jeremy
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <0KWdnYU5w94OI-CiU-KYuA@comcast.com>
"Jeremy H. Brown" <·······@ai.mit.edu> wrote in message
····················@tenebrae.ai.mit.edu...
> "Terry Reedy" <·······@udel.edu> writes:
....
> > give a short listing of the current main differences (S vs. CL)?
...
> than not.  Here are a few of the (arguably) notable differences:
...
Thank you.  This is just the sort of preview I wanted.

> Try them both, see which one works for you in what you're doing.

My present interest is intellectual broadening.  I think I should
start with parts of the current version of SICP and then read a modern
CL chapter on macros.

Terry J. Reedy
From: felix
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwhl4wctw2xcd0@news.freenet.de>
On 03 Oct 2003 11:25:31 -0400, Jeremy H. Brown <·······@ai.mit.edu> wrote:

> I'm sure if you do some web-groveling, you can find some substantial
> comparisons of the two; I personally think they have more in common
> than not.  Here are a few of the (arguably) notable differences:
>
> Scheme                                  Common Lisp

> Namespaces              one             two (functions, variables)

Common Lisp has actually more than two namespaces.

> Implementations         >10             ~4

There are loads more.

> Performance             "worse"         "better"

Nonsense.

> Support Community       Academic        Applications writers

Also nonsense.

>
> Try them both, see which one works for you in what you're doing.
>

Very good point.


cheers,
felix
From: synthespian
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bllrtt$do447$1@ID-78052.news.uni-berlin.de>
Jeremy H. Brown wrote:
(snip)
> 
> According to the "Revised(5) Report on the Algorithmic Language
> Scheme", "Scheme is a statically scoped and properly tail-recursive
> dialect of the Lisp programming language..."  It's certainly not a
> dialect of Common Lisp, although it is one of CL's ancestors.
> 
> I'm sure if you do some web-groveling, you can find some substantial
> comparisons of the two; I personally think they have more in common
> than not.  Here are a few of the (arguably) notable differences:
> 
>                         Scheme          Common Lisp
> Philosophy              minimalism      comprehensiveness

(etc)
Hello --

   I would just like to point out that there's more choice out there in 
the Lisp family than Scheme - Common Lisp.
   In particular, I would like to mention ISLISP, which is an 
ISO-standard Lisp. Apparently, the story goes somewhat like this: when 
lispers went for an ANSI standard, they left out the Europeans and the 
Japanese - which were the other people heavily using Lisp at the time. 
Thus, ANSI Common Lisp was made all-American. So the people left out 
went for an ISO-standard Lisp.
   I don't know why this happened, I suspect (and I might be *very* 
wrong) it had something to do with competition way back when Lisp were 
aiming higher expectations market-wise (the French being very proud of 
Prolog :-) ).
   I have recently bumped into ISLISP. It is pretty good. It has full 
documentation and two usable implementations: a GPL TISL, and a free for 
non-commercial use OpenLisp (for now, at least, and I can't say for now 
if this will change - for the better).
   I don't have time to write a comparison table now, but let me just 
say that it mentions in its documentation the purpose of merging the 
perceived best features of "the family": "It attempts to bridge the gap 
between the various incompatible members of the Lisp family of languages 
(most notably Common Lisp, Eulisp, LeLisp, and Scheme) by focusing on 
standardizing those areas of widespread agreement." (check the URLs 
bellow, this quote from KMP's ISLISP site). However, it's not as big as 
Common Lisp (but some people mention that Common Lisp is a large as it 
is because it ported functionality that was from the Lisp Machines - but 
I might be wrong, what do I know about Lisp Machines - I wish...).
   ISLISP has objects, generic functions, defmacro and other good 
things. One of its stated aims was industry-use, not academia (that's 
from the spec).
   The TISL implementation is not so much developed as OpenLisp, but 
it's functional and GPLed. OpenLisp is lovely, and it beats the hell out 
of Scheme and Common Lisp on the *huge* number of platforms it compiles 
on. OpenLisp has compiled on over 60 platforms (yes! 16 to 64 bits!), 
and is actively ported today to over 20! So, it's pretty amazing, when 
you take into consideration that platform differences are an issue, 
particularly with Common Lisp implementations (CLISP being the most 
portable), when you need to interact with the OS. So, this is a 
non-issue solved on OpenLisp, just as it is solved on Python or Perl. It 
approaches Perl or Python in portability (or beats them, I dunno). 
OpenLisp's author, unfortunately, isn't much of a "marketing" person... 
I have tested it under win32 and NetBSD on Alpha.

   BTW, I bumped into OpenLisp because of a Lisp-friendly unix shell 
account provider,SDF Public Access Unix Network, a non-profit, that 
supports OpenLisp for CGI (also having the usual Python/Perl, etc).
   I mention ISLISP here because people are unaware of its existence, 
and it's quite a jewel, really.
   And let's be honest, who needs Python/Perl/Ruby when you have Lisp? ;-)

   Well, that's my 2c, get to know and enjoy ISLISP.

   Cheers,


   Henry


OpenLisp   by Eligis
http://christian.jullien.free.fr/
or http://www.eligis.com

TISL  GPL'd ISLISP form Tohoku University (Japan) (under active development)
http://www.ito.ecei.tohoku.ac.jp/TISL/index_j.html

ISLISP - Standards http://anubis.dkuug.dk/JTC1/SC22/WG16/open/standard.html

More ISLISP documentation http://www.islisp.info/, this site maintained 
by Kent Pitman

ISLISP in Java http://cube.misto.cz/lisp/

TBK's links on ISLISP 
http://tkb.mpl.com/~tkb/links/tkb-links-2407134d0e19cfa20a5ebad3c416bc48.html
From: james anderson
Subject: ISLISP [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F7E9BDA.6DCC9852@setf.de>
? do you know of a macos port of this? or even a linux/ppc port?

i was perplexed when i looked at the islisp description. in particular, it is
not obvious why they decided that it was appropriate that it is best that "the
correct syntax of filenames is implementation defined." especially for a
system which intends wide portability it seems couterproductive to establish
such an impediment to application portability. i've looked for mention of
logical-pathname extensions, but have not yet succeeded. can you say anythiing
about how  applications which have been used on various of the islisp
implementations cope with this?

...

synthespian wrote:
> 
> ...
> 
> (etc)
> Hello --
> 
>    I would just like to point out that there's more choice out there in
> the Lisp family than Scheme - Common Lisp.
>    In particular, I would like to mention ISLISP, which is an
> ISO-standard Lisp. Apparently, the story goes somewhat like this: when
> lispers went for an ANSI standard, they left out the Europeans and the
> Japanese - which were the other people heavily using Lisp at the time.
> Thus, ANSI Common Lisp was made all-American. So the people left out
> went for an ISO-standard Lisp.

...
From: synthespian
Subject: Re: ISLISP [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blno13$dnptk$1@ID-78052.news.uni-berlin.de>
james anderson wrote:
> ? do you know of a macos port of this? or even a linux/ppc port?
> 
> i was perplexed when i looked at the islisp description. in particular, it is
> not obvious why they decided that it was appropriate that it is best that "the
> correct syntax of filenames is implementation defined." especially for a
> system which intends wide portability it seems couterproductive to establish
> such an impediment to application portability.
(snip)
  can you say anythiing
> about how  applications which have been used on various of the islisp
> implementations cope with this?
> 
> ....
> 
> synthespian wrote:
> 
>>...
>>
>>(etc)
>>Hello --
>>
>>   I would just like to point out that there's more choice out there in
>>the Lisp family than Scheme - Common Lisp.
>>   In particular, I would like to mention ISLISP, which is an
>>ISO-standard Lisp. Apparently, the story goes somewhat like this: when
>
Hi James --

   There are only two ISLIP implementations that seem ok (as in: 
usable), to me (personal view) - TISL and OpenLisp. TISL seems to be an 
easy case of taking the source and compiling (has been for me). The 
other japanese implementaion seems to have disappeared somewhere inside 
the company that supported it, probably being embeded in some of their 
software. The last one being a java implementation, that's interesting 
for that very reason.
   I don't know if I came across in a clear way on my last post, but the 
point was: 1) there is something called ISLISP that's /actively/ 
developed, it's a Lisp, it's worth taking a look at, particularly when 
you take into consideration the portability that the OpenLisp 
implementation achieved; 2) In particular, the OpenLisp implementation 
has outstanding portability, maybe beating Perl/Python; 3) it is more 
"complete" than Scheme. So, it's a real, feasible, alternative if you 
need portable code.
   I made no claims to what is "best".
   So, in answer to your question, I'd tell you to take a look at the 
extensions to the ISLISP spec available at the OpenLisp manual. If you 
consider that you have an implementation that has compiled on 60 
platforms, is actively maintained on 20, this becomes a non-issue.
   The problem I see with OpenLisp is the free for non-commercial use 
license, but this might change. You might want to get in contact with 
OpenLisp's main developer, he's a very accessible guy. Additionally, you 
might wanna help the development of TISL.

   Regards,

    Henry
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blk95c$8n3$1@news-int.gatech.edu>
> Object system           no              yes
To be fair, most Scheme implementations come with one, and you can always
download an external one if you want. 

> Macro system            syntax-rules    defmacro
Again, depends on the implementation. Gambit offers CL-style macros too.

> Performance             "worse"         "better"
Depends on the implementation. Bigloo did a bit better on the Great Computer
Language Shootout than did CMUCL, though, there were complaints that the
CL-code was sub-par. In the few small benchmarks I've tried on my machine,
Bigloo is pretty competitive with CMUCL.
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F7F15E8.4010709@cs.nyu.edu>
Rayiner Hashem wrote:
>>Object system           no              yes
> 
> To be fair, most Scheme implementations come with one, and you can always
> download an external one if you want. 

Not in R^nRS not in Scheme.

> 
>>Macro system            syntax-rules    defmacro
> 
> Again, depends on the implementation. Gambit offers CL-style macros too.

Why not use CL then?


> 
> 
>>Performance             "worse"         "better"
> 
> Depends on the implementation. Bigloo did a bit better on the Great Computer
> Language Shootout than did CMUCL, though, there were complaints that the
> CL-code was sub-par. In the few small benchmarks I've tried on my machine,
> Bigloo is pretty competitive with CMUCL.

Bigloo is not a standard Scheme.

Cheers
--
Marco
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <a3995c0d.0310041538.4e376d25@posting.google.com>
> Not in R^nRS not in Scheme.
True, but that's not really that big of a deal if you're willing to
stick to a specific implementation. In a lot of cases you're tied to a
specific implementation in CL-land as well. For example, if you use
some of AllegroCL's advanced libraries, you can't just migrate them to
CMUCL if you want.

> Why not use CL then?
Because you refer Scheme?

> Bigloo is not a standard Scheme.
Specifically, Bigloo's type declaration syntax is not standard Scheme.
But if you're willing to stick to Bigloo, then it doesn't make a whole
lot of a difference. Nobody uses just the 50 pages of Scheme defined
in R5RS. There is no reason to. People writing apps in Scheme use
implemenations that provide rich libraries and features on top of
standard Scheme.
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F81B13E.2060002@cs.nyu.edu>
Rayiner Hashem wrote:
>>Not in R^nRS not in Scheme.
> 
> True, but that's not really that big of a deal if you're willing to
> stick to a specific implementation. In a lot of cases you're tied to a
> specific implementation in CL-land as well. For example, if you use
> some of AllegroCL's advanced libraries, you can't just migrate them to
> CMUCL if you want.
> 
> 
>>Why not use CL then?
> 
> Because you refer Scheme?

Sorry, I don't understand.

> 
>>Bigloo is not a standard Scheme.
> 
> Specifically, Bigloo's type declaration syntax is not standard Scheme.
> But if you're willing to stick to Bigloo, then it doesn't make a whole
> lot of a difference. Nobody uses just the 50 pages of Scheme defined
> in R5RS. There is no reason to. People writing apps in Scheme use
> implemenations that provide rich libraries and features on top of
> standard Scheme.

Therefore they write inherently unportable code.  In CL the portable 
base is much much larger and better specified.  Why not use CL then?

Cheers
--
Marco
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwi50wex3seq94@news.nscp.aoltw.net>
Since no one has done a point-by-point correction of the errors w/rt 
Scheme...

On 03 Oct 2003 11:25:31 -0400, Jeremy H. Brown <·······@ai.mit.edu> wrote:
> Here are a few of the (arguably) notable differences:
>
> Scheme          Common Lisp
> Philosophy              minimalism      comprehensiveness
                          orthogonality   compromise

> Namespaces              one             two (functions, variables)
                                          more than two, actually

> Continuations           yes             no
> Object system           no              yes

It really depends on how you define 'object system' as to whether or not 
Scheme has one. I personally think it does, but you have to be prepared
to crawl around the foundations of OOP (and CS generally) before this
becomes apparent. It helps if you've ever lived with unconventional
object systems like Self.

> Exceptions              no              yes
                          yes, via continuations which reify the
                          fundamental control operators in all languages

> Macro system            syntax-rules    defmacro
                          most Schemes provide defmacro style macros as
                          they are relatively easy to implement correctly
                          (easier than syntax-rules anyway)

> Implementations         >10             ~4
                          too many to count. The FAQ lists over twenty. IMO
                          there are about 9 'major' implementations which 
have
                          relatively complete compliance to R5RS and/or
                          significant extension libraries

> Performance             "worse"         "better"
                          This is absolutely wrong. Scheme actually boasts 
one
                          of the most efficient compliers on the planet in 
the
                          StaLIn (Static Language Implementation) Scheme 
system.
                          Larceny, Bigloo, and Gambit are also all quite 
zippy
                          when compiled.

> Standards               IEEE            ANSI
                          Hrmf. 'Scheme' and 'Standard' are slightly skewed 
terms.
                          This is probably both the greatest weakness of 
the
                          language and  also its greatest strength. R5RS is 
more
                          of a description to programmers of how to write 
portable
                          code than it is a constraint on implementors. 
Scheme is
                          probably more of a "family" of languages than 
Lisp is
                          at that.

                          Anyway, Nobody really pays much attention to 
IEEE, although
                          that may change since it's being reworked this 
year. The
                          real standard thus far has been the community 
consensus
                          document called R5RS, the Revised^5 Report on the 
Algorithmic
                          Language Scheme. There is a growing consensus 
that it needs
                          work, but nobody has yet figured out how to make 
a new version happen (And I believe that the IEEE effort is just
                          bringing IEEE up to date w/R5RS)

> Reference name          R5RS            CLTL2
> Reference length        50pp            1029pp
> Standard libraries      "few"           "more"
                          Well, we're up to SRFI-45 (admittedly a number of 
them have been withdrawn, but the code and specification are still 
available) and there's very little overlap.
                          Most of the SRFIs have highly portable 
implementations.

> Support Community       Academic        Applications writers
                          in outlook, perhaps, but the academic component 
has dropped fairly significantly over the years. The best implementations 
still come out of academia, but the better libraries are starting to come 
from people in the industry.
                          There is also an emphasis on heavily-armed 
programming
                          which is sadly lacking in other branches of the 
IT
                          industry. Remember - there is no Scheme 
Underground.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Sander Vesik
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1065311973.638668@haldjas.folklore.ee>
In comp.lang.scheme David Rush <·····@aol.net> wrote:
> 
>> Exceptions              no              yes
>                          yes, via continuations which reify the
>                          fundamental control operators in all languages

the exceptions SRFI and saying it is there as an extension would imho be a
better answer. 

> 
>> Implementations         >10             ~4
>                          too many to count. The FAQ lists over twenty. IMO
>                          there are about 9 'major' implementations which 
> have
>                          relatively complete compliance to R5RS and/or
>                          significant extension libraries
> 

And the number is likely to continue increase over the years. Scheme is
very easy to implement, including as an extensions language inside the
runtime of something else. The same doesn't really hold for common lisp.

> 
> david rush

-- 
	Sander

+++ Out of cheese error +++
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F81B25D.8070301@cs.nyu.edu>
Sander Vesik wrote:
> In comp.lang.scheme David Rush <·····@aol.net> wrote:
> 
>>>Exceptions              no              yes
>>
>>                         yes, via continuations which reify the
>>                         fundamental control operators in all languages
> 
> 
> the exceptions SRFI and saying it is there as an extension would imho be a
> better answer.


It would also be more correct to point out that most of the SRFI's 
address features that are already in the CL standard and reliably 
implemented in all CL implementations (which are at least 9).


> 
> 
>>>Implementations         >10             ~4
>>
>>                         too many to count. The FAQ lists over twenty. IMO
>>                         there are about 9 'major' implementations which 
>>have
>>                         relatively complete compliance to R5RS and/or
>>                         significant extension libraries
>>
> 
> 
> And the number is likely to continue increase over the years. Scheme is
> very easy to implement, including as an extensions language inside the
> runtime of something else. The same doesn't really hold for common lisp.

One of the reasons why all the time spent on the godzillionth 
incompatible Scheme implementation would be better spent on improving 
Common Lisp.

Cheers
--
Marco Antoniotti
From: Mark Brady
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <e840346c.0310031050.21fe45c8@posting.google.com>
"Terry Reedy" <·······@udel.edu> wrote in message news:<······················@comcast.com>...
> "Mark Brady" <······@lycos.com> wrote in message
> ·································@posting.google.com...
> > This whole thread is a bad idea.
> 
> I could agree that the OP's suggestion is a bad idea but do you
> actually think that discussion and more publicity here for Lisp/Scheme
> is bad?  You make a pretty good pitch below for more Python=>Lisp
> converts.
> 

You are right of course, however I dislike cross posting and I also
dislike blatantly arguing with people over language choice. I would
prefer to lead by example. I think one good program is worth a
thousand words. For example people listen to Paul Graham
(http://www.paulgraham.com/avg.html) when he advocates Common Lisp
because he wrote Viaweb using it and made a fortune thanks to Lisp's
features (details in the link).

> > If you like python then use python.
> 
> As I plan to do.
> 

Nothing wrong with that. Most people on these groups would agree that
Python is a very good choice for a wide range of software projects and
it is getting better with every release.

I think that if you can get over S-exps then Scheme and Common Lisp
feel very like python. I would recommend Pythonistas to at least
experiment with Common Lisp or Scheme even if you are perfectly happy
with Python. After all you have nothing to lose. If you don't like it
then fine you always have Python and you've probably learned something
and if you do like it then you have another language or two under your
belt.
   

> > Personally I find Scheme and Common Lisp easier to read but that's
> > just me, I prefer S-exps and there seems to be a rebirth in the
>  cheme
> > and Common Lisp communities at the moment. Ironically this seems to
> > have been helped by python. I learned python then got interested in
> > it's functional side and ended up learning Scheme and Common Lisp. A
> > lot of new Scheme and Common Lisp developers I talk to followed the
> > same route. Python is a great language and I still use it for some
> > things.
> 
> Other Lispers posting here have gone to pains to state that Scheme is
> not a dialect of Lisp but a separate Lisp-like language.  Could you
> give a short listing of the current main differences (S vs. CL)?  If I
> were to decide to expand my knowledge be exploring the current
> versions of one(I've read the original SICP and LISP books), on what
> basis might I make a choice?
> 
> Terry J. Reedy


This is a difficult question to answer. It's a bit like trying to
explain the differences between Ruby and Python to a Java developer
;-)

*Personally* I find it best to think of Scheme and Common Lisp as two
different but very closely related languages. The actual languages and
communities are quite different.

Common Lisp is a large, very pragmatic, industrial strength language
and its community reflects this. Common Lisp has loads of features
that you would normally only get in add on libraries built right into
the language, it's object
system "CLOS" has to be experienced to be believed and its macro
system is stunning. Some very smart people have already put years of
effort into making it capable of great things such as Nasa's award
winning remote agent software
(http://ic.arc.nasa.gov/projects/remote-agent/).

Scheme is a more functional language and unlike Common Lisp is has a
single namespace for functions and variables (Python is like Scheme in
this regard). Common Lisp can be just as functional but on the whole
the Scheme community seem to embrace functional programming to a
greater extend.

Scheme is like python in that the actual language is quite small and
uses libraries for many of the same tasks Python would use them for,
unlike Common Lisp that has many of these features built into the
language. It also has a great but slightly different macro system
although every implementation I know also has Common Lisp style
Macros.

Scheme doesn't have a standard object system (it's more functional)
but has libraries to provide object systems. This is very hard to
explain to python developers, scheme is kind of like a big python
metaclass engine where different object systems can be used at will.
It's better than I can describe and it is really like a more powerful
version of Pythons metaclass system.

Pythonistas who love functional programming may prefer Scheme to
Common Lisp while Pythonistas who want a standard amazing object
system and loads of built in power in their language may prefer Common
Lisp.

To be honest the these tutorials will do a far better job than I
could:

For Scheme get DrScheme:
http://www.drscheme.org/

and go to

'Teach yourself scheme in fixnum days' : 
http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html


For Common Lisp get the trial version of Lispworks:
http://www.lispworks.com/

and go get Mark Watsons free web book:
http://www.markwatson.com/opencontent/lisp_lic.htm

Regards,
Mark.

Ps. If anyone spots a mistake in this mail please correct me, it will
have been an honest one and not an attempt to slander your favourite
language and I will be glad to be corrected, in other words there is
no need to flame me :)
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <qwmfb.163149$hE5.5480026@news1.tin.it>
Mark Brady wrote:
   ...
> This is a difficult question to answer. It's a bit like trying to
> explain the differences between Ruby and Python to a Java developer
> ;-)

Been there, done that, it's not all _that_ difficult.  The average Java 
developer is quite able to understand the differences if you explain them 
in terms of similarities and differences from Lisp ("Python has immutable 
strings like Java, while Ruby's strings are mutable; Ruby has single 
inheritance like Java, plus mix-ins, while Python has multiple inheritance, 
with certain limitations", etc) and ability to interoperate ("Python has an 
implementation that runs on a JVM, uses any Java class, and can generate 
.class and .jar files just as if you had coded in Java, Ruby doesn't").

I think the "cultural" differences are subtler and more interesting (and 
also, no doubt, even more debatable:-) -- the distinction between a Python 
culture that takes pride in simplicity, uniformity, and avoidance of clever 
tricks, versus a Ruby  one that's quite different in these regards, IMHO.

Similarly, I suspect (but with even less reason to believe my observations 
are correct) that the concept of a language being small and simple may be a 
source of pride to the Scheme crowd (as it is, say, to the Python or C 
ones), while that of a language being large and comprehensive may appeal to 
Common Lispers (as it does, say, to C++ites or Perlmongers).

Such "soft-sciences" considerations may help guide one's choices about what
language to study next, I believe.  E.g., a Pythonista who's looking for a 
brisk "change of pace" might be more likely to find it in large-language 
Common Lisp, while one who's looking for another "small, simple language" 
culture might be more likely to find it in Scheme.


Alex
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <md4snvook6r0rev0om1lhukd2mh46e15f3@4ax.com>
On Fri, 03 Oct 2003 22:13:42 GMT, Alex Martelli <·····@aleax.it>
wrote:


>Similarly, I suspect (but with even less reason to believe my observations 
>are correct) that the concept of a language being small and simple may be a 
>source of pride to the Scheme crowd (as it is, say, to the Python or C 
>ones), while that of a language being large and comprehensive may appeal to 
>Common Lispers (as it does, say, to C++ites or Perlmongers).

Ugh, you didn't seriously just compare to CL to C++ and Perl!  That's
Heresy in these parts.

I was going to go into a long winded explanation of why that
comparison isn't correct, but it's so wrong on so many levels that I'm
not going to even attempt it.

Suffice it to say that CL has much more in common with Python that in
does with Perl or C++.  It is about practicality rather than purity.

I'm not even going to touch the differences between Scheme and CL, if
you want a good history just google for them.  

However I will say that coming from Python, I feel much more
comfortable in CL than in Scheme.


Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: synthespian
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bllvmj$dmflu$1@ID-78052.news.uni-berlin.de>
Alex Martelli wrote:

> Mark Brady wrote:
>    ...
> 
>>This is a difficult question to answer. It's a bit like trying to
>>explain the differences between Ruby and Python to a Java developer
>>;-)
> 
> 
> Been there, done that, it's not all _that_ difficult.  The average Java 
> developer is quite able to understand the differences if you explain them 
> in terms of similarities and differences from Lisp ("Python has immutable 
> strings like Java, while Ruby's strings are mutable; Ruby has single 
> inheritance like Java, plus mix-ins, while Python has multiple inheritance, 
> with certain limitations", etc) and ability to interoperate ("Python has an 
> implementation that runs on a JVM, uses any Java class, and can generate 
> .class and .jar files just as if you had coded in Java, Ruby doesn't").
> 
> I think the "cultural" differences are subtler and more interesting (and 
> also, no doubt, even more debatable:-) -- the distinction between a Python 
> culture that takes pride in simplicity, uniformity, and avoidance of clever 
> tricks, versus a Ruby  one that's quite different in these regards, IMHO.
> 

Honestly...
Python: similarities with Common Lisp, ever greenspunning itself 
(Dylan's C3MRO class-precedence algorithm being the latest, the whole 
model of interaction, the indentation wanna-be-s-exprs, the syntax 
similarities pointed out by Norvig - and the name "python" - wonder 
where they got /that/ from ;-)). Sure, a nice language.
Ruby: of similarities with Smalltalk (Smalltalk cum Perl cum mixins?) 
Have they sorted out their namespace problem already?

The originals were made by clever people, some eons ago, and remain 
unsurpassed.

I used to think Perl was bad, but I educated myself more, and came to 
appreciate the Parrot guys. Now I think at least they were somewhat 
original (AWK/shell/C notwithstanding).

Henry
From: synthespian
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bllucu$d3fjc$1@ID-78052.news.uni-berlin.de>
Mark Brady wrote:

> Pythonistas who love functional programming may prefer Scheme to
> Common Lisp while Pythonistas who want a standard amazing object
> system and loads of built in power in their language may prefer Common
> Lisp.
> 
(snip)
> Regards,
> Mark.
> 
> Ps. If anyone spots a mistake in this mail please correct me, it will
> have been an honest one and not an attempt to slander your favourite
> language and I will be glad to be corrected, in other words there is
> no need to flame me :)

I would just say that CLOS (Common Lisp Object System) is not "standard" 
in the sense people take OOP to be nowadays, but able to encompass and 
go beyond the JAVA, C++, Python, etc, paradigm. This fact was 
demonstrated briefly on Paul Graham's ANSI Common LISP book, and 
elsewhere, and it's basically a satori.

Henry
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwi0800f3seq94@news.nscp.aoltw.net>
On Fri, 3 Oct 2003 09:36:32 -0400, Terry Reedy <·······@udel.edu> wrote:
> ... Lispers posting here have gone to pains to state that Scheme is
> not a dialect of Lisp but a separate Lisp-like language.  Could you
> give a short listing of the current main differences (S vs. CL)?

Do you even begin to appreciate how inflammatory such a request is when 
posted to to both c.l.l and c.l.s?

Anyway, as a fairly heavily biased Schemer:

	Scheme vs Common Lisp

	1 name space vs multiple name spaces
		This is a bigger issue than it seems on the surface, BTW

	#f vs nil
		In Scheme an empty list is not considered to be the same
		thing as boolean false

	emphasis on all values being first-class vs ad-hoc values
		Scheme tries to achieve this, Lisp is by conscious design a
		compromise system design, for both good and bad

	small semantic footprint vs large semantic footprint
		Scheme seems relatively easier to keep in mind as an
		additional language.CL appears to have several sub-languages
		embedded in it. This cuts both ways, mind you.

Thos eare the most obvious surface issues. My main point is that it is
pretty much silly to consider any of the above in isolation. Both languages
make a lot of sense in their design context. I vastly prefer Scheme because
it suits my needs (small semantic footprint, powerful toolkit) far better
than CL (everything is there if you have the time to look for it). I should
point out that I build a lot of funny data structures (suffix trees and 
other
IR magic) for which pre-built libraries are both exceedingly rare and
incorrectly optimized for the specific application.

I also like the fact that Scheme hews rather a lot closer to the 
theoretical
foundations of CS than CL, but then again that's all part of the small 
semantic
footprint for me.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <vR-cnXOu-IquueKiXTWJkQ@comcast.com>
"David Rush" <·····@aol.net> wrote in message
·····················@news.nscp.aoltw.net...
> On Fri, 3 Oct 2003 09:36:32 -0400, Terry Reedy <·······@udel.edu>
wrote:
> > ... Lispers posting here
By 'here', I meant comp.lang.python ...

>> have gone to pains to state that Scheme is
> > not a dialect of Lisp but a separate Lisp-like language.  Could
you
> > give a short listing of the current main differences (S vs. CL)?

> Do you even begin to appreciate how inflammatory such a request is
> when posted to to both c.l.l and c.l.s?

As implied by 'here', I did not originally notice the cross-posting
(blush, laugh ;<).  I am pleased with the straightforward, civil, and
helpful answers I have received, including yours, and have saved them
for future reference.

...
> compromise system design, for both good and bad
...
> embedded in it. This cuts both ways, mind you.
...

I believe in neither 'one true religion' nor in 'one best
algorithm/computer language for all'.  Studying Lisp has helped me
better understand Python and the tradeoffs embodied in its design.  I
certainly better appreciate the issue of quoting and its relation to
syntax.

Terry J. Reedy
From: Matthias
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <36wwubmft6r.fsf@chagall.ti.uni-mannheim.de>
······@lycos.com (Mark Brady) writes:
> Paul Rubin's comments are just pure fud. 
[...]
> Develop in the language that suits you but despite the fud you do have
> a choice,
> Python, Scheme and Common Lisp are all fine languages with good
> libraries and FFI capabilities.

I think that's incorrect: The Common Lisp language has no FFI (foreign
function call) capabilities.  Each CL _implementation_ has one (which
is usually compatible to itself).  This is exactly the reason why
there are way more libraries out there for Python, Perl, maybe Ruby
than for any single CL implementation.  The same probably holds for
Scheme.
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <877k3mxgpi.fsf@bird.agharta.de>
On 03 Oct 2003 13:37:32 +0200, Matthias <··@spam.pls> wrote:

> I think that's incorrect: The Common Lisp language has no FFI
> (foreign function call) capabilities.  Each CL _implementation_ has
> one (which is usually compatible to itself).  This is exactly the
> reason why there are way more libraries out there for Python, Perl,
> maybe Ruby than for any single CL implementation.  The same probably
> holds for Scheme.

I'd say the Python /language/ also has no FFI capabilities. Either
that, or the Jython people are lying when they say that Jython "is an
implementation of the [...] language Python."  (On the same website:
"Many of these modules are not yet implemented. Those coded in C for
CPython must be re-implemented in Java for Jython.")

Common Lisp and Scheme are languages defined by ANSI standards -
that's why you can have different implementations. Python, Perl, and
Ruby are defined by a reference implementation. You're comparing
apples and oranges.

Edi.
From: Toni Nikkanen
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <rlpvfr6y28r.fsf@morgoth.tuug.fi>
······@lycos.com (Mark Brady) writes:

> just me, I prefer S-exps and there seems to be a rebirth in the Scheme
> and Common Lisp communities at the moment. Ironically this seems to
> have been helped by python. I learned python then got interested in
> it's functional side and ended up learning Scheme and Common Lisp. 

It's be interesting to know where people got the idea of learning
Scheme/LISP from (apart from compulsory university courses)? I think
that for me, it was the LPC language used in LPmuds. It had a
frightening feature called lambda closures, and useful functions such
as map and filter. Then one day I just decided to bite the bullet and
find out where the heck all that stuff came from (my background was
strongly in C-like languages at that point. LPC is like C with some
object-oriented and some FP features.)

Yes, I know, there's nothing frightening in lambda closures. But the
way they were implemented in LPC (actually just the syntax) was
terrible :)
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <FUefb.3455$pv6.3327@twister.nyc.rr.com>
Toni Nikkanen wrote:

> ······@lycos.com (Mark Brady) writes:
> 
> 
>>just me, I prefer S-exps and there seems to be a rebirth in the Scheme
>>and Common Lisp communities at the moment. Ironically this seems to
>>have been helped by python. I learned python then got interested in
>>it's functional side and ended up learning Scheme and Common Lisp. 
> 
> 
> It's be interesting to know where people got the idea of learning
> Scheme/LISP from (apart from compulsory university courses)? 

<g> We wonder alike. That's why I started:

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

That recently got repotted from another cliki and it's a little mangled, 
but until after ILC2003 I am a little too swamped to clean it up. But 
there is still a lot of good stuff in there. On this page I grouped 
folks according to different routes to Lisp (in the broadest sense of 
that term): http://alu.cliki.net/The%20RtLS%20by%20Road

You will find some old-timers because I made the survey super-inclusive, 
but my real interest was the same as yours: where are the New Lispniks 
coming from?

Speaking of which, Mark Brady cited Python as a stepping-stone, and I 
have been thinking that might happen, but the survey has yet to confirm. 
Here's one: http://alu.cliki.net/Robbie%20Sedgewick's%20Road%20to%20Lisp

So Ping! Mark Brady, please hie ye (and all the others who followed the 
same road to Lisp) to the survey and correct the record.

I think
> that for me, it was the LPC language used in LPmuds. It had a
> frightening feature called lambda closures, and useful functions such
> as map and filter. Then one day I just decided to bite the bullet and
> find out where the heck all that stuff came from (my background was
> strongly in C-like languages at that point. LPC is like C with some
> object-oriented and some FP features.)
> 
> Yes, I know, there's nothing frightening in lambda closures. But the
> way they were implemented in LPC (actually just the syntax) was
> terrible :)

You could cut and paste that into the survey as well. :)

kenny
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <baffb.3638$pv6.1100@twister.nyc.rr.com>
Kenny Tilton wrote:

> 
> 
> Toni Nikkanen wrote:
> 
>> It's be interesting to know where people got the idea of learning
>> Scheme/LISP from (apart from compulsory university courses)? 
> 
> 
> <g> We wonder alike. That's why I started:
> 
>    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
> 
> That recently got repotted from another cliki and it's a little mangled, 
> but until after ILC2003 I am a little too swamped to clean it up.

Me and my big mouth. Now that I have adevrtised the survey far and wide, 
and revisited it and seen up close the storm damage, sh*t, there goes 
the morning. :) Well, I needed a break from RoboCells:

    http://sourceforge.net/projects/robocells/

I am going to do what I can to fix up at least the road categorization, 
and a quick glance revealed some great new entries, two that belong in 
my Top Ten (with apologies to those getting bumped).

kenny
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <gPifb.5074$pv6.3800@twister.nyc.rr.com>
Kenny Tilton wrote:

> 
> 
> Kenny Tilton wrote:
> 
>>
>>
>> Toni Nikkanen wrote:
>>
>>> It's be interesting to know where people got the idea of learning
>>> Scheme/LISP from (apart from compulsory university courses)? 
>>
>>
>>
>> <g> We wonder alike. That's why I started:
>>
>>    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
>>
>> That recently got repotted from another cliki and it's a little 
>> mangled, but until after ILC2003 I am a little too swamped to clean it 
>> up.
> 
> 
> Me and my big mouth. Now that I have adevrtised the survey far and wide, 
> and revisited it and seen up close the storm damage, sh*t, there goes 
> the morning. :) 


OK, I copied over all the twenty-plus pages that got lost in the 
repotting, fixed the survey questions, and even took the time to 
annotate my Top Ten list:

    http://alu.cliki.net/Kenny's%20RtLS%20Top-Ten

Check it out. The Switch Date pages have been restored, but I do not 
think the cross-indexing works until pages get edited and resaved. That 
is not the most fascinating breakdown in the world, so it may be a while 
before I fuss with that. But this breakdown is cool:

    http://alu.cliki.net/The%20RtLS%20by%20Road

More responses always welcome.

kenny
From: Toni Nikkanen
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <rlpn0cixwrm.fsf@morgoth.tuug.fi>
Kenny Tilton <·······@nyc.rr.com> writes:

> Speaking of which, Mark Brady cited Python as a stepping-stone, and I
> have been thinking that might happen, but the survey has yet to
> confirm. 

It usually happens that when I google for some scheme/lisp-isms,
I get lots of Python mailing list messages as results. There's
something going on with that.
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <52ornv0ceoqc6u61cge0iqnjo9re6a4fds@4ax.com>
On Fri, 03 Oct 2003 13:33:25 GMT, Kenny Tilton <·······@nyc.rr.com>
wrote:

>> 
>> It's be interesting to know where people got the idea of learning
>> Scheme/LISP from (apart from compulsory university courses)? 
>
><g> We wonder alike. That's why I started:
>
>    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
>

Kenny, something you said in the passed bugged me just a little.  It
was when you began grouping the Surveys together, you made the
suggestion that the people who were learning Lisp due to a
dissatisfaction with their current language were the future of Lisp
and for some reason you seemed to rule out all the people who were led
to Lisp by Paul Graham from this group.

While it's true that I heard about Lisp and many of it's advantages
from Paul Graham, I ultimately have decided to cast my lot with Lisp
because of my deep dissatisfaction with the so called Languages for
the Masses.

So I guess I felt a little left out of the "future of Lisp" group,
even though I came to Lisp under my own will power and without the
prodding and poking of a college professor.  Interestingly I never
took a single Lisp or Scheme class for my CS degree.  I wonder what
that says about my degree.

Even so, I am very much looking forward to your Cells talk at the ILC.
Is it still going to be deliverable in a blacked out room?

Good luck on your preparation.


Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mQmfb.5370$pv6.32@twister.nyc.rr.com>
Doug Tolton wrote:
> On Fri, 03 Oct 2003 13:33:25 GMT, Kenny Tilton <·······@nyc.rr.com>
> wrote:
> 
> 
>>>It's be interesting to know where people got the idea of learning
>>>Scheme/LISP from (apart from compulsory university courses)? 
>>
>><g> We wonder alike. That's why I started:
>>
>>   http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
>>
> 
> 
> Kenny, something you said in the passed bugged me just a little.  It
> was when you began grouping the Surveys together, you made the
> suggestion that the people who were learning Lisp due to a
> dissatisfaction with their current language were the future of Lisp
> and for some reason you seemed to rule out all the people who were led
> to Lisp by Paul Graham from this group.
> 
> While it's true that I heard about Lisp and many of it's advantages
> from Paul Graham, I ultimately have decided to cast my lot with Lisp
> because of my deep dissatisfaction with the so called Languages for
> the Masses.
> 

First of all, you are absolutely right. Taxonomies all suck. Thank god 
for multiple inheritance, since you fall into two classes. Don't forget, 
  in the "By Road" taxonomy one is allowed multiple Roads. I think 
someone had six or seven.

Second, I think you misconstrued my enthusiasm for stories involving a 
deliberate search for A Better Way(tm). That does not make those newbies 
better for Lisp, it's just worse news for the status quo.

You see, I once read a piece about how timing is everything in these 
techno-competitions. The better mouse-trap also must get a break 
timing-wise, or some lesser technology gets in and cannot be unseated. 
It wasn't Gabriel's "Worse Is Better", but similar. The danger is that 
no matter how good is Lisp, that won't help if Java cannot be unseated. 
The fact that people (such as yourself) gallop for the mountains when 
they find the barn door open suggests Java's dominance today will not 
help it tomorrow (meaning I guess that dominance is great only below a 
certain level of suckitude).

All I was saying was that stories where people kicked out the sides of 
the barn to escape are even stronger evidence that, contrary to the 
doomsday pattern in the piece I read, in fact we are in more of a Yogi 
scenario: It ain't over till it's over.

But most of all, taxonomies suck and are arbitray and have artificial 
boundaries. I doubt you would have reacted as you did to what Graham 
wrote if you were not at some level searching for an escape route.

> Even so, I am very much looking forward to your Cells talk at the ILC.
> Is it still going to be deliverable in a blacked out room?
> 

Sure. I splurged on the laptop with the screen you can view from 90% on 
either side. Everyone can come up on stage and we'll just huddle around 
for the demo. I slouch at the keyboard as well, so everyone should be 
able to see. :)

kenny

ps. Come to think of, maybe the very worst news for Java is people who 
like it and /still/ switch to Lisp. Hmmmm....

k
From: Rene van Bevern
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnr2pu.1qe.rvb@negoyl.vb-network>
On 03 Oct 2003 14:44:36 +0300, Toni Nikkanen <····@tuug.fi> wrote:
> It's be interesting to know where people got the idea of learning
> Scheme/LISP from (apart from compulsory university courses)?

i came from C, learned some other languages and then ruby. I wanted to
know why one could write "lambda" instead of the proc keyword and i got
pointed out to lambda calculus and lisp ;) because lambda did not make
sense to me, because i only knew its meaning as a greek letter.

also there were a lot of people on the ruby newsgroup talking about LISP
and so i wanted to try it.

First i was discouraged because of the lack of libraries. i also doubted
that LISP hat the power and versatileness of ruby, but in this point i
was very wrong ;)

At the moment i am still learning, have read the Gentle Introduction to
Symbolic Computation, On Lisp and now reading in CLTL2 about the things
the other two books did not cover.

I know at least one more person who came to LISP/Scheme over ruby. Maybe
it needs ruby and python to enlighten people without confusing them with
a syntax they are not used to first. ;)

bye
	Rene
From: Grzegorz Chrupala
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8b9e2260.0310031455.227084e3@posting.google.com>
Rene van Bevern <···@rvb.dyndns.org> wrote in message news:<··················@negoyl.vb-network>...
 
> I know at least one more person who came to LISP/Scheme over ruby. Maybe
> it needs ruby and python to enlighten people without confusing them with
> a syntax they are not used to first. ;)

I can't remember how *exactly* I came to use scheme (unfortuantely I
don't keep a diary), but trying to reconstruct it looks something like
this:

I am actually not a programmer, but mostly a linguist. About four 
years ago I got interested in computational linguistics and decided to
learn a programming language. The first programming book I picked up
was "The Gentle Introduction..." (Common Lisp). I made sense to me but
I couldn't find a plug'n' play lisp implementation (I was pretty
computer-illiterate at the time: could only manage v. basic stuff on
Windoze). So I put that aside and decided to have a go at Perl (widely
used in NLP). That was much easier, I installed the ActiveState win32
port no problems and picked Perl up from  online tutorials and the
multitude of other easily accessible Perl resources. After I've played
with perl for a while I heard about Python and Ruby, which to me
looked like more sophisticated versions of Perl, and I switched to
Ruby for most of my toy and not-so-toy scripts. While reading
ruby-talk and other ruby-stuff I kept coming across references to
Scheme and Lisp, which I was already vaguely familiar with from my
perusal of the "Gentle Introduction". At this point I was already
using Linux and so could easily install Clisp and half a dozen Scheme
implementations. Schemes such as Gauche, Bigloo and PLT seemed like
they were better suited to writing the sort of small programs or CGI
scripts that I was using Perl and Ruby for, so I sort of settled for
Scheme. (Sometime during this time I also learned Prolog in a
university course and it made me aware of the various advantages, as
well as some disadvantages, of using a very high level languages in
comp-ling).
At the moment I am quite happy with Scheme although I do miss the
large lively communities and the amout of libraries associated with
Perl, Python and Ruby. I hope the "revival" of Lisp-like languages
some of you have observed will gain momentum and that CL anb Scheme
will catch up with Python and Ruby in the areas where they are behind.

Cheers,
--
Grzegorz
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <IGofb.5735$pv6.4292@twister.nyc.rr.com>
Grzegorz Chrupala wrote:

> Rene van Bevern <···@rvb.dyndns.org> wrote in message news:<··················@negoyl.vb-network>...
>  
> 
>>I know at least one more person who came to LISP/Scheme over ruby. Maybe
>>it needs ruby and python to enlighten people without confusing them with
>>a syntax they are not used to first. ;)
> 
> 
> I can't remember how *exactly* I came to use scheme (unfortuantely I
> don't keep a diary), but trying to reconstruct it looks something like
> this:

It would be valuable to have what you wrote next in:

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

Lisp there is defined as "any member of the Lisp family".

Aside: oh, great. Now the survey is going to get thrown off the ALU 
Cliki by the Iki Police. um, could you all find something less 
productive to focus on? Cutting and pasting thirty pages is /so/ helpful 
to the Lisp community. Not!!!

You can be response #78...oops, #79.

Or e-mail me a go-ahead and I'll do the legwork.

kenny
From: Grzegorz Chrupala
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8b9e2260.0310032252.228a5cf0@posting.google.com>
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<···················@twister.nyc.rr.com>...

> 
> It would be valuable to have what you wrote next in:
> 
>    http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey

OK, I've put it in there. 

[By the way, the Wiki seems to make it impossible to spell non-ascii
names correctly in page titles. The last but one letter in my name is 
(integer->char 322) rather than (integer->char 108)]

[By the way, SCHEMERS, are we going to have a wiki like COMMON Lispers
do? I know it's been asked before, just nagging :)]

Cheers,
--
Grzegorz
From: Dave Pearson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnr93m.e3h.davep.news@hagbard.davep.org>
* Rene van Bevern <···@rvb.dyndns.org>:

> First i was discouraged because of the lack of libraries. i also doubted
> that LISP hat the power and versatileness of ruby, but in this point i was
> very wrong ;)

I'm not sure if "wrong" relates to both the points in that paragraph or just
the ruby point. But reading the above made me think about this post
<URL:http://groups.google.com/groups?selm=85he2th31x.fsf%40junk.nocrew.org>
from the other day.

Not that this actually says that your first point is wrong, but I guess it's
a list many people don't notice at first.

-- 
Dave Pearson
http://www.davep.org/lisp/
From: Rene van Bevern
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnt5qq.f1.rvb@negoyl.vb-network>
On 3 Oct 2003 16:31:50 GMT, Dave Pearson <··········@davep.org> wrote:
> I'm not sure if "wrong" relates to both the points in that paragraph or just
> the ruby point. But reading the above made me think about this post
><URL:http://groups.google.com/groups?selm=85he2th31x.fsf%40junk.nocrew.org>
> from the other day.
>
> Not that this actually says that your first point is wrong, but I guess it's
> a list many people don't notice at first.

well, ok, this list *looks* large and you seem to find libraries for a
lot of tasks there. the other thing is, that many of these libraries are
badly-documented or in an early development stage. many of them have
examples, though, which are very good, even better than a huge
collection of documentation (in some cases).

	Rene
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwiphz2j3seq94@news.nscp.aoltw.net>
On 03 Oct 2003 14:44:36 +0300, Toni Nikkanen <····@tuug.fi> wrote:
> It's be interesting to know where people got the idea of learning
> Scheme/LISP from (apart from compulsory university courses)?

Emacs. I've noticed over the years that people don't really get Emacs
religion until they've started hacking elisp. I know that the frustration
of having almost-but-not-quite the behavior I wanted on top of having all
that source code was a powerful incentive for me to learn Lisp. Of course
my apreciation of Emacs only increased as I went...

The thing that sealed it for me was re-programming SCWM's behavior so that
I could use X w/no mouse &cet. That got me hooked on Scheme (I had been
hacking SML at roughly the same time while looking for the foundations of
OOP), which was really just about perfect semantically.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Sander Vesik
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1065308133.373374@haldjas.folklore.ee>
In comp.lang.scheme David Rush <·····@aol.net> wrote:
> On 03 Oct 2003 14:44:36 +0300, Toni Nikkanen <····@tuug.fi> wrote:
>> It's be interesting to know where people got the idea of learning
>> Scheme/LISP from (apart from compulsory university courses)?
> 
> Emacs. I've noticed over the years that people don't really get Emacs
> religion until they've started hacking elisp. I know that the frustration
> of having almost-but-not-quite the behavior I wanted on top of having all
> that source code was a powerful incentive for me to learn Lisp. Of course
> my apreciation of Emacs only increased as I went...

I have at times almost gnawed off my hand to avoid going down that path.
I'd rather write cobol than elisp...

> 
> The thing that sealed it for me was re-programming SCWM's behavior so that
> I could use X w/no mouse &cet. That got me hooked on Scheme (I had been
> hacking SML at roughly the same time while looking for the foundations of
> OOP), which was really just about perfect semantically.
> 
> david rush

-- 
	Sander

+++ Out of cheese error +++
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <crIfb.14315$pv6.1105@twister.nyc.rr.com>
Sander Vesik wrote:
> I have at times almost gnawed off my hand to avoid going down that path.
> I'd rather write cobol than elisp...

Mileage does vary :): http://alu.cliki.net/RtL%20Emacs%20Elisp

That page lists people who actually cite Elisp as at least one way they 
got turned on to Lisp. I started the survey when newbies started showing 
up on the c.l.l. door in still small but (for Lisp) significantly larger 
numbers. Pail Graham holds a commanding lead, btw.

kenny
From: Paul Rubin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7xd6dclh91.fsf@ruckus.brouhaha.com>
Kenny Tilton <·······@nyc.rr.com> writes:
> That page lists people who actually cite Elisp as at least one way
> they got turned on to Lisp. I started the survey when newbies started
> showing up on the c.l.l. door in still small but (for Lisp)
> significantly larger numbers. Pail Graham holds a commanding lead, btw.

I'd fooled around with other lisp systems before using GNU Emacs, but
reading the Emacs source code was how I first got to really understand
how Lisp works.
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-E90B17.16463604102003@news.service.uci.edu>
In article <····················@twister.nyc.rr.com>,
 Kenny Tilton <·······@nyc.rr.com> wrote:

> > I have at times almost gnawed off my hand to avoid going down that path.
> > I'd rather write cobol than elisp...
> 
> Mileage does vary :): http://alu.cliki.net/RtL%20Emacs%20Elisp
> 
> That page lists people who actually cite Elisp as at least one way they 
> got turned on to Lisp. I started the survey when newbies started showing 
> up on the c.l.l. door in still small but (for Lisp) significantly larger 
> numbers. Pail Graham holds a commanding lead, btw.

Heh.  Does that mean former TECO programmers will get turned on to Perl?  
Hasn't had that effect for me yet...

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Rene van Bevern
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnvk3q.cn.rvb@negoyl.vb-network>
On Sat, 04 Oct 2003 13:11:49 +0100, David Rush <·····@aol.net> wrote:
> Emacs. I've noticed over the years that people don't really get Emacs
> religion until they've started hacking elisp. I know that the frustration
> of having almost-but-not-quite the behavior I wanted on top of having all
> that source code was a powerful incentive for me to learn Lisp. Of course
> my apreciation of Emacs only increased as I went...

hm. i really like LISP, but still don't get through emacs. After i
learned a bit LISP i wanted to try it again, and again i failed ;) i
know vim from the in- and out- side and just feel completely lost in
emacs.

i also like vim with gtk2 support more. not because of menu or toolbar,
which are usually switched off in my config, but because of antialiased
letters. I just don't like coding with bleeding eyes anymore ;)

*to me* vim just looks and feels much more smooth than emacs, so i don't
think that hacking LISP influences the choice of the editor much. it of
course makes people *try* Emacs because of its LISP support.

	Rene
From: Matthew Danish
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <20031005152851.GH1454@mapcar.org>
On Sun, Oct 05, 2003 at 10:04:10AM +0200, Rene van Bevern wrote:
> hm. i really like LISP, but still don't get through emacs. After i
> learned a bit LISP i wanted to try it again, and again i failed ;) i
> know vim from the in- and out- side and just feel completely lost in
> emacs.

http://www.lisp-p.org/htdocs/15-vim/

Of course, a good way not to feel lost in emacs is to use C-h t, C-h b,
or the variety of other C-h commands, as it recommends on start-up.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Rene van Bevern
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbo0rre.3i5.rvb@negoyl.vb-network>
On Sun, 5 Oct 2003 11:28:51 -0400, Matthew Danish <·······@andrew.cmu.edu> wrote:
> http://www.lisp-p.org/htdocs/15-vim/

yup, i know that, using that a lot ;)

> Of course, a good way not to feel lost in emacs is to use C-h t, C-h b,
> or the variety of other C-h commands, as it recommends on start-up.

well, these are actually one of the reasons i feel quite lost ;) i have
to read a lot of stuff just to be able to do things i could do
immediately in vim. of course it needed me to read vim's help too. but
it is actually the point, that there is no real reason for me to switch
to emacs, which is what i wanted to express refering to the statement
that one needs lisp to get emacs' religion.

i didn't get its religion, neither with nor without lisp ;)

	Rene
From: Matthew Danish
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <20031005213731.GI1454@mapcar.org>
On Sun, Oct 05, 2003 at 09:22:22PM +0200, Rene van Bevern wrote:
> On Sun, 5 Oct 2003 11:28:51 -0400, Matthew Danish <·······@andrew.cmu.edu> wrote:
> > Of course, a good way not to feel lost in emacs is to use C-h t, C-h b,
> > or the variety of other C-h commands, as it recommends on start-up.
> 
> well, these are actually one of the reasons i feel quite lost ;) i have
> to read a lot of stuff just to be able to do things i could do
> immediately in vim. of course it needed me to read vim's help too. but
> it is actually the point, that there is no real reason for me to switch
> to emacs, which is what i wanted to express refering to the statement
> that one needs lisp to get emacs' religion.

Well, once someone "gets lisp" so to speak, he realizes that emacs's
lisp is rather sucky and has only the advantage of being widely used.

Personally, I use vim quite a lot too (for example, this post), but I
never found the lisp editing capabilities of vim to be very highly
developed.  As bad as ILISP is, it does integrate enough to be
worthwhile using.  Emacs is not that great, it's just good enough and
readily available.  (who says worse is better doesn't apply to lisp? ;)

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: MetalOne
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <92c59a2c.0310031345.57d20631@posting.google.com>
······@lycos.com (Mark Brady) wrote in message news:<····························@posting.google.com>...
> Personally I find Scheme and Common Lisp easier to read but that's
> just me, I prefer S-exps ...

I am just barely familiar with Lisp and Scheme.  However, I always
find comments like the above interesting.  I have seen other people
make this claim also.
However, from an earlier post on comp.lang.python comparing a simple
loop.

Scheme
(define vector-fill!
  (lambda (v x)
    (let ((n (vector-length v)))
      (do ((i 0 (+ i 1)))
          ((= i n))
          (vector-set! v i x)))))

Python
def vector_fill(v, x):
    for i in range(len(v)):
        v[i] = x

To me the Python code is easier to read, and I can't possibly fathom
how somebody could think the Scheme code is easier to read.  It truly
boggles my mind.

The second thing that puzzles me is the usage of the LISP macro
system.  This system is touted as one of LISPs major strengths.  I
believe the "Do" above is a  macro.  Is that the best syntax that can
be achieved with a macro for "Do".  I would think there would already
be macros to write the Scheme code above in a format similar to the
Python code below, or some more readable syntax.  I have looked for
repositories of such macros and I can't find any.  This leads me to
think that in practice LISP macros are not used.  Couple this with the
fact that LISP programmers seem happier with S-exprs, and I can't see
why a LISP programmer would even want to write a macro.

I have tried on 3 occassions to become a LISP programmer, based upon
the constant touting of LISP as a more powerful language and that
ultimately S-exprs are a better syntax.  Each time, I have been
stopped because the S-expr syntax makes we want to vomit.

If a set of macros could be written to improve LISP syntax, then I
think that might be an amazing thing.  An interesting question to me
is why hasn't this already been done.
From: Paul Rubin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7xisn6arb1.fsf@ruckus.brouhaha.com>
···@iteris.com (MetalOne) writes:
> Scheme
> (define vector-fill!
>   (lambda (v x)
>     (let ((n (vector-length v)))
>       (do ((i 0 (+ i 1)))
>           ((= i n))
>           (vector-set! v i x)))))

I think you could write the scheme code like this:

    (define vector-fill! (v x)
      (let ((i 0))
         (while (< i (length v))
            (vector-set! v i x)
            (set! i (1+ i)))))

> I have tried on 3 occassions to become a LISP programmer, based upon
> the constant touting of LISP as a more powerful language and that
> ultimately S-exprs are a better syntax.  Each time, I have been
> stopped because the S-expr syntax makes we want to vomit.

If you go crazy with macros, lisp gets confusing, that's for sure.
From: Sampo Smolander
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bllqph$7n9$2@oravannahka.helsinki.fi>
In comp.lang.scheme Paul Rubin <·············@nospam.invalid> wrote:
> I think you could write the scheme code like this:

>     (define vector-fill! (v x)

I guess parenthesising like

   (define (vector-fill! v x)

would be more schemey.

[Followups set to scheme-group only]
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0310031646010001@k-137-79-50-101.jpl.nasa.gov>
In article <····························@posting.google.com>,
···@iteris.com (MetalOne) wrote:

> ······@lycos.com (Mark Brady) wrote in message
news:<····························@posting.google.com>...
> > Personally I find Scheme and Common Lisp easier to read but that's
> > just me, I prefer S-exps ...
> 
> I am just barely familiar with Lisp and Scheme.  However, I always
> find comments like the above interesting.  I have seen other people
> make this claim also.
> However, from an earlier post on comp.lang.python comparing a simple
> loop.
> 
> Scheme
> (define vector-fill!
>   (lambda (v x)
>     (let ((n (vector-length v)))
>       (do ((i 0 (+ i 1)))
>           ((= i n))
>           (vector-set! v i x)))))
> 
> Python
> def vector_fill(v, x):
>     for i in range(len(v)):
>         v[i] = x
> 
> To me the Python code is easier to read, and I can't possibly fathom
> how somebody could think the Scheme code is easier to read.  It truly
> boggles my mind.

In Common Lisp you can write:

(defun vector-fill (v x)
  (loop for i from 0 below (length v) do
        (setf (aref v i) x)))

or

(defun vector-fill (v x)
  (dotimes (i (length v))
    (setf (aref v i) x)))

But if you focus on examples like this you really miss the point.  Imagine
that you wanted to be able to write this in Python:

def vector_fill(v, x):
  for i from 0 to len(v)-1:
    v[i] = x

You can't do it because Python doesn't support "for i from ... to ...",
only "for i in ...".  What's more, you can't as a user change the language
so that it does support "for i from ... to ...".  (That's why the xrange
hack was invented.)

In Lisp you can.  If Lisp didn't already have LOOP or DOTIMES as part of
the standard you could add them yourself, and the way you do it is by
writing a macro.

That's what macros are mainly good for, adding features to the langauge in
ways that are absolutely impossible in any other language.  S-expression
syntax is the feature that enables users to so this quickly and easily.

> I can't see
> why a LISP programmer would even want to write a macro.

That's because you are approaching this with a fundamentally flawed
assumption.  Macros are mainly not used to make the syntax prettier
(though they can be used for that).  They are mainly used to add features
to the language that cannot be added as functions.

For example, imagine you want to be able to traverse a binary tree and do
an operation on all of its leaves.  In Lisp you can write a macro that
lets you write:

(doleaves (leaf tree) ...)

You can't do that in Python (or any other langauge).

Here's another example of what you can do with macros in Lisp:

(with-collector collect
  (do-file-lines (l some-file-name)
    (if (some-property l) (collect l))))

This returns a list of all the lines in a file that have some property. 
DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
any other way because they take variable names and code as arguments.

E.


----

P.S.  Here is the code for WITH-COLLECTOR and DO-FILE-LINES:

(defmacro with-collector (var &body body)
  (let ( (resultvar (gensym "RESULT")) )
    `(let ( (,resultvar '()) )
       (flet ( (,var (item) (push item ,resultvar)) )
         ,@body)
       (nreverse ,resultvar))))

(defmacro do-file-lines ((linevar filename &optional streamvar) &body body)
  (let ( (streamvar (or streamvar (gensym "S"))) )
    `(with-open-file (,streamvar ,filename)
       (do ( (,linevar (read-line ,streamvar nil nil)
                       (read-line ,streamvar nil nil)) )
           ( (null ,linevar) )
         ,@body))))

Here's DOLEAVES:

(defmacro doleaves ((var tree) &body body)
  `(walkleaves (lambda (,var) ,@body) ,tree))

:-)

(defun walkleaves (fn tree)
  (iterate loop1 ( (tree tree) )
    (if (atom tree)
      (funcall fn tree)
      (progn (loop1 (car tree)) (and (cdr tree) (loop1 (cdr tree)))))))

; This is the really cool way to iterate
(defmacro iterate (name args &rest body)
  `(labels ((,name ,(mapcar #'car args) ,@body))
     (,name ,@(mapcar #'cadr args))))

E.
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <uEwfb.222927$R32.7155971@news2.tin.it>
Erann Gat wrote:
   ...
> But if you focus on examples like this you really miss the point.  Imagine
> that you wanted to be able to write this in Python:
> 
> def vector_fill(v, x):
>   for i from 0 to len(v)-1:
>     v[i] = x
> 
> You can't do it because Python doesn't support "for i from ... to ...",
> only "for i in ...".  What's more, you can't as a user change the language
> so that it does support "for i from ... to ...".  (That's why the xrange
> hack was invented.)

Almost right, except that xrange is a hack.  Since in Python you cannot
change the language to suit your whims, you USE the language (designed
by a pretty good language designer) -- by coding an iterator that is
suitable to put where the ... are in "for i in ...".

> In Lisp you can.  If Lisp didn't already have LOOP or DOTIMES as part of
> the standard you could add them yourself, and the way you do it is by
> writing a macro.

Good summary: if you fancy yourself as a language designer, go for Lisp;
if you prefer to use a language designed by somebody else, without you
_or any of the dozens of people working with you on the same project_
being able to CHANGE the language, go for Python.

> That's what macros are mainly good for, adding features to the langauge in
> ways that are absolutely impossible in any other language.  S-expression
> syntax is the feature that enables users to so this quickly and easily.

Doesn't Dylan do a pretty good job of giving essentially the same
semantics (including macros) without S-expression syntax?  That was
my impression, but I've never used Dylan in production.

> For example, imagine you want to be able to traverse a binary tree and do
> an operation on all of its leaves.  In Lisp you can write a macro that
> lets you write:
> 
> (doleaves (leaf tree) ...)
> 
> You can't do that in Python (or any other langauge).

Well, in Ruby, or Smalltalk, you would pass your preferred code block
to the call to the doleaves iterator, giving something like:

    doleaves(tree) do |leaf|
        ...
    end

while in Python, where iterators are "the other way around" (they
get relevant items out rather than taking a code block in), it would be:

    for leaf in doleaves(tree):
        ...

In either case, it may not be "that" (you are not ALTERING the syntax
of the language, just USING it for the same purpose), but it's sure close.
(In Dylan, I do believe you could ``do that'' -- except the surface
syntax would not be Lisp-ish, of course).


> Here's another example of what you can do with macros in Lisp:
> 
> (with-collector collect
>   (do-file-lines (l some-file-name)
>     (if (some-property l) (collect l))))
> 
> This returns a list of all the lines in a file that have some property.
> DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
> any other way because they take variable names and code as arguments.

If you consider than giving e.g. the variable name as an argument to
do-file-lines is the crucial issue here, then it's probably quite true
that this fundamental (?) feature "cannot be implemented any other way";
in Ruby, e.g., the variable name would not be an argument to dofilelines,
it would be a parameter at the start of the block receiving & using it:

   dofilelines(somefilename) do |l|
      collect l if someproperty? l
   end

However, it appears to me that the focus on where variable names are
to be determined may be somewhat misplaced.  The key distinction does
seem to be: if you're happy using a language as it was designed (e.g.,
in this example, respecting the language designer's concept that the
names for the control variables of a block must appear within | vertical
bars | at the start of the block -- or, in Python, the reversed concept 
that they must appear between the 'for' and 'in' in the "for ... in ...:
statement), macros are not relevant; if you do want to design and use
your own language (including, for example, placing variable names in 
new and interesting places) then macros can let you do that, while
other constructs would be insufficiently powerful.

If you dream of there being "preferably only one obvious way to do it",
as Pythonistas do (try "import this" at an interactive Python prompt),
macros are therefore a minus; if you revel in the possibilities of there
being many ways to do it, even ones the language designer had never even
considered (or considered and rejected in disgust:-), macros then become
a huge plus.

Therefore, I entirely agree that people who pine for macros should
use them in a language that accomodates them quite well, is designed
for them, cherishes and nurtures and exhalts them, like some language
of the Lisp family (be it Common, ISO, Scheme, ...), or perhaps Dylan
(which often _feels_ as if "of the Lisp family" even though it does
not use S-expressions), rather than trying to shoehorn them willy-nilly
into a language to whose overall philosophy they are SO utterly foreign,
like Python (Ruby, and even more Perl, may be a different matter;
google for "Lingua Latina Perligata" to see what Perl is already able
to do in terms of within-the-language language design and syntax
alteration, even without anything officially deemed to be 'macros'...
it IS, after all, a language CENTERED on "more than one way to do it").


Alex
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0410030909370001@192.168.1.51>
In article <························@news2.tin.it>, ·····@aleax.it wrote:

> Erann Gat wrote:
>    ...
> > (That's why the xrange hack was invented.)
> 
> Almost right, except that xrange is a hack.

I presume you meant to say that xrange is *not* a hack.  Well, hackiness
is to some extent a matter of taste.  The only reason xrange exists is
because range uses more memory than it needs to in the context where it is
most often used.  IMO, any construct that exists solely to work around an
inefficiency which should never have been there in the first place (as
evidenced by the fact that Python is unique among programming langauges in
having this particular inefficiency) is a hack.

> Since in Python you cannot change the language to suit your whims

That seems to be the crux of the difference between Python and Lisp.  For
some reason that I don't quite fathom, Pythonistas seem to think that this
limitation in their language is actually a feature.  It boggles my mind.

> Good summary: if you fancy yourself as a language designer, go for Lisp;

By using Lisp you *become* a language designer in the normal course of
learning to program in it.  After a while you even become a good language
designer.

> if you prefer to use a language designed by somebody else, without you
> _or any of the dozens of people working with you on the same project_
> being able to CHANGE the language, go for Python.

If you prefer to remain forever shackled by the limitations imposed by
someone else, someone who may not have known what they were doing, or
someone who made tacit assumptions that are not a good fit to your
particular problem domain, then by all means go for Python.  (Oh, you also
have to be willing to give up all hope of ever having efficient
native-code compilation.)

> > That's what macros are mainly good for, adding features to the langauge in
> > ways that are absolutely impossible in any other language.  S-expression
> > syntax is the feature that enables users to so this quickly and easily.
> 
> Doesn't Dylan do a pretty good job of giving essentially the same
> semantics (including macros) without S-expression syntax?

Similar, but not quite the same.  But there are other reasons to use
S-expressions besides macros.  For example, supposed you are writing code
for a mission-critical application and you want to write a static analyzer
to check that the code has a particular property.  That's vastly easier to
do if your code is in S-expressions because you don't have to write a
parser.

> > For example, imagine you want to be able to traverse a binary tree and do
> > an operation on all of its leaves.  In Lisp you can write a macro that
> > lets you write:
> > 
> > (doleaves (leaf tree) ...)
> > 
> > You can't do that in Python (or any other langauge).
> 
> Well, in Ruby, or Smalltalk, you would pass your preferred code block
> to the call to the doleaves iterator, giving something like:
> 
>     doleaves(tree) do |leaf|
>         ...
>     end

True.  For any single example (especially simple ones) I can give you can
almost certainly find some language somewhere that can do that one thing
with a specialized construct in that language.  The point is, macros let
you do *all* these things with a single mechanism.


> while in Python, where iterators are "the other way around" (they
> get relevant items out rather than taking a code block in), it would be:
> 
>     for leaf in doleaves(tree):
>         ...

Forcing you to either waste a lot of memory or write some very awkward code.

Here's another example: suppose you're writing embedded code and you need
to write a critical section, that is, code that runs with no interrupts
enabled.  In Lisp you can use macros to add a macro that lets you write:

(critical-section [code])

Getting this macro right is non-trivial because you have to make sure that
it works properly if critical sections are nested, and if there are
non-local exits from the code.

Another example: suppose you want to write some code that insures that a
particular condition is maintained while a code block executes.  In Lisp
you can render that as:

(with-maintained-condition [condition] [code])

e.g.:

(with-maintained-condition (< minval (reactor-temp) maxval)
  (start-reactor)
  (operate-reactor)
  (shutdown-reactor))

What's more, WITH-MAINTAINED-CONDITION can actually look at the code in
the CONDITION part and analyze it to figure out how to take action to
avoid having the condition violated, rather than just treating the
condition as a predicate.

> However, it appears to me that the focus on where variable names are
> to be determined may be somewhat misplaced.

Yes, I'm only focusing on that because I wanted to come up with simple
examples.  The problem is that the real power of macros can't really be
conveyed with a simple example.  By definition, any simple macro can
easily be replaced with simple code.  WITH-MAINTAINED-CONDITION starts to
come closer to indicating what macros are capable of.

> If you dream of there being "preferably only one obvious way to do it",
> as Pythonistas do

So which is the one obvious way to do it, range or xrange?

> (try "import this" at an interactive Python prompt),

Nice.  I particularly like the following:

"Errors should never pass silently."

and

"In the face of ambiguity, refuse the temptation to guess."

I predict that if Python is ever used in mission-critical applications
that it is only a matter of time before a major disaster is caused by
someone cutting and pasting this:

def foo():
  if baz():
    f()
  g()

and getting this:

def foo():
  if baz():
    f()
    g()

> if you revel in the possibilities of there
> being many ways to do it, even ones the language designer had never even
> considered (or considered and rejected in disgust:-), macros then become
> a huge plus.

If you are content to forever be a second-class citizen in the programming
world, to blindly accept the judgements of the exalted language designers
as if they are gospel, even when the language designers obviously don't
know what they're doing as Guido clearly didn't in early version of Python
as evidenced by the fact that proper lexical scoping wasn't added until
version 2, even when the language designers come up with horrible messes
like C++, if you are willing to take on faith that the language designers
anticipated every need you might ever have in any programming domain you
might ever choose to explore, then indeed macros are of no use to you.

If on the other hand you dream of obtaining a deep understanding of what
programming is and how languages work, if you dream of some day writing
your own compilers rather than waiting for someone else to write them for
you, if you want to write code that trancends the ordinary and explores
ideas and modes of thought that no one has explored before, and you want
to do all this without having to overcome arbitrary obstacles placed in
your way by people who think they know more than you do but really don't,
then macros - and Lisp macros in particular - are a huge win.

E.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <4qyohlxm.fsf@comcast.net>
··························@jpl.nasa.gov (Erann Gat) writes:

> I predict that if Python is ever used in mission-critical applications
> that it is only a matter of time before a major disaster is caused by
> someone cutting and pasting this:
>
> def foo():
>   if baz():
>     f()
>   g()
>
> and getting this:
>
> def foo():
>   if baz():
>     f()
>     g()

At least the infamous `missing period' bug involved something with a
printed representation.
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Snhgb.235745$R32.7621170@news2.tin.it>
Erann Gat wrote:

> In article <························@news2.tin.it>, ·····@aleax.it wrote:
> 
>> Erann Gat wrote:
>>    ...
>> > (That's why the xrange hack was invented.)
>> 
>> Almost right, except that xrange is a hack.
> 
> I presume you meant to say that xrange is *not* a hack.  Well, hackiness

Please don't put words in my mouth, thanks.  xrange _IS_ a hack, because
it was introduced in Python back in the dark ages before Python had the
iterator protocol.  If Python could be redesigned from scratch, without
needing to ensure backwards compatibility, the 'range' builtin (which 
might perhaps be better named 'irange', arguably) would no doubt be a
generator returning suitable iterators depending on its parameters.

[[ It is possible, though far from certain, that the next major release
of Python (3.0, presumably coming in a few years), which by definition of
"major" IS entitled to introduce some backwards incompatibilities, will
solve this legacy problem.  3.0's main theme will be to simplify Python
by removing redundancies, "more than one way to do it"'s, accreted over
the years; in my personal and humble opinion, range and xrange are just
such mtowdtis -- e.g. when one does need a list containing an arithmetic
progression, list(irange( ... -- the normal way to build a list from
any finite iterator, applied to a bounded arithmetic-progression
iterator -- is "the obvious way to do it", again IMPAHO. ]]

> is to some extent a matter of taste.  The only reason xrange exists is
> because range uses more memory than it needs to in the context where it is
> most often used.  IMO, any construct that exists solely to work around an
> inefficiency which should never have been there in the first place (as
> evidenced by the fact that Python is unique among programming langauges in
> having this particular inefficiency) is a hack.

We agree in broad terms on the definition of "hack" -- although any
discourse using "should" is obviously going to be debatable, e.g., I
consider cuts in Prolog, and strictness annotations in Haskell, as
generally being hacks, but (never having implemented compilers for
either) I can't discuss whether the inefficiencies they work around
"should" be there, or not.  Generally, whenever release N+1 of a
language adds a construct or concept that is really useful, one
could argue that the new addition "should" have been there before
(except, perhaps, in those exceedingly rare cases where the new
feechur deals with things that just didn't exist in the past).


>> Since in Python you cannot change the language to suit your whims
> 
> That seems to be the crux of the difference between Python and Lisp.  For

I agree with you on this point, too.

> some reason that I don't quite fathom, Pythonistas seem to think that this
> limitation in their language is actually a feature.  It boggles my mind.

Imagine a group of, say, a dozen programmers, working together by
typical Agile methods to develop a typical application program of
a few tens of thousands of function points -- developing about
100,000 new lines of delivered code plus about as much unit tests,
and reusing roughly the same amount of code from various libraries,
frameworks, packages and modules obtained from the net and/or from
commercial suppliers.  Nothing mind-boggling about this scenario,
surely -- it seems to describe a rather run-of-the-mill case.

Now, clearly, _uniformity_ in the code will be to the advantage
of the team and of the project it develops.  Extreme Programming
makes a Principle out of this (no "code ownership"), but even if
you don't rate it quite that highly, it's still clearly a good
thing.  Now, you can impose _some_ coding uniformity (within laxer
bounds set by the language) _for code originally developed by the
team itself_ by adopting and adhering to team-specific coding
guidelines; but when you're reusing code obtained from outside,
and need to adopt and maintain that code, the situation is harder.
Either having that code remain "alien", by allowing it to break
all of your coding guidelines; or "adopting" it thoroughly by,
in practice, rewriting it to fit your guidelines; is a serious
negative impact on the team's productivity.

In any case, to obtain any given level of uniformity, even just
in the code newly produced by the team, you need more and more
coding guidelines as the language becomes laxer.  For example:
in Ruby, class names MUST start with an uppercase letter, no
ifs, no buts; languages where such a language-imposed rule does
not exist (such as Python) may choose to adopt it as a coding
convention -- but it's one more atom of effort in writing those
conventions and in enforcing them.  The language that makes this
a rule makes life marginally _simpler_ for you; the language
that gives you more freedom makes life _harder_ for you.  I hope
that by choosing an example where Python is the "freer", and thus
LESS simple, language, I can show that this line of reasoning is
not a language-induced bias; I appreciate such uniformity, and I
think it simplifies the life of teams engaged in application
development, quite apart from Python vs other-languages issues.
(Of course, I could have chosen many examples where Python is
the more uniform/restrictive language: e.g., after a "def x()",
Python _mandates_ a colon, where Ruby 1.8 makes it _optional_ in
the same syntactic position -- here, Ruby is "freer", and thus
Python makes your life simpler).

The issue is by no means limited to lexical-level minutiae (though
in practice many people, and thus many teams, are quite prone to
waste inordinate amount of debate on exactly such minutiae -- one
of the "laws" first humorously identified by Cyril Northcote Parkinson
in his hilarious columns for "The Economist" later collected in book
form).  A language which allows dozens of forms of loops gives you
much more freedom of expression -- and thereby gives you headaches
when you try to write coding guidelines making the team's code more
uniform (and worse ones if you need to adopt and maintain reused
code of alien origin).  One that lets (e.g.) the definition of a
single module, or class, be spread over many separate code parts
over many files, again, gives you much more freedom -- and more
headaches -- than one which mandates classes and modules be
defined in textually-contiguous blocks of code.  Any increase in
freedom of expression is thus not an unalloyed good: it carries
costs as well as benefits.  Therefore, just like any other aspect
of an engineering design, it is subject to trade-offs.

It should be clear by now that the "quantum jump" (using this phrase
in the quaint popular sense of "huge leap", rather than in the correct
one of "tiny variation":-) in expressiveness that is afforded by a
powerful macro system, one letting you enrich and enhance, and thus
CHANGE, the very language you're using, can be viewed as TOO MUCH
(for the context of application development by middle-sized teams
reusing substantial amounts of alien code) without needing to boggle
anybody's mind.  You may perfectly well disagree with this and
counter-claim that having macros available will make everybody into
wonderful language designers: I will still prefer to stick to what
my experience has taught me, even within the context of my generally
optimistic stance on human nature, which is that it just ain't so.

It's optimistic enough to believe that average practitioners WILL be
able to design good interfaces (functions, procedures, classes and
hierarchies thereof, ...) suitable for the task at hand and with some
future potential for reuse in similar but not identical contexts; I
believe that there are plenty of problems even within these limited
confines, and giving more powerful tools to the same practitioners,
more degrees of freedom yet, is IMHO anything but conducive to optimal
performance in the areas I'm most interested in (chiefly application
development by mid-sized teams with very substantial reuse).

I hope this presents my opinions (shared by many, though far from all,
in the Python community) clearly enough that we can "agree to
disagree" without offending each other with such quips as "boggling
the mind".


>> Good summary: if you fancy yourself as a language designer, go for Lisp;
> 
> By using Lisp you *become* a language designer in the normal course of
> learning to program in it.  After a while you even become a good language
> designer.

Here is the crux of our disagreement.  If you believe everybody can
become a good language designer, I think the onus is on you to explain
why most languages are not designed well.  Do remember that a vast
majority of the people who do design languages HAVE had some -- in
certain cases, VAST -- experience with Lisp, e.g., check out the
roster of designers for the Java language.  My thesis is that the
ability to design languages well is far rarer than the ability to
design well within more restricted confines, and good design is taught
and learned much more easily in restricted realms, much less easily
the broader the degrees of freedom.


>> if you prefer to use a language designed by somebody else, without you
>> _or any of the dozens of people working with you on the same project_
>> being able to CHANGE the language, go for Python.
> 
> If you prefer to remain forever shackled by the limitations imposed by
> someone else, someone who may not have known what they were doing, or
> someone who made tacit assumptions that are not a good fit to your
> particular problem domain, then by all means go for Python.  (Oh, you also

If I thought Python's design was badly done, and a bad fit for my
problem domain, then, obviously, I would not have chosen Python (I
hardly lack vast experience in many other programming languages,
after all).  Isn't this totally obvious?

> have to be willing to give up all hope of ever having efficient
> native-code compilation.)

This assertion is false.  The psyco specializing-compiler already
shows what can be done in these terms within the restrictions of the
existing classic-python implementation.  The pypy project (among
whose participants Armin Rigo, the author of psyco, is counted) aims
(among other things) to apply the same techniques, without those very
confining restrictions, to provide "efficient native-code compilation"
to vastly greater extents.  Therefore, clearly, your assertion that
(to adopt Python) one has "to give up all hope" of such goals is not
at all well-founded.  There is nothing intrinsic to Python that can
justify it.  You may want to rephrase it in terms of having production
quality compilers to native code available _today_ -- but surely not in
terms of hopes, or in fact realistic possibilities, for the future.


>> > That's what macros are mainly good for, adding features to the langauge
>> > in
>> > ways that are absolutely impossible in any other language. 
>> > S-expression syntax is the feature that enables users to so this
>> > quickly and easily.
>> 
>> Doesn't Dylan do a pretty good job of giving essentially the same
>> semantics (including macros) without S-expression syntax?
> 
> Similar, but not quite the same.  But there are other reasons to use
> S-expressions besides macros.  For example, supposed you are writing code
> for a mission-critical application and you want to write a static analyzer
> to check that the code has a particular property.  That's vastly easier to
> do if your code is in S-expressions because you don't have to write a
> parser.

If your toolset includes a parser, you don't have to write one -- it's
there, ready for reuse.  The difficulty of writing a parser may give some
theoretical pause in a "greenfield development" idealized situation, but
given that parsers ARE in fact easily available it's not a compelling
argument in practice.  Still, we're not debating S-expressions, but,
rather, macros: from that POV, it seems to me that Dylan is quite a bit
more similar to Lisp than to Python -- even though, in terms of many
aspects of surface syntax, the reverse many appear true.  (Just to show
that I'm _NOT_ acritically accepting of anything Python and critical of
anything nonPython: I _do_ envy Dylan, and Lisp, the built-in generic
function / multimethod approach -- I think it's superior to the single
dispatch of Smalltalk / Ruby / Python / C++ / Java, with more advantages
than disadvantages, and am overjoyed that in pypy we have based the
whole architecture on a reimplementation of such multiple dispatch).


>> > For example, imagine you want to be able to traverse a binary tree and
>> > do
>> > an operation on all of its leaves.  In Lisp you can write a macro that
>> > lets you write:
>> > 
>> > (doleaves (leaf tree) ...)
>> > 
>> > You can't do that in Python (or any other langauge).
>> 
>> Well, in Ruby, or Smalltalk, you would pass your preferred code block
>> to the call to the doleaves iterator, giving something like:
>> 
>>     doleaves(tree) do |leaf|
>>         ...
>>     end
> 
> True.  For any single example (especially simple ones) I can give you can
> almost certainly find some language somewhere that can do that one thing
> with a specialized construct in that language.  The point is, macros let
> you do *all* these things with a single mechanism.

And nuclear warheads let you dispatch any enemy with a single kind of
weapon.  Despite which, some of us are QUITE happy that other weapon
systems still exist, and that our countries have abjured nukes...;-).

 
>> while in Python, where iterators are "the other way around" (they
>> get relevant items out rather than taking a code block in), it would be:
>> 
>>     for leaf in doleaves(tree):
>>         ...
> 
> Forcing you to either waste a lot of memory or write some very awkward
> code.

I _BEG_ your pardon...?  Assuming for definiteness that a tree is a
sequence of leaves and subtrees, and some predicate leafp tells me
whether something IS a leaf:

def doleaves(tree):
    for item in tree:
        if leafp(item):
                yield item
        else:
            for leaf in doleaves(item):
                yield leaf

where do I "waste a lot of memory"?  What is "very awkward" in
the above code?  I really don't understand.


> Here's another example: suppose you're writing embedded code and you need
> to write a critical section, that is, code that runs with no interrupts
> enabled.  In Lisp you can use macros to add a macro that lets you write:
> 
> (critical-section [code])
> 
> Getting this macro right is non-trivial because you have to make sure that
> it works properly if critical sections are nested, and if there are
> non-local exits from the code.

In Ruby and Smalltalk, you can clearly pass the code block to the critical-
section method just as you would pass it to any other iterator (i.e.,
same non-syntax-altering mechanism does cover this kind of needs just
as well as it covers looping).  In Python, the cultural preference is
for explicitness, thus try/finally (which IS designed specifically to
ensure handling of "nonlocal exits", and has no problem being nested)
enjoys strong preference over the "use of the same construct for widely
different purposes" which WOULD be currently allowed by iterators:

>>> class criticalsection(object):
...   def __init__(self): print 'Entering'
...   def __del__(self): print 'Exiting'
...   def __iter__(self): return self
...   def next(self): return None
...
>>> for x in criticalsection():
...   print "about to nonlocal-exit"
...   raise RuntimeError, "non-local exit right here"
...
Entering
about to nonlocal-exit
Exiting
Traceback (most recent call last):
  File "<stdin>", line 3, in ?
RuntimeError: non-local exit right here
>>>

Such reliance on the __del__ ("destructor") is not a well-received
idiom in Python, and the overall cultural preference is strongly for
NOT stretching a construct to perform widely different tasks (looping
vs before/after methods), even though technically it would be just
as feasible with Python's iterators as with Smalltalk's and Ruby's.

So, it IS quite possible that Python will grow a more specific way
to ensure the same semantics as try/finally in a more abstract way --
not because Python's iterators aren't technically capable of it, but
because using them that way would hit against such cultural issues
as the dislike for stretching a single tool to do different things.
(Clearly, macros would not help fight such a cultural attitude:-).


> Another example: suppose you want to write some code that insures that a
> particular condition is maintained while a code block executes.  In Lisp
> you can render that as:
> 
> (with-maintained-condition [condition] [code])
> 
> e.g.:
> 
> (with-maintained-condition (< minval (reactor-temp) maxval)
>   (start-reactor)
>   (operate-reactor)
>   (shutdown-reactor))
> 
> What's more, WITH-MAINTAINED-CONDITION can actually look at the code in
> the CONDITION part and analyze it to figure out how to take action to
> avoid having the condition violated, rather than just treating the
> condition as a predicate.

I have no idea of how with-maintained-condition would find and
examine each of the steps in the body in this example; isn't
the general issue quite equivalent to the halting problem, and
thus presumably insoluble?  If with-maintained-condition is, as
it would appear here, written by somebody who's not a chemical
engineer and has no notion about control of temperatures in
chemical reactors (or, other specialized engineers for completely
different types of reactors), HOW does it figure out (e.g.) the
physical model of the outside world that is presumably being
controlled here?  It seems to me that, compared to these huge
semantical issues, the minor ones connected to allowing such
"nifty syntax" pale into utter insignificance.


>> However, it appears to me that the focus on where variable names are
>> to be determined may be somewhat misplaced.
> 
> Yes, I'm only focusing on that because I wanted to come up with simple
> examples.  The problem is that the real power of macros can't really be
> conveyed with a simple example.  By definition, any simple macro can
> easily be replaced with simple code.  WITH-MAINTAINED-CONDITION starts to
> come closer to indicating what macros are capable of.

If your claim is that macros are only worthwhile for "artificial
intelligence" code that is able, by perusing other code, to infer
(and perhaps critique?) the physical world model it is trying to
control, and modify the other code accordingly, I will not dispute
that claim.  Should I ever go back to the field of Artificial
Intelligence (seems unlikely, as it's rather out of fashion right
now, but, who knows) I will probably ask you for more guidance
(the Prolog that I was using 15/20 years ago for the purpose was
clearly nowhere near up to it... it lacked macros...!-).  But as
long as my interests suggest _eschewing_ "self-modifying code" as
the plague, it seems to me I'm at least as well off w/o macros!-)


>> If you dream of there being "preferably only one obvious way to do it",
>> as Pythonistas do
> 
> So which is the one obvious way to do it, range or xrange?

An iterator.  Unfortunately, iterators did not exist when range and
xrange were invented, and thus the 'preferably' is violated.  By dint
of such issues of maintaining backwards compatibility, and not having
been born "perfect like Athena from Zeus's head" from day one, Python
is not perfect: it's just, among all imperfect languages, the one that,
in my judgment, best fits my current needs and interests.


>> (try "import this" at an interactive Python prompt),
> 
> Nice.  I particularly like the following:
> 
> "Errors should never pass silently."
> 
> and
> 
> "In the face of ambiguity, refuse the temptation to guess."
> 
> I predict that if Python is ever used in mission-critical applications

Hmmm, "if"?  Google for python "air traffic control", or python
success stories, depending on your definition of "mission-critical".
Either way, it IS being so used.

> that it is only a matter of time before a major disaster is caused by
> someone cutting and pasting this:
> 
> def foo():
>   if baz():
>     f()
>   g()
> 
> and getting this:
> 
> def foo():
>   if baz():
>     f()
>     g()

Ah, must be a mutation of the whitespace-eating nanovirus that was
identified and neutralized years ago -- a whitespace-*adding*
nanovirus, and moreover one which natural selection has carefully
honed to add just the right number of spaces (two, in this weird
indentation style).  I would estimate the chance of such a nanovirus
attacking as comparable to that of the attack of other mutant
strains, such as the dreaded balanced-parentheses-eaters which might 
prove particularly virulent in the rich culture-broth of an
S-expressions environment.  Fortunately, in either case, the rich
and stong suite of unit tests that surely accompanies such a
"mission-critical application" will easily detect the nefarious
deed and thus easily defang the nanoviruses' (nanovirii's? nanovirorum...?)
menace, even more easily than it detects and defangs the "type errors"
so utterly dreaded by all those who claim that only strictly statically
typed languages could ever possibly be any use in mission-critical
applications.


>> if you revel in the possibilities of there
>> being many ways to do it, even ones the language designer had never even
>> considered (or considered and rejected in disgust:-), macros then become
>> a huge plus.
> 
> If you are content to forever be a second-class citizen in the programming
> world, to blindly accept the judgements of the exalted language designers
> as if they are gospel, even when the language designers obviously don't
> know what they're doing as Guido clearly didn't in early version of Python
> as evidenced by the fact that proper lexical scoping wasn't added until
> version 2, even when the language designers come up with horrible messes
> like C++, if you are willing to take on faith that the language designers
> anticipated every need you might ever have in any programming domain you
> might ever choose to explore, then indeed macros are of no use to you.

Whoa there.  I detect in this tirade a crucial unspoken assumption: that
One Language is necessarily going to be all I ever learn, all I ever use,
for "any programming domain I might ever choose to explore".  This is,
most obviously, a patently silly crucial unspoken assumption, and this
obvious and patent silliness undermines the whole strength of the
argument, no matter how forcefully you choose to present it.

There being no open-source, generally useful operating system kernels in
any language but C, if one "programming domain I choose to explore" is to
modify, enrich and adapt the kernel of the operating system I'm using, with
the ambition of seeing my changes make it into the official release -- I
had better learn and use C pretty well, for example.  Does this mean, by
the (silly, unspoken) "one-language rule", that I am condemned to do _ALL_
of my programming in C...?  By no means!  I can, and do, learn and use more
than one programming language, depending on the context -- who must I be
cooperating with, in what "programming domain", on what sets of platforms,
and so on.  Since I know (and, at need, use) several different programming
languages, I have no need to BLINDLY accept anything whatsoever -- my
(metaphorical) eyes are quite open, and quite able to discern both the
overall picture, and the minutest details -- in point of fact far better
than my "actual" eyes are, since my actual, physical eyesight is far from
good.  With Python, I know by actual experience as well as supporting
reflection and analytical thought, I am quite able to cooperate fruitfully
in mid-sized teams of programmers of varying levels of ability working
rapidly and productively to implement application programs (and frameworks
therefor) of reasonable richness and complexity: the language's clarity,
simplicity, and uniformity (and the cultural biases reinforcing the same
underlying values) help quite powerfully in such collaboration.  If and
when specialized languages are opportune, they can be and are designed
separately (often subject to external constraints, e.g., XML for purposes
of cooperation with other -- separately designed and implemented -- "alien"
applications) and _implemented_ with Python.


> If on the other hand you dream of obtaining a deep understanding of what
> programming is and how languages work, if you dream of some day writing
> your own compilers rather than waiting for someone else to write them for

Beg pardon: I *HAVE* "written my own compilers", several times in the
course of my professional career.  I don't particularly "dream" of doing
it again, I just suspect it's quite possible that it may happen again,
e.g., next time somebody hires me to help write an application that
must suck in some alien-application-produced data (presumably in XML
with some given schema, these days) and produce something else as a
result.  I neither dread nor yearn for such occasions, any more than I
do wrt writing my own network protocols, GUI frameworks, device drivers,
schedulers, and so on -- all tasks I have had to perform, and which
(if I am somewhat unlucky, but within the reasonable span of possiiblities)
may well happen to fall on my shoulders again.  If I'm lucky, I will instead
find and be able to re-use *existing* device drivers, compilers, network
protocols, etc, etc -- I would feel luckier, then, because I could devote
more of my effort to building application programs that are going to be
directly useful to other human beings and thus enhance their lives.

I think I have a reasonably deep understanding of "what programming is" --
an activity performed by human beings, more often than not in actual or
virtual teams, and thus first and foremost an issue of collaboration
and cooperation.  "How languages work", from this POV, is first and
foremost by facilitating (or not...;-) the precise, unambiguous
communication that in turn underlies and supports the cooperation and
collaboration among these human beings.  Writing device drivers to
learn what hardware is and how interfaces to it work is one thing; in
most cases, if you find me writing a device driver it will be because,
after searching to the best of my ability, I have not located a device
driver I could simply and productively reuse (and couldn't "wait for
someone else to write" one for me).  And quite similarly, if you find
me writing a network protocol, a compiler, a GUI framework, etc, etc.
I'm not particularly _motivated_ in the abstract to such pursuits, and
to say I "dream" of spending my time building plumbing (i.e., building
infrastructure) would be laughable; I have often had to, and likely
will again in the future, e.g. because a wonderful new piece of HW I
really truly want to use doesn't come with a device driver for the
operating system I need to use it with, etc, etc.


> you, if you want to write code that trancends the ordinary and explores
> ideas and modes of thought that no one has explored before, and you want

Pure research?  Been there, done that (at IBM Research, in the 80's),
eventually moved to an application-development shop because I realized
that such "transcending and exploring" wasn't what I really wanted to
spend my whole life doing -- I wanted to make applications directly
useful to other human beings; I'm an engineer, not a pure scientist.
In any case, even in such pure research I didn't particularly miss
macros.  I was first hired by Texas Instruments in 1980 specifically
because of my knowledge of Lisp -- but was quite glad in 1981 to move
to IBM, and back to APL, which I had used at the start of my "tesi di
laurea" before being forced to recode it all in Fortran, Pascal and
assembly language on a then-newfangled machine called VAX-11 780.  For
the kind of purely numerical processing that constituted my "transcending
and exploring" back then, reusing the existing array-computation
infrastructure in APL was _so_ much better than having to roll my
own in Lisp -- let alone the half dozen different languages all called
"Lisp" (or in a couple of cases "Scheme") that different labs and factions
within labs inside TI had cobbled together with their own homebrew sets
of macros.  Factions and "NIH" are part of the way human beings are
made, of course, but at least, with APL, everybody WAS using the same
language -- the lack of macros constrained the amount of divergence --
so that collaborating with different groups, and sharing and reusing
code, was much more feasible that way.  (Of course, APL had its own
defects -- and how... -- but for the specific task of array computations
it was OK).  Of course, by that time it was already abundantly clear
to me that "horses for courses" was a much better idea in programming
than "one ring to bind them all".  Many people will never agree with
that (and thus almost all languages keep growing to try and be all
things to all people), but since my background (in theory) was mostly HW
(even though I kept having to do SW instead) the idea of having to use
one programming language for everything struck me as silly as having to
use one hardware tool for everything -- I'd rather have a toolbox with
a hammer for when I need to pound nails, AND a screwdriver for when I
need to drive screws, than a "superduper combined hammer+screwdriver+
scissors+pliers+soldering iron+..." which is apparently what most
programming languages aim to be...

> to do all this without having to overcome arbitrary obstacles placed in
> your way by people who think they know more than you do but really don't,

Been there, done that; I can easily say that most of the technologies
I've used in the course of about a quarter century do indeed respond quite
well to this description -- not just programming languages, mind you.  The
fundamental reason I've moved to using Python more than any other language,
these days, is that it doesn't.  It is not perfect -- but then, I have
never used any _perfect_ human-made artefact; it IS simple enough that I
can comfortably grasp it, explain it, understand its defects as well as
its strengths [and where both kinds of characteristics come from] and easily
see how to use it in reasonably good ways for tasks I care a lot about; it
promotes the cultural values that I see as most important for programming
collaboration in typical mid-sized teams -- simplicity, clarity, uniformity.

When it comes to programming language design, my experience learning, using
and teaching Python tells me one thing: Guido thinks he knows more than I
do about programming language design... and _he is right_, he does.  In an
egoless, objective mindset, I'm happier and more productive re-using the
fruits of his design, than I've ever been using languages of my own design
(and those designed by others yet).  I squabble with him as much as anybody,
mind you -- the flamewars you can find in the archives of python-dev and
the main Python list/newsgroup can only testify to a part of that, and
will never capture the expression on his face when he heard somebody else
at PythonUK presenting inter alia the Borg nonpattern I had designed (he
did not know that I, sitting next to him in the audience, was the designer,
so his disgusted diatribe was quite unconstrained -- it probably would have
been anyway, as he's quite an outspoken fellow:-), nor mine after my N-th
fruitless attempt to "sell" him on the "Protocol Adaptation metaprotocol",
the huge benefits of case-insensitivity, or some other of my
hobby-horses;-).  But, you know -- macros wouldn't help me on ANY of
these.  The PAm needs no syntax changes -- it's strictly a semantic issue
and I could easily implement it today (the problem is, due to what in
economics is called a "network effect", the PAm is worth little UNLESS
it's widely adopted, which means making it into the RELEASED language...).
As for changing a language from case-sensitive to case-insensitive, or
viceversa -- well, how WOULD you do it with macros -- without instantly
breaking a zillion lines of good, reusable existing code that depend on
the case-sensitivity rules defined in the official language definition?
And I care more about that wonderful panoply of reusable code, than I do
about making life easier for (e.g.) user of screen-reading software; so
I don't really think Python ever will or should become case-insensitive,
I only DREAM about it, to quote you (but my dream includes a time machine
to go back to 1990 and make it case-insensitive *from the start*, which
is about as likely as equipping it with iterators or PAm from then...:-).

> then macros - and Lisp macros in particular - are a huge win.

I think macros (Lisp ones in particular) are a huge win in situations
in which the ability to enrich / improve / change the language has more
advantages than disadvantages.  So, I think they would be a great fit
for languages which target just such situations, such as, definitely,
Perl, and perhaps also Ruby; and a net loss for languages which rely on
simplicity and uniformity, such as, definitely, Python.  If and when I
find myself tackling projects where macros "are a huge win", I may use a
Lisp of some sort, or Dylan, or maybe check out if Glasgow Haskell's
newest addition is usable within the limited confines of my brain -- I
just dearly and earnestly hope that Python remains true to its own
self -- simple, clear, uniform -- and NOT grow any macros itself...!!!


Alex
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <llry2m99.fsf@ccs.neu.edu>
Alex Martelli <·····@aleax.it> writes:

> Imagine a group of, say, a dozen programmers, working together by
> typical Agile methods to develop a typical application program of
> a few tens of thousands of function points -- developing about
> 100,000 new lines of delivered code plus about as much unit tests,
> and reusing roughly the same amount of code from various libraries,
> frameworks, packages and modules obtained from the net and/or from
> commercial suppliers.  Nothing mind-boggling about this scenario,
> surely -- it seems to describe a rather run-of-the-mill case.
>
> In any case, to obtain any given level of uniformity, even just
> in the code newly produced by the team, you need more and more
> coding guidelines as the language becomes laxer.  For example:
> in Ruby, class names MUST start with an uppercase letter, no
> ifs, no buts; languages where such a language-imposed rule does
> not exist (such as Python) may choose to adopt it as a coding
> convention -- but it's one more atom of effort in writing those
> conventions and in enforcing them.  The language that makes this
> a rule makes life marginally _simpler_ for you; the language
> that gives you more freedom makes life _harder_ for you.  

Freedom, horrible freedom!  It so much harder to think than it is to
let other people do it for you.

> Any increase in freedom of expression is thus not an unalloyed good:
> it carries costs as well as benefits.  Therefore, just like any
> other aspect of an engineering design, it is subject to trade-offs.

Unless, of course, when the decision has already been made for you.
Then there is no trade-off to consider, you simply take what is given
to you.

> Here is the crux of our disagreement.  If you believe everybody can
> become a good language designer, I think the onus is on you to explain
> why most languages are not designed well.  

On the contrary.  I believe that *very few* people can become good
language designers.  The best language designers realize that they
*don't* know the problems the user will attempt to solve.

> Do remember that a vast majority of the people who do design
> languages HAVE had some -- in certain cases, VAST -- experience with
> Lisp, e.g., check out the roster of designers for the Java language.

Snort.  Mocklisp doesn't count.

The vast majority of people who design languages have had minimal,
if any, exposure to Lisp. 

> My thesis is that the ability to design languages well is far rarer
> than the ability to design well within more restricted confines, and
> good design is taught and learned much more easily in restricted
> realms, much less easily the broader the degrees of freedom.

Here you are wrong.  In a restricted realm, it may be easier to design
good things, but it is not easier to become a good designer.  These
are two different things.  `Paint by Numbers' is a highly restricted
realm, and with a little practice you, too, can create a painting that
is easily recognizable as a landscape.  You will never create a true
work of art this way.

> If I thought Python's design was badly done, and a bad fit for my
> problem domain, then, obviously, I would not have chosen Python (I
> hardly lack vast experience in many other programming languages,
> after all).  Isn't this totally obvious?

So you're abandoning the `fine-grained' approach and going for the
`all-or-nothing' approach.  Lisp has *never* been good fit for any
problem domain I have worked on, yet I use it virtually exclusively.
I can trivially extend it into the problem domain quicker than any
other language, and completely finesse the issue of `fitting the
language to the problem domain'.  

If you find a problem the tool doesn't fit, you have to discard the
tool altogether.  I simply adjust the tool.

> And nuclear warheads let you dispatch any enemy with a single kind of
> weapon.  Despite which, some of us are QUITE happy that other weapon
> systems still exist, and that our countries have abjured nukes...;-).

... and this means something about macros?

>> Another example: suppose you want to write some code that insures that a
>> particular condition is maintained while a code block executes.  In Lisp
>> you can render that as:
>> 
>> (with-maintained-condition [condition] [code])
>> 
>> e.g.:
>> 
>> (with-maintained-condition (< minval (reactor-temp) maxval)
>>   (start-reactor)
>>   (operate-reactor)
>>   (shutdown-reactor))
>> 
>> What's more, WITH-MAINTAINED-CONDITION can actually look at the code in
>> the CONDITION part and analyze it to figure out how to take action to
>> avoid having the condition violated, rather than just treating the
>> condition as a predicate.
>
> I have no idea of how with-maintained-condition would find and
> examine each of the steps in the body in this example; isn't
> the general issue quite equivalent to the halting problem, and
> thus presumably insoluble?  

I have no idea either, and if the condition is sufficiently general
and the body sufficiently complex, yes it would be insoluble.  What of
it?  We simply restrict ourselves to the cases where we *can* analyze
and decide.  Presumably a macro such as the above would generate a
compile time error 
``cannot maintain condition (< minval (reactor-temp) maxval)''

> If with-maintained-condition is, as
> it would appear here, written by somebody who's not a chemical
> engineer and has no notion about control of temperatures in
> chemical reactors (or, other specialized engineers for completely
> different types of reactors), HOW does it figure out (e.g.) the
> physical model of the outside world that is presumably being
> controlled here?  It seems to me that, compared to these huge
> semantical issues, the minor ones connected to allowing such
> "nifty syntax" pale into utter insignificance.

You're missing the point.  Suppose Erann and I were working on some
project and he had written the above macro.  I don't have to know
the details of implementation (I'm assuming that I can trust Erann
not to write bogus code).  Using the macro is *far* preferable to
something like:
   
     (start-reactor)
     (when (< minval (reactor-temp) maxval)
        (scram))
     (while (true)
        (operate-reactor-step))
        (when (< minval (reactor-temp) maxval)
           (scram))
     (shutdown-reactor)

Especially because there is a non-obvious bug in the above code.

> If your claim is that macros are only worthwhile for "artificial
> intelligence" code that is able, by perusing other code, to infer
> (and perhaps critique?) the physical world model it is trying to
> control, and modify the other code accordingly, I will not dispute
> that claim.  

I doubt Erann is asserting that.

> Should I ever go back to the field of Artificial
> Intelligence (seems unlikely, as it's rather out of fashion right
> now, but, who knows) I will probably ask you for more guidance
> (the Prolog that I was using 15/20 years ago for the purpose was
> clearly nowhere near up to it... it lacked macros...!-).  But as
> long as my interests suggest _eschewing_ "self-modifying code" as
> the plague, it seems to me I'm at least as well off w/o macros!-)

And higher-order functions, as well.  Better stick to Basic or
Fortran.

> Hmmm, "if"?  Google for python "air traffic control", or python
> success stories, depending on your definition of "mission-critical".
> Either way, it IS being so used.
>
>> that it is only a matter of time before a major disaster is caused by
>> someone cutting and pasting this:
>> 
>> def foo():
>>   if baz():
>>     f()
>>   g()
>> 
>> and getting this:
>> 
>> def foo():
>>   if baz():
>>     f()
>>     g()
>
> Ah, must be a mutation of the whitespace-eating nanovirus that was
> identified and neutralized years ago -- a whitespace-*adding*
> nanovirus, and moreover one which natural selection has carefully
> honed to add just the right number of spaces (two, in this weird
> indentation style).  

You're right, of course.  Decades of makefile errors notwithstanding.

> When it comes to programming language design, my experience
> learning, using and teaching Python tells me one thing:  Guido thinks
> he knows more than I do about programming language design... and _he
> is right_, he does.  In an egoless, objective mindset, I'm happier
> and more productive re-using the fruits of his design, than I've
> ever been using languages of my own design (and those designed by
> others yet).

Stop now.  You are scaring me.
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3llryunix.fsf@javamonkey.com>
Joe Marshall <···@ccs.neu.edu> writes:

> You're missing the point.  Suppose Erann and I were working on some
> project and he had written the above macro.  I don't have to know
> the details of implementation (I'm assuming that I can trust Erann
> not to write bogus code).  Using the macro is *far* preferable to
> something like:
>    
>      (start-reactor)
>      (when (< minval (reactor-temp) maxval)
>         (scram))
>      (while (true)
>         (operate-reactor-step))
>         (when (< minval (reactor-temp) maxval)
>            (scram))
>      (shutdown-reactor)
> 
> Especially because there is a non-obvious bug in the above code.

Not obvious to you or me maybe. But Emacs Knows(tm). ;-)

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvisn2j9u9.fsf@firestorm.OCF.Berkeley.EDU>
Peter Seibel <·····@javamonkey.com> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
> 
> > You're missing the point.  Suppose Erann and I were working on some
> > project and he had written the above macro.  I don't have to know
> > the details of implementation (I'm assuming that I can trust Erann
> > not to write bogus code).  Using the macro is *far* preferable to
> > something like:
> >    
> >      (start-reactor)
> >      (when (< minval (reactor-temp) maxval)
> >         (scram))
> >      (while (true)
> >         (operate-reactor-step))
> >         (when (< minval (reactor-temp) maxval)
> >            (scram))
> >      (shutdown-reactor)
> > 
> > Especially because there is a non-obvious bug in the above code.
> 
> Not obvious to you or me maybe. But Emacs Knows(tm). ;-)

Or, with sufficiently developed paren-goggles, you can just see it.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8ynyf5m8.fsf@ccs.neu.edu>
Peter Seibel <·····@javamonkey.com> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
>
>> You're missing the point.  Suppose Erann and I were working on some
>> project and he had written the above macro.  I don't have to know
>> the details of implementation (I'm assuming that I can trust Erann
>> not to write bogus code).  Using the macro is *far* preferable to
>> something like:
>>    
>>      (start-reactor)
>>      (when (< minval (reactor-temp) maxval)
>>         (scram))
>>      (while (true)
>>         (operate-reactor-step))
>>         (when (< minval (reactor-temp) maxval)
>>            (scram))
>>      (shutdown-reactor)
>> 
>> Especially because there is a non-obvious bug in the above code.
>
> Not obvious to you or me maybe. But Emacs Knows(tm). ;-)

Heh heh heh.... yet another reason that indentation is a poor choice
for block delimiting.
From: Hannu Kankaanp??
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <840592e1.0310070257.1bdc5aa0@posting.google.com>
Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
> Peter Seibel <·····@javamonkey.com> writes:
> 
> > Joe Marshall <···@ccs.neu.edu> writes:
> >
> >> You're missing the point.  Suppose Erann and I were working on some
> >> project and he had written the above macro.  I don't have to know
> >> the details of implementation (I'm assuming that I can trust Erann
> >> not to write bogus code).  Using the macro is *far* preferable to
> >> something like:
> >>    
> >>      (start-reactor)
> >>      (when (< minval (reactor-temp) maxval)
> >>         (scram))
> >>      (while (true)
> >>         (operate-reactor-step))
> >>         (when (< minval (reactor-temp) maxval)
> >>            (scram))
> >>      (shutdown-reactor)
> >> 
> >> Especially because there is a non-obvious bug in the above code.
> >
> > Not obvious to you or me maybe. But Emacs Knows(tm). ;-)
> 
> Heh heh heh.... yet another reason that indentation is a poor choice
> for block delimiting.

Hmm. In a previous reply you answered sarcastically that indentation
is a poor choice, so I doubt this is again sarcasm saying the contrary.

So getting to the point, doesn't the example show that indentation
is in fact a *good* choice for block delimiting? It's an alternative that
wouldn't have the subtle bug you introduced here. So how can you
claim that this example shows indentation is a poor choice for block
delimiting? It doesn't make sense.

The problem with the example arises from the fact that indentation
is used for human readability, but parens are used by the parser.
A clash between these two representations can lead to subtle bugs
like this one. But remove one of the representations, and there
can't be clashes. Of course removing indentation would lead
super-ugly code, so why not just remove parens like has been
done in Python? I haven't heard of people swearing about bugs
introduced by this syntax choice, nor have I personally ever
made a mistake with indentation.
From: Ingvar Mattsson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87wubhmhgb.fsf@gruk.tech.ensign.ftech.net>
········@yahoo.com.au (Hannu Kankaanp??) writes:

> Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
> > Peter Seibel <·····@javamonkey.com> writes:
> > 
> > > Joe Marshall <···@ccs.neu.edu> writes:
> > >
> > >> You're missing the point.  Suppose Erann and I were working on some
> > >> project and he had written the above macro.  I don't have to know
> > >> the details of implementation (I'm assuming that I can trust Erann
> > >> not to write bogus code).  Using the macro is *far* preferable to
> > >> something like:
> > >>    
> > >>      (start-reactor)
> > >>      (when (< minval (reactor-temp) maxval)
> > >>         (scram))
> > >>      (while (true)
> > >>         (operate-reactor-step))
> > >>         (when (< minval (reactor-temp) maxval)
> > >>            (scram))
> > >>      (shutdown-reactor)
> > >> 
> > >> Especially because there is a non-obvious bug in the above code.
> > >
> > > Not obvious to you or me maybe. But Emacs Knows(tm). ;-)
> > 
> > Heh heh heh.... yet another reason that indentation is a poor choice
> > for block delimiting.
> 
> Hmm. In a previous reply you answered sarcastically that indentation
> is a poor choice, so I doubt this is again sarcasm saying the contrary.

Look closely at the condition for performing a scram, it is only done
when (and only when) the dynamically grabbed reactor temperature is
above the minimum value and below the maximum value.

> So getting to the point, doesn't the example show that indentation
> is in fact a *good* choice for block delimiting? It's an alternative that
> wouldn't have the subtle bug you introduced here. So how can you
> claim that this example shows indentation is a poor choice for block
> delimiting? It doesn't make sense.

If indentation is *all* you have to guide you to judge what the code
will do, what will you do when teh indentation is smashed? And it will
be, it always is, at some point. It's damned annoying.

> The problem with the example arises from the fact that indentation
> is used for human readability, but parens are used by the parser.
> A clash between these two representations can lead to subtle bugs
> like this one. But remove one of the representations, and there
> can't be clashes. Of course removing indentation would lead
> super-ugly code, so why not just remove parens like has been
> done in Python? I haven't heard of people swearing about bugs
> introduced by this syntax choice, nor have I personally ever
> made a mistake with indentation.

I have had production systems down for about 10-15 minutes due to
Python (the language) being indentation sensitive (also for comments[1])
in combination with tabs and cut&paste between different
representations (diff in xterm, pasted into email).

Had there been block delimiters, that wouldn't have happened.

//Ingvar
[1] I naively (but I only use Python (the language) as a Better Perl)
    that all I need to do to comment out a section of code is to smack
    in comment-to-end-of-line as teh first character. Obviously, this
    breaks Python code quite badly. Not an excellent, but in
    retrospect understandable behaviour.
-- 
"I'm in 386 enchanted mode." 
From: A.M. Kuchling
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <PY2dnXK_PaGANR-iRTvU2Q@speakeasy.net>
On 07 Oct 2003 12:10:28 +0100, 
	Ingvar Mattsson <······@cathouse.bofh.se> wrote:
> [1] I naively (but I only use Python (the language) as a Better Perl)
>     that all I need to do to comment out a section of code is to smack
>     in comment-to-end-of-line as teh first character. Obviously, this
>     breaks Python code quite badly. 

That should work fine, e.g.

···@vail:~$ cat t.py

for i in [1,2,3]:
        # Strangely indented comment
    print i
#    print i*2
   # More freaky comments
# Comment no. 3
	       
···@vail:~$ python t.py
1
2
3
···@vail:~$

Comments aren't part of the parser's token stream and are simply discarded,
so their indentation level doesn't matter.

--amk
From: Ingvar Mattsson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87smm5mf5f.fsf@gruk.tech.ensign.ftech.net>
"A.M. Kuchling" <···@amk.ca> writes:

> On 07 Oct 2003 12:10:28 +0100, 
> 	Ingvar Mattsson <······@cathouse.bofh.se> wrote:
> > [1] I naively (but I only use Python (the language) as a Better Perl)
> >     that all I need to do to comment out a section of code is to smack
> >     in comment-to-end-of-line as teh first character. Obviously, this
> >     breaks Python code quite badly. 
> 
> That should work fine, e.g.
> 

Hm, strange, I strongly recall stuff breaking when I did that and
unbreaking when I fixed the indented comments. I'll have to try to
build a test case. Shame I didn't save the code where I thought it
happened. 

//Ingvar
-- 
"I'm in 386 enchanted mode." 
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8ynx6tb1.fsf@comcast.net>
········@yahoo.com.au (Hannu Kankaanp??) writes:

> Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
>> Peter Seibel <·····@javamonkey.com> writes:
>> 
>> > Joe Marshall <···@ccs.neu.edu> writes:
>> >
>> >> You're missing the point.  Suppose Erann and I were working on some
>> >> project and he had written the above macro.  I don't have to know
>> >> the details of implementation (I'm assuming that I can trust Erann
>> >> not to write bogus code).  Using the macro is *far* preferable to
>> >> something like:
>> >>    
>> >>      (start-reactor)
>> >>      (when (< minval (reactor-temp) maxval)
>> >>         (scram))
>> >>      (while (true)
>> >>         (operate-reactor-step))
>> >>         (when (< minval (reactor-temp) maxval)
>> >>            (scram))
>> >>      (shutdown-reactor)
>> >> 
>> >> Especially because there is a non-obvious bug in the above code.
>> >
>> > Not obvious to you or me maybe. But Emacs Knows(tm). ;-)
>> 
>> Heh heh heh.... yet another reason that indentation is a poor choice
>> for block delimiting.
>
> Hmm. In a previous reply you answered sarcastically that indentation
> is a poor choice, so I doubt this is again sarcasm saying the contrary.
>
> So getting to the point, doesn't the example show that indentation
> is in fact a *good* choice for block delimiting? It's an alternative that
> wouldn't have the subtle bug you introduced here. So how can you
> claim that this example shows indentation is a poor choice for block
> delimiting? It doesn't make sense.

The point was that even though I screwed up the indentation, it was
easily discovered and repaired with Emacs.  If the program were
whitespace-sensitive, then the screwed-up version would be
mechanically indistinguishable from the intended one.

But I had a thought last night.  I assume that Python has comments.
I can imagine a `structural' editor that hid block information in
comment fields in Python, but didn't display them to the user (and
obviously Python wouldn't care about comments).  This sort of editor
*would* be able to detect and repair the kind of mistakes I'm
talking about.  (And when Microsoft gets around to releasing its
Python derivative, I bet the `intellicode' system does just that.) 


> The problem with the example arises from the fact that indentation
> is used for human readability, but parens are used by the parser.
> A clash between these two representations can lead to subtle bugs
> like this one. But remove one of the representations, and there
> can't be clashes. Of course removing indentation would lead
> super-ugly code, so why not just remove parens like has been
> done in Python? I haven't heard of people swearing about bugs
> introduced by this syntax choice, nor have I personally ever
> made a mistake with indentation.

Makefile
From: Hannu Kankaanp??
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <840592e1.0310071159.2a4be62@posting.google.com>
·············@comcast.net wrote in message news:<············@comcast.net>...
> ········@yahoo.com.au (Hannu Kankaanp??) writes:
> > So getting to the point, doesn't the example show that indentation
> > is in fact a *good* choice for block delimiting? It's an alternative that
> > wouldn't have the subtle bug you introduced here. So how can you
> > claim that this example shows indentation is a poor choice for block
> > delimiting? It doesn't make sense.
> 
> The point was that even though I screwed up the indentation, it was
> easily discovered and repaired with Emacs.  If the program were
> whitespace-sensitive, then the screwed-up version would be
> mechanically indistinguishable from the intended one.

How do you "screw up indentation"? Actually, being more of a
Python fan, I though you had screwed up parens, since indentation
is absolute for me :). Anyway, do you just go to some line and start
pressing spacebar randomly, and not notice this? Maybe
you do need a safety net, then.

> But I had a thought last night.  I assume that Python has comments.

Haha. For someone who hasn't actually used Python, you sure have
strong opinions about it. Before Python, I had only used languages
that had explicit block delimiter characters, but boy was I
delighted with Python's choice. Maybe you should try it out too.

> I can imagine a `structural' editor that hid block information in
> comment fields in Python, but didn't display them to the user (and
> obviously Python wouldn't care about comments).  This sort of editor
> *would* be able to detect and repair the kind of mistakes I'm
> talking about.  (And when Microsoft gets around to releasing its
> Python derivative, I bet the `intellicode' system does just that.) 

But the whitespace already has all the structural information needed.
The whitespace doesn't just disappear suddenly, much like parens don't
magically disappear or mutate.

There can be problems in cutting and pasting code if one mixes tabs
and spaces, like Ingvar said, but generally the rule in Python is to
use 4 spaces for each indentation level. If you break this rule,
you know you had it coming when something fails ;).
From: Steven E. Harris
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <q677k3gg6ek.fsf@raytheon.com>
········@yahoo.com.au (Hannu Kankaanp??) writes:

> Anyway, do you just go to some line and start pressing spacebar
> randomly, and not notice this? Maybe you do need a safety net, then.

You mention it later, not intending to answer your own question, but
cut-and-paste provides this error-provoking scenario. If one cuts a
block out of one level of nesting and pastes it into a deeper nesting
elsewhere, the block must be (uniformly) reindented. In Lisp, with
parentheses present, the editor can fix the inserted parts up to make
them consistent with the new enclosing context. Is the same
transformation as simple with Python syntax?

-- 
Steven E. Harris        :: ········@raytheon.com
Raytheon                :: http://www.raytheon.com
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oewseq1r.fsf@ccs.neu.edu>
········@yahoo.com.au (Hannu Kankaanp??) writes:

> How do you "screw up indentation"? 

Cutting & pasting fragments of code, emailing a file, opening a file
on a different OS than the one it was built on, making changes to code.

> Actually, being more of a Python fan, I though you had screwed up
> parens, since indentation is absolute for me :).  Anyway, do you
> just go to some line and start pressing spacebar randomly, and not
> notice this?  Maybe you do need a safety net, then.

I certainly do.  I marvel at those people that never mistype anything
or have to change their code.

I can easily imagine deciding that some code I had already written
needs to be protected by a conditional.  In Lisp, perhaps, it would
look like this:

   (defun foo (x)
     (format t "~&Frobbing x, which is ~s" x)
     (frob x))

And perhaps I didn't notice that sometimes X was empty and shouldn't
be frobbed.  So I add a conditional: 

   (defun foo (x)
     (when (frobbable? x)
       (format t "~&Frobbing x, which is ~s" x)
       (frob x)))

And a C-M-q indents the code to the proper level.  If it looks `funny'
after I indent it, for instance, like this:

   (defun foo (x)
     (when (frobbable? x)
       (format t "~&Frobbing x, which is ~s" x))
     (frob x))

It's pretty obvious I made a typo.

Now with whitespace delimited blocks I have to manually re-indent the
code.  Sure, it is unlikely that I'd miss one in the middle, but it
is far more likely I'd miss a line at the end.

>> But I had a thought last night.  I assume that Python has comments.
>
> Haha. For someone who hasn't actually used Python, you sure have
> strong opinions about it. Before Python, I had only used languages
> that had explicit block delimiter characters, but boy was I
> delighted with Python's choice. Maybe you should try it out too.

I played with Python several years ago. (circa 1999 or so)
I have forgotten most of the details of the syntax, for instance,
what the comment character is (a sharp?) whether comments can go
anywhere, whether comments affect indentation, etc.

>> I can imagine a `structural' editor that hid block information in
>> comment fields in Python, but didn't display them to the user (and
>> obviously Python wouldn't care about comments).  This sort of editor
>> *would* be able to detect and repair the kind of mistakes I'm
>> talking about.  (And when Microsoft gets around to releasing its
>> Python derivative, I bet the `intellicode' system does just that.) 
>
> But the whitespace already has all the structural information needed.
> The whitespace doesn't just disappear suddenly, much like parens don't
> magically disappear or mutate.

I must be using the wrong sort of computer.  When I view HTML in my
browser, the whitespace is *nothing* like what I wrote.  When I send
email, I have had whitespace lopped off the ends of lines (and strange
greater than signs inserted before the word `from').

Not to mention my own typos.  I do not believe in magic whitespace 
fairies, but every time I modify a file, I have a probabilistic
chance of typos.  In *general* it is somewhat unlikely that a typo
leads to code parsable by the computer.  This is good because it
helps me find the typos faster.  Even if the typo leads to parsable
code, it is unlikely to be semantically correct.  Unbound variable
or missing function errors catch those.

By using the distance from the left edge as a block delimiter,
though, you've significantly reduced the hamming distance between
differing legitimate programs.

> There can be problems in cutting and pasting code if one mixes tabs
> and spaces, like Ingvar said, but generally the rule in Python is to
> use 4 spaces for each indentation level. If you break this rule,
> you know you had it coming when something fails ;).

I thought Pythonista's never screwed up the distance to the left edge.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <877k3g8ydo.fsf@thalassa.informatimago.com>
Joe Marshall <···@ccs.neu.edu> writes:

> ········@yahoo.com.au (Hannu Kankaanp??) writes:
> 
> > How do you "screw up indentation"? 
> 
> Cutting & pasting fragments of code, emailing a file, opening a file
> on a different OS than the one it was built on, making changes to code.

Let me add the following easy way to mess an indentation:

    - the biggest and more accessible key on any keyboard is the space
      bar.

    - the tabulation key is not amongst the smallest.

    - the  return   key  neither.   Quite  often   I  insert  newlines
      inadvertently.


emacs  users  are  a   little  spoiled  here,  because  emacs  indents
automatically and can be configured so that most of these actions does
not significantly alter the  indentation (and I assume the python-mode
to be  very helpful too).  But  in almost all  other editors, pressing
one  of these keys  will lead  to change  to the  meaning of  a python
program (or  COBOL or FORTRAN or  ASSEMBLER or AUTOCODER),  but not of
any modern language.


> I must be using the wrong sort of computer.  When I view HTML in my
> browser, the whitespace is *nothing* like what I wrote.  When I send
> email, I have had whitespace lopped off the ends of lines (and strange
> greater than signs inserted before the word `from').

See  the  white  space  treatment  given  by  MUA  badly  encoding  in
quoted-printable...


Not to  mention the tendency since  the Mac to  use proportional fonts
where the white space may be very small.


> By using the distance from the left edge as a block delimiter,
> though, you've significantly reduced the hamming distance between
> differing legitimate programs.
> [...]

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <scb6ov8mfvm34v8746m30ekrjq01hp4f8l@4ax.com>
On 7 Oct 2003 12:59:07 -0700, ········@yahoo.com.au (Hannu Kankaanp??)
wrote:

>·············@comcast.net wrote in message news:<············@comcast.net>...
>> ········@yahoo.com.au (Hannu Kankaanp??) writes:
>> > So getting to the point, doesn't the example show that indentation
>> > is in fact a *good* choice for block delimiting? It's an alternative that
>> > wouldn't have the subtle bug you introduced here. So how can you
>> > claim that this example shows indentation is a poor choice for block
>> > delimiting? It doesn't make sense.
>> 
>> The point was that even though I screwed up the indentation, it was
>> easily discovered and repaired with Emacs.  If the program were
>> whitespace-sensitive, then the screwed-up version would be
>> mechanically indistinguishable from the intended one.

>How do you "screw up indentation"? Actually, being more of a
>Python fan, I though you had screwed up parens, since indentation
>is absolute for me :). Anyway, do you just go to some line and start
>pressing spacebar randomly, and not notice this? Maybe
>you do need a safety net, then.
>

Maybe by coding in an environment with multiple programmers?
Alex was saying that Python's syntax and simplicity is so much better
for large scale projects with multiple programmers.  With just 4
programmers using Python at work we have problems with indentation
levels.  One guy (me) uses emacs, another uses ultra-edit, another
uses Boa and the other uses PythonWin.  Indenting can be a major
source of compilation bugs.

>But the whitespace already has all the structural information needed.
>The whitespace doesn't just disappear suddenly, much like parens don't
>magically disappear or mutate.
>
>There can be problems in cutting and pasting code if one mixes tabs
>and spaces, like Ingvar said, but generally the rule in Python is to
>use 4 spaces for each indentation level. If you break this rule,
>you know you had it coming when something fails ;).

Just because it's defined that way, doesn't make it less a pain in the
ass to fix the problems.

of course it's not a big problem if you are the only consumer of your
code.


Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Ingvar Mattsson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <871xtodal6.fsf@gruk.tech.ensign.ftech.net>
········@yahoo.com.au (Hannu Kankaanp??) writes:

[SNIP]
> But the whitespace already has all the structural information needed.
> The whitespace doesn't just disappear suddenly, much like parens don't
> magically disappear or mutate.

Just for fun, do some changes to a file, bung teh diff in a web-based
mail client and then apply the diff to the original code and see what
(if anything) is different. Whitespace mutate much more than
non-whitespace characters (apart from possibly &, < and >) when they
get shuffled through different parts of code.

//Ingvar (is that an argument against &AUX variables?)
-- 
When in douFNORD! This signature has been hi-jacked by Fnord Information
systems, to fnordprovide you with unfnordlimited information.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <873ce48y7g.fsf@thalassa.informatimago.com>
Ingvar Mattsson <······@cathouse.bofh.se> writes:

> ········@yahoo.com.au (Hannu Kankaanp??) writes:
> 
> [SNIP]
> > But the whitespace already has all the structural information needed.
> > The whitespace doesn't just disappear suddenly, much like parens don't
> > magically disappear or mutate.
> 
> Just for fun, do some changes to a file, bung teh diff in a web-based
> mail client and then apply the diff to the original code and see what
> (if anything) is different. Whitespace mutate much more than
> non-whitespace characters (apart from possibly &, < and >) when they
> get shuffled through different parts of code.

Which leads me to use   diff -NaurtwbB   when I make patches.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Rob Warnock
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <W0-dnWlECdx-Rh6iXTWc-w@speakeasy.net>
Pascal Bourguignon  <····@thalassa.informatimago.com> wrote:
+---------------
| Ingvar Mattsson <······@cathouse.bofh.se> writes:
| > Just for fun, do some changes to a file, bung teh diff in a web-based
| > mail client and then apply the diff to the original code and see what
| > (if anything) is different. Whitespace mutate much more than
| > non-whitespace characters (apart from possibly &, < and >) when they
| > get shuffled through different parts of code.
| 
| Which leads me to use   diff -NaurtwbB   when I make patches.
+---------------

Boy, will *that* break Python!! That is, it fails to catch a number of
significant differences between the files (especially the "-b" & "-B").

Also, while "-b" is o.k. for most non-Python code, you really, *really*
don't want to be using "-w", since it fails to distinguish between "FOOBAR"
and "FOO BAR".


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ismz62qy.fsf@thalassa.informatimago.com>
····@rpw3.org (Rob Warnock) writes:

> Pascal Bourguignon  <····@thalassa.informatimago.com> wrote:
> +---------------
> | Ingvar Mattsson <······@cathouse.bofh.se> writes:
> | > Just for fun, do some changes to a file, bung teh diff in a web-based
> | > mail client and then apply the diff to the original code and see what
> | > (if anything) is different. Whitespace mutate much more than
> | > non-whitespace characters (apart from possibly &, < and >) when they
> | > get shuffled through different parts of code.
> | 
> | Which leads me to use   diff -NaurtwbB   when I make patches.
> +---------------
> 
> Boy, will *that* break Python!! That is, it fails to catch a number of
> significant differences between the files (especially the "-b" & "-B").
> 
> Also, while "-b" is o.k. for most non-Python code, you really, *really*
> don't want to be using "-w", since it fails to distinguish between "FOOBAR"
> and "FOO BAR".

Right.  I'll remove -w from my patch diffs.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87pth89411.fsf@thalassa.informatimago.com>
········@yahoo.com.au (Hannu Kankaanp??) writes:
> How do you "screw up indentation"? Actually, being more of a
> Python fan, I though you had screwed up parens, since indentation
> is absolute for me :). 

There  are   a  lot  of  different  editors,   text  processors,  word
processors, and other text processing tools, and not all have the same
notion of  what indentation is  and what can  be done or not  with the
white spaces.

Granted, since I use exclusively emacs and banned TAB characters, I've
got  less  problems,  but  it's   still  quite  easy  to  C-u  80  M-x
decrease-left-margin RET.

Also, with the  spread of the WWW, and with  the generalization of the
Internet protocols, there  seem to be much less  variations in network
transports; when  did you  last read a  BITNET (EBCDIC) mail  list? or
when did  you last downloaded a file  from a FTP server  that does not
have a byte stream paradigm but  record based text files?  

But  even if  you're  young enough  to  not know  these systems,  HTML
specifies that what  spaces are not significant, and  it happens often
enough to  find full  justified blocks of  code that should  have been
enclosed in <pre></pre> but are not...




-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <y8vw64zy.fsf@comcast.net>
········@yahoo.com.au (Hannu Kankaanp??) writes:

> ·············@comcast.net wrote in message news:<············@comcast.net>...
>> ········@yahoo.com.au (Hannu Kankaanp??) writes:
>> > So getting to the point, doesn't the example show that indentation
>> > is in fact a *good* choice for block delimiting? It's an alternative that
>> > wouldn't have the subtle bug you introduced here. So how can you
>> > claim that this example shows indentation is a poor choice for block
>> > delimiting? It doesn't make sense.
>> 
>> The point was that even though I screwed up the indentation, it was
>> easily discovered and repaired with Emacs.  If the program were
>> whitespace-sensitive, then the screwed-up version would be
>> mechanically indistinguishable from the intended one.
>
> How do you "screw up indentation"? 

I don't know, but may I draw your attention to these URLs:


http://www.python.org/search/hypermail/python-1994q2/0752.html

http://www-106.ibm.com/developerworks/library/l-pycon.html?t=gr,lnxw06=PyIntro

In the first, I see this code snippet:

-------------------------

def zip(*args):
result = []
i = 0
while 1:
item = []
ok = 0
for a in args:
try:
ai = a[i]
except IndexError:
ai = None
else:
ok = 1
item.append(ai)
if not ok:
break
result.append(tuple(item))
i = i+1
return result


def tuple(list):
t = ()
for i in list: t = t + (i,)
return t

---------------------

and in the second, I see this:

--------------------

import random
def randomwalk_list():
    last, rand = 1, random.random() # init candidate elements
    nums = []                       # empty listwhile rand > 0.1:               # threshhold terminatorif abs(last-rand) >= 0.4:   # accept the number
            last = rand
            nums.append(rand)       # add latest candidate to numselse:
            print'*',              # display the rejection
        rand = random.random()      # new candidate
    nums.append(rand)               # add the final small elementreturn nums

-------------------

These don't look right to me, but I'm not a python expert.

But it must be what the authors intended because we
all know that no one mysteriously adds and removes
whitespace.
  
From: Hannu Kankaanp??
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <840592e1.0310072232.60438bc5@posting.google.com>
·············@comcast.net wrote in message news:<············@comcast.net>...
> ········@yahoo.com.au (Hannu Kankaanp??) writes:
> 
> > ·············@comcast.net wrote in message news:<············@comcast.net>...
> >> ········@yahoo.com.au (Hannu Kankaanp??) writes:
> >> > So getting to the point, doesn't the example show that indentation
> >> > is in fact a *good* choice for block delimiting? It's an alternative that
> >> > wouldn't have the subtle bug you introduced here. So how can you
> >> > claim that this example shows indentation is a poor choice for block
> >> > delimiting? It doesn't make sense.
> >> 
> >> The point was that even though I screwed up the indentation, it was
> >> easily discovered and repaired with Emacs.  If the program were
> >> whitespace-sensitive, then the screwed-up version would be
> >> mechanically indistinguishable from the intended one.
> >
> > How do you "screw up indentation"? 
> 
> I don't know, but may I draw your attention to these URLs:
> 
> http://www.python.org/search/hypermail/python-1994q2/0752.html
> 
> http://www-106.ibm.com/developerworks/library/l-pycon.html?t=gr,lnxw06=PyIntro

Point taken, but the second example is bogus. Comments
will eat Lisp code equally well as they eat Python code
if some line breaks are missing. Line breaks seem pretty
important independent of block structuring choice, if
comments that eat rest of the line are used.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7k3g5gos.fsf@comcast.net>
········@yahoo.com.au (Hannu Kankaanp??) writes:

> ·············@comcast.net wrote in message news:<············@comcast.net>...
>> ········@yahoo.com.au (Hannu Kankaanp??) writes:
>> 
>> > ·············@comcast.net wrote in message news:<············@comcast.net>...
>> >> ········@yahoo.com.au (Hannu Kankaanp??) writes:
>> >> > So getting to the point, doesn't the example show that indentation
>> >> > is in fact a *good* choice for block delimiting? It's an alternative that
>> >> > wouldn't have the subtle bug you introduced here. So how can you
>> >> > claim that this example shows indentation is a poor choice for block
>> >> > delimiting? It doesn't make sense.
>> >> 
>> >> The point was that even though I screwed up the indentation, it was
>> >> easily discovered and repaired with Emacs.  If the program were
>> >> whitespace-sensitive, then the screwed-up version would be
>> >> mechanically indistinguishable from the intended one.
>> >
>> > How do you "screw up indentation"? 
>> 
>> I don't know, but may I draw your attention to these URLs:
>> 
>> http://www.python.org/search/hypermail/python-1994q2/0752.html
>> 
>> http://www-106.ibm.com/developerworks/library/l-pycon.html?t=gr,lnxw06=PyIntro
>
> Point taken, but the second example is bogus. Comments
> will eat Lisp code equally well as they eat Python code
> if some line breaks are missing. Line breaks seem pretty
> important independent of block structuring choice, if
> comments that eat rest of the line are used.

I'll still argue that I'd have an easier time figuring out
the intent of the code if it had delimiters.  At the second
URL, there is an example where line 2 has gotten several
comments glommed on it:

def randomwalk_static(last=[1]):    # init the "static" var(s)
    rand = random.random()          # init a candidate valueif last[0] < 0.1:               # threshhold terminatorreturn None                 # end-of-stream flagwhile abs(last[0]-rand) < 0.4:  # look for usable candidateprint'*',                  # display the rejection
        rand = random.random()      # new candidate
    last[0] = rand                  # update the "static" varreturn rand


Now I can guess that the intended lines were:

if last[0] < 0.1:
return None
while abs(last[0]-rand) < 0.4:  
print'*',

but it's a lot more work to guess the indentation.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87oewr62wm.fsf@thalassa.informatimago.com>
·············@comcast.net writes:
> I'll still argue that I'd have an easier time figuring out
> the intent of the code if it had delimiters.  At the second
> URL, there is an example where line 2 has gotten several
> comments glommed on it:
> 
> def randomwalk_static(last=[1]):    # init the "static" var(s)
>     rand = random.random()          # init a candidate valueif last[0] 
> < 0.1:               # threshhold terminatorreturn None     # end-of-stream
> flagwhile abs(last[0]-rand) < 0.4:  # look for usable candidateprint'*',
>                  # display the rejection
>         rand = random.random()      # new candidate
>     last[0] = rand                  # update the "static" varreturn rand
> 

This becomes really ridiculous!   

Both comments and statements  MUST be encapsulated in parenthesis.  Up
to end-of-line comments are evil, because the line may be cut and what
was once a comment suddenly become statement...

You never have  any problem with Modula-2 comments (*  that you can (*
enclose in sub-comments *) like  that, and split over several lines as
needed *).


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <evi8ovkdikbh7gtb1omr6li0psspq32ajr@4ax.com>
On Tue, 07 Oct 2003 14:01:07 GMT, ·············@comcast.net wrote:

>The point was that even though I screwed up the indentation, it was
>easily discovered and repaired with Emacs.  If the program were
>whitespace-sensitive, then the screwed-up version would be
>mechanically indistinguishable from the intended one.

How do you do that with Emacs?  There have been several sections of
code that I would've like to fix this way, but I don't know the
command.

Can you tell me what the command is?  Or what the typical key-binding
is under Lisp Interaction Mode?


Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvad8br1xx.fsf@famine.OCF.Berkeley.EDU>
Doug Tolton <····@nospam.com> writes:

> On Tue, 07 Oct 2003 14:01:07 GMT, ·············@comcast.net wrote:
> 
> >The point was that even though I screwed up the indentation, it was
> >easily discovered and repaired with Emacs.  If the program were
> >whitespace-sensitive, then the screwed-up version would be
> >mechanically indistinguishable from the intended one.
> 
> How do you do that with Emacs?  There have been several sections of
> code that I would've like to fix this way, but I don't know the
> command.
> 
> Can you tell me what the command is?  Or what the typical key-binding
> is under Lisp Interaction Mode?

indent-sexp[-ilisp], it's usually bound to M-C-q

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <d6d7ef84.fsf@ccs.neu.edu>
Doug Tolton <····@nospam.com> writes:

> On Tue, 07 Oct 2003 14:01:07 GMT, ·············@comcast.net wrote:
>
>>The point was that even though I screwed up the indentation, it was
>>easily discovered and repaired with Emacs.  If the program were
>>whitespace-sensitive, then the screwed-up version would be
>>mechanically indistinguishable from the intended one.
>
> How do you do that with Emacs?  There have been several sections of
> code that I would've like to fix this way, but I don't know the
> command.

The obvious one is 

    M-C-q   indent-sexp

Which will re-indent the sexp based on the parenthesis and symbols
in the CAR of the list.  If the resulting indentation is bogus, you
probably have an unbalanced paren or something.

But it is *very* worthwhile to learn these:

    M-(    insert-parenthesis
           Puts in a () pair and puts point between them.

    M-C-f  forward-sexp
    M-C-b  backward-sexp
           Go forward or backward by s-exp.

    M-C-k    kill-sexp
    M-C-del  backward-kill-sexp
             Delete an sexp.

    M-C-t  transpose-sexp
           swaps the sexps on either side of point, moving point to behind
           the last one.  This sounds random, but it allows you to `drag'
           sexps around in list structure.  You can get an awful lot of
           milage out of this one.

    ····@  mark-sexp
           Puts mark at end of next sexp, leaves point where it is.
           If your emacs is set up to highlight the current region, this
           will highlight the sexp.


These next two are a bit esoteric, but also worth knowing:

    C-M-u   backward-up-list
            Go to the beginning of the *containing* list structure.
            So suppose you are in the body of a LET expression.  C-M-u
            will put point just before the open paren of the LET.

    C-M-d   down-list
            Go to the beginning of the next *contained* list structure.


These ones aren't particularly lisp-specific, but rather handy in lisp
mode:

    C-M-a  beginning-of-defun
           Takes you to the current top level defun.  At this point, if you
           type C-M-f (forward-sexp) you'll either end up at the end of
           the current defun, or your parens aren't balanced.

    C-M-/  dabbrev-completion
           If you type the first few letters of a symbol and hit this,
           it will attempt to complete the symbol.  If it guesses wrong,
           hit it again.  You can save a lot of typing with this and still
           use reasonably descriptive identifiers.


You should also be using font-lock-mode.  I have mine set up for *extreme*
coloring (much more than the usual maximum decoration).  I have found that
what happens is that I no longer pay much conscious attention to the color,
but if the color is `wrong', the code looks `funny' and I'm alerted to the
error right away.


I suggest taking a day and forcing yourself to use these commands.
It'll be slow going for a little while (an hour or two), but then
you'll get the hang of it and you'll wonder how you ever did without.
From: Brian Downing
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <TqZgb.705807$YN5.575556@sccrnsc01>
In article <············@ccs.neu.edu>, Joe Marshall  <···@ccs.neu.edu> wrote:
> But it is *very* worthwhile to learn these:

An excellent list!

>     M-(    insert-parenthesis
>            Puts in a () pair and puts point between them.

Very useful also with this is the prefix-arg version, which puts the
parens around the next arg forms.

Since I've always learned useful stuff when someone has given an editing
example, here is my silly one.  It should be noted that I have [ bound
to M-(, and ] bound to M-).  I am using ilisp, which provides some more
indenting commands (M-q, reindent-lisp).

(defun drive (speed)
  (accelerate speed)
  (get-pulled-over)
  (decf *currency* 75)
  (make-court-appearance))

Clearly we need some sort of conditional here.  If I put point in front
of (get-pulled-over), I would hit:

M-3 [ when [ > speed *speed-limit* ] M-q

to get:

(defun drive (speed)
  (accelerate speed)
  (when (> speed *speed-limit*)
    (get-pulled-over)
    (decf *currency* 75)
    (make-court-appearance)))

If I already had the conditional, and wanted to get rid of it, I would
do (again starting with point before (get-pulled-over):

C-M-k C-M-k C-M-k C-M-u C-M-k C-y M-y M-y M-q

to get the original function:

(defun drive (speed)
  (accelerate speed)
  (get-pulled-over)
  (decf *currency* 75)
  (make-court-appearance))

I think some lisp editors have something like a kill-up-tree command to
do my second example.  I haven't written one yet, but have thought about
it.

I'm an old vi user, and still think vim is quite a bit more friendly and
powerful for me when editing a language like C where things are done by
lines, not structure.  But I have to admit that emacs's sexp
manipulation commands are insanely productive.  I definitely would not
write lisp in vi.

Hope this helps someone.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Steven E. Harris
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <q67k77feaqf.fsf@raytheon.com>
Brian Downing <·············@lavos.net> writes:

> It should be noted that I have [ bound to M-(, and ] bound to M-).

In case others would like to give this a try, here's my XEmacs
configuration to use [ and ] as M-( and M-) respectively, preserving
the original characters as M-[ and M-].


(defmacro make-key-inserter (def)
  "Substitute for `self-insert-command'."
  `(lambda (arg)
    (interactive "*P")
    (insert-char ,def (prefix-numeric-value arg))))

(define-key shared-lisp-mode-map ?\[ 'insert-parentheses)
(define-key shared-lisp-mode-map ?\] 'move-past-close-and-reindent)
(define-key shared-lisp-mode-map '(meta ?\[) (make-key-inserter ?\[))
(define-key shared-lisp-mode-map '(meta ?\]) (make-key-inserter ?\]))
(define-key shared-lisp-mode-map '(meta control ?\]) 'close-all-lisp)


I couldn't figure out how to use something like self-insert-command to
just insert "[" and "]" without reinterpreting them again as key
presses, so I wrote the macro to approximate what self-insert-command
would have done.

-- 
Steven E. Harris        :: ········@raytheon.com
Raytheon                :: http://www.raytheon.com
From: lawrence mitchell
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <?fnord?ud6d636o1.fsf@ID-97657.usr.dfncis.de>
Steven E. Harris wrote:

[...] Swap () and []

> I couldn't figure out how to use something like self-insert-command to
> just insert "[" and "]" without reinterpreting them again as key
> presses, so I wrote the macro to approximate what self-insert-command
> would have done.

How about, in Emacs, not sure about XEmacs:

(keyboard-translate ?\[ ?\()
(keyboard-translate ?\( ?\[)
(keyboard-translate ?\) ?\])
(keyboard-translate ?\] ?\))

Though this does set up a translation irrespective of mode,
which may not be ideal.

You might be able to make KEYBOARD-TRANSLATION-TABLE
buffer-local to work around this though.
-- 
lawrence mitchell <·····@gmx.li>
From: Steven E. Harris
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <q673ce2avle.fsf@raytheon.com>
lawrence mitchell <·····@gmx.li> writes:

> How about, in Emacs, not sure about XEmacs:

Yes, XEmacs does support this.

> Though this does set up a translation irrespective of mode, which
> may not be ideal.
>
> You might be able to make KEYBOARD-TRANSLATION-TABLE buffer-local to
> work around this though.

It looks like keyboard-translate-table is global�, not mode- or
buffer-local.

,----
| M-: (make-variable-buffer-local 'keyboard-translate-table) RET
| 
| Symbol may not be buffer-local: keyboard-translate-table
`----

Oh well. The posted code does the trick when one wants to confine the
key swaps to the Lisp modes.


Footnotes: 
� documentation: "`keyboard-translate-table' is a simple built-in
                  constant variable."

-- 
Steven E. Harris        :: ········@raytheon.com
Raytheon                :: http://www.raytheon.com
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <r81no2ys.fsf@ccs.neu.edu>
Brian Downing <·············@lavos.net> writes:

> Since I've always learned useful stuff when someone has given an editing
> example, here is my silly one.  It should be noted that I have [ bound
> to M-(, and ] bound to M-).  

I have remapped my keyboard so that ( and ) are where [ and ] are.
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <_7_gb.5706770$cI2.807298@news.easynews.com>
Joe Marshall wrote:

> Doug Tolton <····@nospam.com> writes:
> 
> 
>>On Tue, 07 Oct 2003 14:01:07 GMT, ·············@comcast.net wrote:
>>
>>
>>>The point was that even though I screwed up the indentation, it was
>>>easily discovered and repaired with Emacs.  If the program were
>>>whitespace-sensitive, then the screwed-up version would be
>>>mechanically indistinguishable from the intended one.
>>
>>How do you do that with Emacs?  There have been several sections of
>>code that I would've like to fix this way, but I don't know the
>>command.
> 
> 
> The obvious one is 
> 
>     M-C-q   indent-sexp
> 
> Which will re-indent the sexp based on the parenthesis and symbols
> in the CAR of the list.  If the resulting indentation is bogus, you
> probably have an unbalanced paren or something.
> 
> But it is *very* worthwhile to learn these:
> 
>     M-(    insert-parenthesis
>            Puts in a () pair and puts point between them.
> 
>     M-C-f  forward-sexp
>     M-C-b  backward-sexp
>            Go forward or backward by s-exp.
> 
>     M-C-k    kill-sexp
>     M-C-del  backward-kill-sexp
>              Delete an sexp.
> 
>     M-C-t  transpose-sexp
>            swaps the sexps on either side of point, moving point to behind
>            the last one.  This sounds random, but it allows you to `drag'
>            sexps around in list structure.  You can get an awful lot of
>            milage out of this one.
> 
>     ····@  mark-sexp
>            Puts mark at end of next sexp, leaves point where it is.
>            If your emacs is set up to highlight the current region, this
>            will highlight the sexp.
> 
> 
> These next two are a bit esoteric, but also worth knowing:
> 
>     C-M-u   backward-up-list
>             Go to the beginning of the *containing* list structure.
>             So suppose you are in the body of a LET expression.  C-M-u
>             will put point just before the open paren of the LET.
> 
>     C-M-d   down-list
>             Go to the beginning of the next *contained* list structure.
> 
> 
> These ones aren't particularly lisp-specific, but rather handy in lisp
> mode:
> 
>     C-M-a  beginning-of-defun
>            Takes you to the current top level defun.  At this point, if you
>            type C-M-f (forward-sexp) you'll either end up at the end of
>            the current defun, or your parens aren't balanced.
> 
>     C-M-/  dabbrev-completion
>            If you type the first few letters of a symbol and hit this,
>            it will attempt to complete the symbol.  If it guesses wrong,
>            hit it again.  You can save a lot of typing with this and still
>            use reasonably descriptive identifiers.
> 
> 
> You should also be using font-lock-mode.  I have mine set up for *extreme*
> coloring (much more than the usual maximum decoration).  I have found that
> what happens is that I no longer pay much conscious attention to the color,
> but if the color is `wrong', the code looks `funny' and I'm alerted to the
> error right away.
> 
> 
> I suggest taking a day and forcing yourself to use these commands.
> It'll be slow going for a little while (an hour or two), but then
> you'll get the hang of it and you'll wonder how you ever did without.

Those are very useful key commands.  Thank you Joe.
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <u167zzuz.fsf@ccs.neu.edu>
Jan Rychter <···@rychter.com> writes:

> Joe Marshall:
>>
>>     M-C-del  backward-kill-sexp
>>              Delete an sexp.
> [...]
>
> That one is rather interesting for people using Emacs/XEmacs on a Linux
> console.
>
> I also seem to remember reading a posting about M-C-Backspace being
> "interesting" under XFree and actually trying it out...

I use a Dvorak keyboard on Windows.  Not every piece of software out
there implements the event loop correctly.  In particular, some
`short-circuit' the handling of control characters to bypass keyboard
translation.  So when I use SSH to run Emacs remotely, I have to
remember to mentally switch to QWERTY mode when I have the control key
down, but switch back to Dvorak when it is up.

This makes life rather `exciting'.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfs65ingag9.fsf@black132.ex.ac.uk>
Joe Marshall <···@ccs.neu.edu> writes:

> I use a Dvorak keyboard on Windows.  Not every piece of software out
> there implements the event loop correctly.  In particular, some
> `short-circuit' the handling of control characters to bypass keyboard
> translation.  So when I use SSH to run Emacs remotely, I have to
> remember to mentally switch to QWERTY mode when I have the control key
> down, but switch back to Dvorak when it is up.
> 
> This makes life rather `exciting'.

Best reason for using vi I've ever seen :)

'as
From: Björn Lindberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <hcsllrvvb97.fsf@fnatte.nada.kth.se>
Doug Tolton <····@nospam.com> writes:

> On Tue, 07 Oct 2003 14:01:07 GMT, ·············@comcast.net wrote:
> 
> >The point was that even though I screwed up the indentation, it was
> >easily discovered and repaired with Emacs.  If the program were
> >whitespace-sensitive, then the screwed-up version would be
> >mechanically indistinguishable from the intended one.
> 
> How do you do that with Emacs?  There have been several sections of
> code that I would've like to fix this way, but I don't know the
> command.
> 
> Can you tell me what the command is?  Or what the typical key-binding
> is under Lisp Interaction Mode?

C-M-q will indent the whole s-exp after the cursor. M-x indent-region
will indent a whole region of code. C-x h marks the whole buffer, so
C-x h M-x indent-region will format a whole file(buffer).


Bj�rn
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8765j1avma.fsf@thalassa.informatimago.com>
········@yahoo.com.au (Hannu Kankaanp??) writes:
> The problem with the example arises from the fact that indentation
> is used for human readability, but parens are used by the parser.
> A clash between these two representations can lead to subtle bugs
> like this one. But remove one of the representations, and there
> can't be clashes. Of course removing indentation would lead
> super-ugly code, so why not just remove parens like has been
> done in Python? 

That's an easy one:  because when I drop my lisp files,  I end up with
all lines  flushed to the right  (or to the left)  and no indentation.
Then I'm happy  to have the parentheses structuring my  code to let my
editor re-indent it properly.



Another reason, but  it may be more complicated  to understand is that
sometimes I  want to format my code  in a more readable  way, and that
means, with an  indentation that DOES NOT correspond  to the syntactic
structure of the program, but rather to its semantic structure.


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsbrssg572.fsf@black132.ex.ac.uk>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> That's an easy one:  because when I drop my lisp files,  I end up with
> all lines  flushed to the right  (or to the left)  and no indentation.
> Then I'm happy  to have the parentheses structuring my  code to let my
> editor re-indent it properly.

Why drop your files in the first place?
 
> Another reason, but  it may be more complicated  to understand is that
> sometimes I  want to format my code  in a more readable  way, and that
> means, with an  indentation that DOES NOT correspond  to the syntactic
> structure of the program, but rather to its semantic structure.

Could you maybe provide an example (ideally one where another human reader
would not be misled by your choice of indentation)?

'as
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87brss8ysr.fsf@thalassa.informatimago.com>
Alexander Schmolck <··········@gmx.net> writes:

> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
> > That's an easy one:  because when I drop my lisp files,  I end up with
> > all lines  flushed to the right  (or to the left)  and no indentation.
> > Then I'm happy  to have the parentheses structuring my  code to let my
> > editor re-indent it properly.
> 
> Why drop your files in the first place?

Because of gravity, and because you need to move them from the storage
cabinet to the card reader.


> > Another reason, but  it may be more complicated  to understand is that
> > sometimes I  want to format my code  in a more readable  way, and that
> > means, with an  indentation that DOES NOT correspond  to the syntactic
> > structure of the program, but rather to its semantic structure.
> 
> Could you maybe provide an example (ideally one where another human reader
> would not be misled by your choice of indentation)?

Take the  case of prog1, prog2  and progn2.  They have  about the same
syntactic structure. However we indent them differently:

    (prog1
        result
      additional-1
      additional-2)

    (prog2
        initial
        result
      additional-1
      additional-2)

    (progn
      statement-1
      statement-2
      statement-n
      result)


But what I have in mind is cases where I format the source in a tabular form:

    (case state
      ;; state       column-1   column-2   column-3   column-4 
      ;; ----------  ---------  ---------  ---------  ---------
        (:state-1    (act-1)               (act-3)    (act-4)   )
        (:state-2               (act-2)    (act-3)    (act-4)   )
        (:state-3    (act-1)    (act-2)                        
                     (act-1)               (act-3)              )
      ;; etc
     )


One case that happens often enough, in C, would be:

    if(condition-1){ statement-1;                    final-1; }else
    if(condition-2){ statement-2-1; statement-2-2;   final-2; }else
    if(condition-3){ stat-3;                         final-3; }


Another case, but perhaps it is  not discriminant if a similar form is
possible in python is when a control structure can stand one one line,
particularly when there are several similar control structures:

    (if condition-1  statement-1a     statement-1b)
    (if condition-2  stat-2a          statement-2b)
    (if condition-3  statement-3a     stat-3b)

[vs.
    (if condition-1
        statement-1a
        statement-1b)
]




In anycase, when you'll have a  macro system as powerful as the one in
Common-Lisp,  I  guess  that   you'll  see  reasons  enough  to  avoid
structuring indentation.  For  an example of what I  mean, have a look
at the output  of cpp (gcc -E)  with the expansion of a  couple of cpp
macros.


But  to revert  to the  original subject  "Python syntax  in  Lisp and
Scheme", I think  that you can easily write  macros and read-macros to
let you interpret  a range of text in a lisp  source as python source,
taking into account the spaces.


For example, loading this python.lisp file:
------------------------------------------------------------------------
(defvar *python-readtable* (copy-readtable nil))

(set-macro-character
 (character " ")
 (lambda (stream char)
   (cons
    (loop for indent from 1
          until (char/= (character " ") char)
          do (setq char (read-char stream nil nil t))
          finally return indent)
    (with-standard-io-syntax (concatenate 'string (string char)
                                          (read-line stream nil nil t)))))
 nil *python-readtable*)

(defun python-mode () (setq *readtable* *python-readtable*)   (values))
(defun lisp-mode   () (setq *readtable* (copy-readtable nil)) (values))


(setq python-code
      '(
#.(python-mode)
  i cannot
      program in
      python
          but you get
      the idea
  i guess...
#.(lisp-mode)
))

(format t "python-code=~S~%" python-code)
------------------------------------------------------------------------
gives:

[26]> (load "python.lisp")
python-code=
(NIL (3 . "i cannot") (7 . "program in") (7 . "python") (11 . "but you get")
 (7 . "the idea") (3 . "i guess...") NIL)

and from then  on, you could python-parse the  lines, interpreting the
indentation.  Addition  of sweeter syntactic sugar macros  left to the
reader...



My point  here being that  if you like python  structural indentation,
you  can easy  implement  it in  Common-Lisp. 

If you like parenthesis indentation,  could you as easily have them in
python?


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfshe2je356.fsf@black132.ex.ac.uk>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Alexander Schmolck <··········@gmx.net> writes:
> > Why drop your files in the first place?
> 
> Because of gravity, and because you need to move them from the storage
> cabinet to the card reader.

Yes, I thought it must be a similarly frequently encountered problem.

> > Could you maybe provide an example (ideally one where another human reader
> > would not be misled by your choice of indentation)?
> 
> Take the  case of prog1, prog2  and progn2.  They have  about the same
> syntactic structure. However we indent them differently:

Hmm, I don't think standard stuff like PROGx, IF etc. forms relevant examples
(either it's always indented in that way (by common convention in CL and by
necessity in some hypothetical python)) or you're dealing with a misfeature
(or do you e.g. think that the millions of man-hours wasted on debating,
setting up and converting between various C (or worse C++) indentation schemes
are a worthy price for individual freedom of
indentation-preference-self-expression?).


> 
> But what I have in mind is cases where I format the source in a tabular form:
> 
>     (case state
>       ;; state       column-1   column-2   column-3   column-4 
>       ;; ----------  ---------  ---------  ---------  ---------
>         (:state-1    (act-1)               (act-3)    (act-4)   )
>         (:state-2               (act-2)    (act-3)    (act-4)   )
>         (:state-3    (act-1)    (act-2)                        
>                      (act-1)               (act-3)              )
>       ;; etc
>      )

[Well, you'd better not drop this one (unless your emacs comes with M-x
ai-indent-region :)]

A better example, only that you could write something analogous (certainly as
far as use of indentation is concerned) in python (verbose rendition):

    #              state       column-1   column-2   column-3   column-4 
    stateTable = {'state1' :   (func1,               func3,     func4),
                  'state2' :   (                     func3,     func4),
                  'state3' :   (func1,    func2,     func3,
                             thisIsSyntacticallyOKTooBTW)}
    for action in stateTable[state]: action()



> 
> 
> One case that happens often enough, in C, would be:
> 
>     if(condition-1){ statement-1;                    final-1; }else
>     if(condition-2){ statement-2-1; statement-2-2;   final-2; }else
>     if(condition-3){ stat-3;                         final-3; }

      if    condition1: statement1;    final1
      elif  condition2: statement2_1;  final2
      else:             stat3

Happy?

> In anycase, when you'll have a  macro system as powerful as the one in
> Common-Lisp,  I  guess  that   you'll  see  reasons  enough  to  avoid
> structuring indentation.  For  an example of what I  mean, have a look
> at the output  of cpp (gcc -E)  with the expansion of a  couple of cpp
> macros.

Well, I explicitly disclaimed that changing lisp to structuring indentation
would be necessarily a good idea. 

I just think the arguments why it's a bad idea for python are pretty bogus
(one I think pretty good reason to back up my conclusion is empirical
observation: frequent python users, including myself don't seem to experience
problems with python's use of indentation [1], despite the fact that they are
familiar (and often even weaned on) languages with different structure
delimiters, *including* lisp and scheme. What is more, I have seen few
complaints from people who have actually written significant amounts of code
in python, it's mostly those who haven't used python but were unfortunately
subjected to make and fortran who are certain python must be really
error-prone because of whitespace etc.).

 
> My point  here being that  if you like python  structural indentation,
> you  can easy  implement  it in  Common-Lisp. 

Sure, I know.
 
> If you like parenthesis indentation,  could you as easily have them in
> python?

If you mean as an alternative syntax: Nope and that's a feature.

'as

Footnotes:

[1] I will concede that there is one wart about indentation in python: tabs
are only discouraged (the standard which most people adhere to is 4 spaces per
level), not disallowed.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87k77f2q3a.fsf@thalassa.informatimago.com>
Alexander Schmolck <··········@gmx.net> writes:
> [1] I will concede that there is one wart about indentation in python: tabs
> are only discouraged (the standard which most people adhere to is 4 spaces per
> level), not disallowed.

I did not thought about it.   Is there a pragma or something to inform
the python compiler  of the width of the  tabulation?  Happily I don't
use python, I often find  code formated with tabulations that had been
used as a number of space different  from what I use, and this is only
a  minor anoyance when  I cut-and-paste  it into  my code,  since with
parenthesis or braces, emacs can easily reformat it with only spaces.

    

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f8346a9@news.sentex.net>
In article <····························@posting.google.com>,
	········@yahoo.com.au (Hannu Kankaanp??) writes:
> ...
> So getting to the point, doesn't the example show that indentation
> is in fact a *good* choice for block delimiting? It's an alternative that
> wouldn't have the subtle bug you introduced here. So how can you
> claim that this example shows indentation is a poor choice for block
> delimiting? It doesn't make sense.

assume you seem a piece of code you never saw before, with its
indentation screwed up.  how do you untangle it?

> The problem with the example arises from the fact that indentation
> is used for human readability, but parens are used by the parser.
> A clash between these two representations can lead to subtle bugs
> like this one. But remove one of the representations, and there
> can't be clashes. Of course removing indentation would lead
> super-ugly code, so why not just remove parens like has been
> done in Python? I haven't heard of people swearing about bugs
> introduced by this syntax choice, nor have I personally ever
> made a mistake with indentation.

i had one big screw up, when a coworker messed with a python file
using some MS editor like notepad or whatever the thing was called.
it was painful to fix.

more important, the indentation makes the code more readable for
humans, but explicit delimiters (which can be used an intelligent to
indent the code properly) leaves visible marks that can be checked
independently.  emacs often enough alerted me to typos by putting in
indentations that signalled something different from what i intended.

what i don't understand is wha an indentation based syntax is supposed
to buy you compared to explicit delimiters (as long as they aren't too
verbose).  at the end of a block you must (in python) hit the back tab
key to indicate the  end of the block.  in lisp i indicate the same
with ")", in C/C++ with "}".  the typing is the same.  with the
explicit delimiters i have clearly spelled out signals indicating the
code structure that can be used by any decent editor or code formatter
to display the code in a neat form

hs

-- 

ceterum censeo SCO esse delendam
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <fGEgb.21271$pv6.11600@twister.nyc.rr.com>
Hannu Kankaanp?? wrote:

> The problem with the example arises from the fact that indentation
> is used for human readability, but parens are used by the parser.

And by the editor, meaning the buggy code with the extra parens had not 
been written in a parens-aware editor (or the coder had stuck a parens 
on without kicking off a re-indentation).

> A clash between these two representations can lead to subtle bugs
> like this one. But remove one of the representations, and there
> can't be clashes.

No need. Better yet, with parens you do not have to do the indentation 
yourself, you just have to look at what you are typing. Matching parens 
highlight automatically as you close up nested forms (it's kinda fun 
actually), and then a single key chard re-indents (if you have been 
refactoring and things now belong at diff indentation levels).

I used to spend a /lot/ of time on indentation (in other languages). No 
more. That is just one of the advantages of all those parentheses.

kenny
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f8216be@news.sentex.net>
In article <············@ccs.neu.edu>,
	Joe Marshall <···@ccs.neu.edu> writes:
> ...
> Freedom, horrible freedom!  It so much harder to think than it is to
> let other people do it for you.

reminds me of an argument an intel guy (probably sales) put forward in
SIGPLAN in praise of the 8086 architecture (shortly after this
abomination was introduced):  he argued that instructions requiring
their operands relieves programmers (and compilers) from the burden of
having to chose registers

> ...

hs

-- 

ceterum censeo SCO esse delendam
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bltjiv$m75$1@news-int2.gatech.edu>
> The vast majority of people who design languages have had minimal,
> if any, exposure to Lisp.
To be fair, the designers of Java really do have a lot of Lisp experience.
Its just that they intentionally chose to restrict the language according
to their belief that a free-form, expressive language did not mesh-well
with the types of development models you have in internet companies. You
may disagree with that conclusion, but you can't disagree with their
backgrounds.

PS> You'd be surprised how many language designers like and have exposure
Lisp. Even Bjarne Stroustrup is a fan of CL + CLOS in addition to ML. If
you read the new XTI proposal, you'll see bits of Lisp-y stuff in there
(even a prefix notation.)
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Qnzgb.6$KR3.660@typhoon.nyu.edu>
Rayiner Hashem wrote:

>>The vast majority of people who design languages have had minimal,
>>if any, exposure to Lisp.
> 
> To be fair, the designers of Java really do have a lot of Lisp experience.
> Its just that they intentionally chose to restrict the language according
> to their belief that a free-form, expressive language did not mesh-well
> with the types of development models you have in internet companies. You
> may disagree with that conclusion, but you can't disagree with their
> backgrounds.
> 
> PS> You'd be surprised how many language designers like and have exposure
> Lisp. Even Bjarne Stroustrup is a fan of CL + CLOS in addition to ML. If
> you read the new XTI proposal, you'll see bits of Lisp-y stuff in there
> (even a prefix notation.)

Greenspun's Tenth Rules. :)

--
Marco
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blu20r$ggm$1@f1node01.rhrz.uni-bonn.de>
Rayiner Hashem wrote:
>>The vast majority of people who design languages have had minimal,
>>if any, exposure to Lisp.
> 
> To be fair, the designers of Java really do have a lot of Lisp experience.
> Its just that they intentionally chose to restrict the language according
> to their belief that a free-form, expressive language did not mesh-well
> with the types of development models you have in internet companies. You
> may disagree with that conclusion, but you can't disagree with their
> backgrounds.

James Gosling invented mocklisp which obviously isn't really a Lisp. See 
http://www.wikipedia.org/wiki/Gosling_Emacs

Guy Steele was involved in the Java specification as a kind of 
"biographer" of the specification process. See 
http://groups.google.com/groups?selm=b4aq6e%244h4%241%40f1node01.rhrz.uni-bonn.de 
and http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html

Gilad Bracha was involved in the 2nd edition of Java. He is mainly a 
Smalltalk guy.

I don't know how much Lisp exposure Bill Joy had.

Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <d6d96tmn.fsf@comcast.net>
Pascal Costanza <········@web.de> writes:

> Rayiner Hashem wrote:
>>>The vast majority of people who design languages have had minimal,
>>>if any, exposure to Lisp.
>> To be fair, the designers of Java really do have a lot of Lisp
>> experience.
>> Its just that they intentionally chose to restrict the language according
>> to their belief that a free-form, expressive language did not mesh-well
>> with the types of development models you have in internet companies. You
>> may disagree with that conclusion, but you can't disagree with their
>> backgrounds.
>
> James Gosling invented mocklisp which obviously isn't really a
> Lisp. See http://www.wikipedia.org/wiki/Gosling_Emacs

He got the syntax about right, though.

> Guy Steele was involved in the Java specification as a kind of
> "biographer" of the specification process. See
> http://groups.google.com/groups?selm=b4aq6e%244h4%241%40f1node01.rhrz.uni-bonn.de
> and http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html

And Guy Steele has explicitly disavowed having a role in the
design of Java.

> Gilad Bracha was involved in the 2nd edition of Java. He is mainly a
> Smalltalk guy.
>
> I don't know how much Lisp exposure Bill Joy had.
From: Marc Battyani
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bludk0$spv@library2.airnews.net>
"Rayiner Hashem" <·······@mail.gatech.edu> wrote
> > The vast majority of people who design languages have had minimal,
> > if any, exposure to Lisp.
> To be fair, the designers of Java really do have a lot of Lisp experience.
> Its just that they intentionally chose to restrict the language according
> to their belief that a free-form, expressive language did not mesh-well
> with the types of development models you have in internet companies.

Java was not designed for this. It ended there, it's different.
At least according to Sun...
http://java.sun.com/features/1998/05/birthday.html

Marc
From: Frode Vatvedt Fjeld
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <2had8e8dlq.fsf@vserver.cs.uit.no>
Alex Martelli <·····@aleax.it> writes:

> [..] If you believe everybody can become a good language designer, I
> think the onus is on you to explain why most languages are not
> designed well.  Do remember that a vast majority of the people who
> do design languages HAVE had some -- in certain cases, VAST --
> experience with Lisp, e.g., check out the roster of designers for
> the Java language.

This argument is in my opinion invalid, for at least three reasons:

  - Designing something like the Java language is very, very different
    from designing a lisp macro.

  - Designing good functional abstractions (libraries) that are
    suitable for sharing with other programmers is also quite
    difficult. This in no way implies that the defun or equivalent
    operator should be removed.

  - That some programming language feature might be beyond some
    people's ability to use well, is not a good reason to dismiss that
    feature, at least not in my book. Of course, languages are
    designed to different ends, and I do seem to recall that one of
    Python's explicit goals is to be "the language for everybody", so
    this argument might make sense from a Python point of view.

> My thesis is that the ability to design languages well is far rarer
> than the ability to design well within more restricted confines, and
> good design is taught and learned much more easily in restricted
> realms, much less easily the broader the degrees of freedom.

This is obviously true, but in my opinion completely irrelevant to the
issue of whether macros are helpful or not.

-- 
Frode Vatvedt Fjeld
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <r7a6ov49mpbrpmb749c6m6jesuu63pg1dh@4ax.com>
On Mon, 06 Oct 2003 17:12:18 GMT, Alex Martelli <·····@aleax.it>
wrote:

>Imagine a group of, say, a dozen programmers, working together by
>typical Agile methods to develop a typical application program of
>a few tens of thousands of function points -- developing about
>100,000 new lines of delivered code plus about as much unit tests,
>and reusing roughly the same amount of code from various libraries,
>frameworks, packages and modules obtained from the net and/or from
>commercial suppliers.  Nothing mind-boggling about this scenario,
>surely -- it seems to describe a rather run-of-the-mill case.
>
>Now, clearly, _uniformity_ in the code will be to the advantage
>of the team and of the project it develops.  Extreme Programming
>makes a Principle out of this (no "code ownership"), but even if
>you don't rate it quite that highly, it's still clearly a good
>thing.  Now, you can impose _some_ coding uniformity (within laxer
>bounds set by the language) _for code originally developed by the
>team itself_ by adopting and adhering to team-specific coding
>guidelines; but when you're reusing code obtained from outside,
>and need to adopt and maintain that code, the situation is harder.
>Either having that code remain "alien", by allowing it to break
>all of your coding guidelines; or "adopting" it thoroughly by,
>in practice, rewriting it to fit your guidelines; is a serious
>negative impact on the team's productivity.

Alex, this is pure un-mitigated non-sense.  Python's Metaclasses are
far more dangerous than Macro's.  Metaclasses allow you to globally
change the underlying semantics of a program.  Macros only allow you
to locally change the Syntax.  Your comparison is spurious at best.

Your argument simply shows a serious mis-understanding of Macros.
Macros as has been stated to you *many* times are similar to
functions.  They allow a certain type of abstraction to remove
extraneous code.

Based on your example you should be fully campaigning against
Metaclasses, FP constructs in python and Functions as first class
objects.  All of these things add complexity to a given program,
however they also reduce the total number of lines.  Reducing program
length is to date the only effective method I have seen of reducing
complexity.

If you truly believe what you are saying, you really should be
programming in Java.  Everything is explicit, and most if not all of
these powerful constructs have been eschewed, because programmers are
just too dumb to use them effectively.


Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <T4Vgb.247129$R32.7987601@news2.tin.it>
Doug Tolton wrote:
   ...
> Alex, this is pure un-mitigated non-sense.

Why, thanks!  Nice to see that I'm getting on the nerves of _some_
people, too, not just having them get on mine.

> Python's Metaclasses are
> far more dangerous than Macro's.  Metaclasses allow you to globally
> change the underlying semantics of a program.

Nope: a metaclass only affects (part of the semantics of) the
classes that instantiate it.  No "globally" about it.  When I
write a class I can explicity control what metaclass it uses,
or inherit it.  E.g., by writing 'class My(object):', with no
explicit metaclass, I ensure type(my)==type(object).  The type
of the built-in named 'object' is the built-in named 'type'
(which most custom metaclasses subclass), which is also the
type of most other built-in types (numbers, strings, list,
tuple, dict, functions, methods, module, file, ...).  I.e.,
your assertion is pure un-mitigated FUD.

> Macros only allow you
> to locally change the Syntax.

"Locally"?  Not globally?  Care to explain?  Each 'invocation'
(expansion) of a macro must occur in a particular locus, sure,
but isn't the _point_ of (e.g.) defining a 'loop-my-way' macro
that every occurrence of 'loop-my-way' is such an expansion?

As for that mention of "the Syntax" AS IF somehow contrasted
with the "underlying semantics" just before, don't even bother
to try explaining: one example of macros' wonders offered by a 
particularly vocal and emotional advocate was a macro
'with-condition-maintained' that was somehow supposed to make
whatever alterations might be needed in the control program of
a reactor in order to regulate temperature -- and it was
passed that code as three calls to functions (or expansions
of macros) NOT defined inside it, so how it could possibly
work "only...locally", when to do anything at all it MUST
necessarily find, "expand", and alter the local instantiations
of those functions (or macros)...?!

If that's an example of "only allow you to locally change
the syntax", what would be an example of *EVEN DEEPER
AND MORE PERVASIVE* changes ?!

> Your comparison is spurious at best.

What "my comparison" are you blabbering about?  My text that
you quoted, and called "pure un-mitigated non-sense", had no
"comparisons", neither my own nor others'.  I see YOU attempting
to draw some "comparison" (eminently spurious, to be sure) 
between metaclasses and macros...


> Your argument simply shows a serious mis-understanding of Macros.
> Macros as has been stated to you *many* times are similar to
> functions.  They allow a certain type of abstraction to remove
> extraneous code.

Yeah, right.  Kindly explain that 'with-condition-maintained'
example and the exhalted claims made and implied for it, then.


> Based on your example you should be fully campaigning against
> Metaclasses, FP constructs in python and Functions as first class
> objects.  All of these things add complexity to a given program,

"FUD" and "nonsense" (with or without a hyphen) would be serious
understatements in an attempt to characterize *THIS*.  *HOW* do
"functions as first class objects" perform this devilish task of
"adding complexity to a given program", for example?!  The extra
complexity would be in rules trying to FORBID normal usage of an
object (passing as argument, returning as value, appending to a
list, ...) based on the object's type.  There is obviously no
complexity in saying "_WHATEVER_ x happens to stand for, you
can correctly call somelist.append(x)" [passing x as argument to
a method of the somelist which appends x to the list], for example.
The added complexity would come if you had to qualify this with
"UNLESS ..." for whatever value of ``...''.

> however they also reduce the total number of lines.  Reducing program
> length is to date the only effective method I have seen of reducing
> complexity.

For some (handwaving-defined) "appropriate" approach to measuring
"length" (and number of lines is most definitely not it), it is ONE
important way.  But you're missing another crucial one, which is
the count of interactions, actual and potential, between "parts"
of the program -- the key reason why global effects do not in fact
effectively reduce complexity, but rather bid fair to increase it,
even though they might often "reduce the total [[length]]", is
exactly this.  E.g., if large parts of my program needed all kinds
of comparisons between strings (including comparison-related
functionality such as hashing) to be case-insensitive, it might
make my program 'shorter' if I could set case insensitivity as
the global default -- but it might easily mess up totally unrelated
and otherwise stable modules that rely on the usual case sensitive
operations, causing weird, hard-to-trace malfunctionings.  I've
mentioned my youthful APL experiences: with its quad-IO to globally
set index origin for arrays, and its quad-I forget what to globally
set comparison tolerance in all comparisons between floating point
numbers, APL was a prime example of this (among other things,
reusability-destroying) global-effects risk.  Sure, it was cool
and made my program shorter to be able to check if "a < b" and
have this IMPLICITLY mean "to within N significant digits" (or
whatever) -- but it regularly broke other otherwise-stable modules
and thus destroyed reuse.  Not to mention the mind-boggling effects
when a<b, a>b and a=b can ALL be 'true' at once thanks to the
"to within N significant digits" IMPLICIT proviso...

Complexity is not just program length, and reducing program length
not the only important thing in reducing complexity.  Removing
*repetition* (boilerplate), sure, that's nice -- and if there was
a way to constrain macros to ONLY do that (as opposed to ending up
with examples such as 'with-condition-maintained', see above) I
would be very interested in seeing it.  I doubt there is one, though.


> If you truly believe what you are saying, you really should be
> programming in Java.  Everything is explicit, and most if not all of

Hmmm, one wonders -- are you a liar, or so totally ignorant of what
you're talking about that you don't even KNOW that one of Java's
most "cherished" features is that the "self." is just about ALWAYS
implicit...?  Anyway, in my text which you quoted and characterized
as "pure un-mitigated non-sense" I was speaking of UNIFORMITY as
a plus -- and Java's use of { } for example ensures NON-uniformity
on a lexical plane, since everybody has different ideas about where
braces should go:-).

But I've NEVER argued in favour of boilerplate, of repetitiousness.
I think that the occasional error that you can catch by forcing
redundancy is generally outweighed by all the errors that just
would not be there if the language let me state things "once, and
only once".  So, for example, when I write
    x = 23
I most definitely don't WANT to have to redundantly state that,
by the way, there is a variable x, and, whaddyaknow, x refers
to an integer.  As to whether it makes more sense to later let
the same name x in the same scope refer to OTHER objects (of
the same type; or, of any type) -- I still don't know; maybe
a single-assignment kind of functional language would in fact be
preferable, or maybe Python's relaxed attitude about re-bindings
is best, or maybe something in-between, allowing re-bindings but
only within a single type's items (for "re-bindings" you may
choose to read "assignments" if you wish, I'm not trying to
reopen THAT particular lexical flamewar for further debate;-).

So far, I'm pretty happy with Python's permissive approach to
mutation and re-binding, but I notice I don't mind (differently
from many others) the inability to re-bind SOME references
(e.g., items of tuples, or lexically-outer names) -- and in
Haskell or ML I don't recall ever feeling confined by the
inability to have the same name refer to different values at
successive times (in the same scope).  [I _do_ recall some
unease at being unable to mutate "large" data structures, as
opposed to rebinding simple names, so it's not as if I can
claim any natural affinity for the functional [immutable-data]
approach to programming -- I just wonder if perhaps the current
widespread _emphasis_ on rebinding and mutation may not be a
TAD overdone -- but, enough for this aside].

I do, of course, truly believe in what I'm saying -- what
WOULD have stopped me from taking up any of a zillion different
languages, instead of Python, when I started studying it
about four years ago?  Indeed, my opportunities for making
money, and the audience for my books, would be vaster if I
had stuck with what I was mainly using at work then (mostly C++,
some Java, VB, Perl), my academic respectability higher if I
had stuck with Haskell or some ML.  But while I don't mind
money, nor fans, I care most about other values -- and the
amount to which "Python fits my brain" and makes me most
comfortable and productive meets and exceeds all claims I had
heard to this effect, PLUS, I have experiential proof (enough
to convince me personally, if nobody else:-) that it's just
as comfortable and productive for many others, from programming
newbies to highly experienced professionals.  Sure, Java would
let me program my cellphone (which currently doesn't support
Python) -- oh well, I'll have to eschew that crucial pursuit
for a while longer now...


Alex
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ml88ov4l6etrnaklj7jpsofk7lr94seddj@4ax.com>
On Wed, 08 Oct 2003 14:22:43 GMT, Alex Martelli <·····@aleax.it>
wrote:

>Doug Tolton wrote:
>   ...
>> Alex, this is pure un-mitigated non-sense.
>
>Why, thanks!  Nice to see that I'm getting on the nerves of _some_
>people, too, not just having them get on mine.

Yes, this discussion is frustrating.  It's deeply frustrating to hear
someone without extensive experience with Macros arguing why they are
so destructive.  Particularly to hear the claim the Macros make it
impossible to have large teams work on a project, and at the same time
supporting features in python that make it far more difficult to share
code between people.  (ie, white space delimiting, the ability to
rebind interenals, Metaclasses).  Personally I'm not against any of
these features, however they all suffer from serious potential
drawbacks.
>
>> Python's Metaclasses are
>> far more dangerous than Macro's.  Metaclasses allow you to globally
>> change the underlying semantics of a program.
>
>Nope: a metaclass only affects (part of the semantics of) the
>classes that instantiate it.  No "globally" about it.  When I
>write a class I can explicity control what metaclass it uses,
>or inherit it.  E.g., by writing 'class My(object):', with no
>explicit metaclass, I ensure type(my)==type(object).  The type
>of the built-in named 'object' is the built-in named 'type'
>(which most custom metaclasses subclass), which is also the
>type of most other built-in types (numbers, strings, list,
>tuple, dict, functions, methods, module, file, ...).  I.e.,
>your assertion is pure un-mitigated FUD.
>
Please explain to me how according to your logic, a semantic change to
the language is good, but a syntactic change is bad.  Your logic is
extremely confusing to me.  On the one hand you think Macro's are bad
because I can define a construct such as 
(do-something-useful-here
	arg1
	arg2
	arg3)
which operates according to all the regular semantic rules.  In fact
there is even an explicit construct that will show me *exactly* what
this code is doing.  Yet you apparently think using Metaclasses to
change the underlying semantics is somehow ok, because you can check
to see if it's built-in?  So are you saying that using only built-in
constructs are good to use?  If someone else gives you a class to use
which uses Metaclasses to change how it operates for some reason or
another, are you ok with that?  What if they need to re-bind some of
the builtins to do something? Because you can't prevent that in python
either.  In fact any piece of python code that runs on your system
could do that, yet you are ok with that?

>> Macros only allow you
>> to locally change the Syntax.
>
>"Locally"?  Not globally?  Care to explain?  Each 'invocation'
>(expansion) of a macro must occur in a particular locus, sure,
>but isn't the _point_ of (e.g.) defining a 'loop-my-way' macro
>that every occurrence of 'loop-my-way' is such an expansion?
yes, but the point is that if I just wrote 'loop-my-way', it doesn't
change existant code in unexpected ways.  It only affects new code
that is written using 'loop-my-way'.  Whereas re-binding the buildins
*will* change existant code.
>
>As for that mention of "the Syntax" AS IF somehow contrasted
>with the "underlying semantics" just before, don't even bother
>to try explaining: one example of macros' wonders offered by a 
>particularly vocal and emotional advocate was a macro
>'with-condition-maintained' that was somehow supposed to make
>whatever alterations might be needed in the control program of
>a reactor in order to regulate temperature -- and it was
>passed that code as three calls to functions (or expansions
>of macros) NOT defined inside it, so how it could possibly
>work "only...locally", when to do anything at all it MUST
>necessarily find, "expand", and alter the local instantiations
>of those functions (or macros)...?!
>
I'm not going to attempt to explain with-condition-maintained, as you
are clearly ignoring the general idea in favor of nitpicking
non-essential details of a hypothetical construct.  When you descend
to the statements you have made about that construct, it's no longer
worth continuing discussion of it.

That's my exact problem though, your statements continually brand you
as ignorant of what macros are and how they operate on a fundamental
level, yet for some reason you feel qualified to extol their evils as
if you actually have significant experience with them.

>If that's an example of "only allow you to locally change
>the syntax", what would be an example of *EVEN DEEPER
>AND MORE PERVASIVE* changes ?!
>
No idea what you are talking about here.

>> Your comparison is spurious at best.
>
>What "my comparison" are you blabbering about?  My text that
>you quoted, and called "pure un-mitigated non-sense", had no
>"comparisons", neither my own nor others'.  I see YOU attempting
>to draw some "comparison" (eminently spurious, to be sure) 
>between metaclasses and macros...
The only reason you think it's spurious is because of your
fundamentally flawed conception of Macros.
>
>
>> Your argument simply shows a serious mis-understanding of Macros.
>> Macros as has been stated to you *many* times are similar to
>> functions.  They allow a certain type of abstraction to remove
>> extraneous code.
>
>Yeah, right.  Kindly explain that 'with-condition-maintained'
>example and the exhalted claims made and implied for it, then.
I thought you didn't want it explained to you?  If you are serious
about wanting to know what the *point* of the code snippet was, then
I'll explain it.  If on the other hand you are going to make some
ridiculous argument about how with-condition-maintained isn't in fact
hooked to any control room circuitry, then forget it.
>
>
>> Based on your example you should be fully campaigning against
>> Metaclasses, FP constructs in python and Functions as first class
>> objects.  All of these things add complexity to a given program,
>
>"FUD" and "nonsense" (with or without a hyphen) would be serious
>understatements in an attempt to characterize *THIS*.  *HOW* do
>"functions as first class objects" perform this devilish task of
>"adding complexity to a given program", for example?!  The extra
>complexity would be in rules trying to FORBID normal usage of an
>object (passing as argument, returning as value, appending to a
>list, ...) based on the object's type.  There is obviously no
>complexity in saying "_WHATEVER_ x happens to stand for, you
>can correctly call somelist.append(x)" [passing x as argument to
>a method of the somelist which appends x to the list], for example.
>The added complexity would come if you had to qualify this with
>"UNLESS ..." for whatever value of ``...''.
>
Hmm...what if using a class with Metaclasses behaves in a totally
non-standard way?  What if a function re-binds the builtins?  What if
they over use FP constucts and nest 50 maps and filters?  Are you ok
with all of these things?  They are certainly more confusing than
Macros.  To make the statement that *any* technology can't be abused
is foolish.  To make that claim implies there is no correct usage,
only usage.  In other words if there is no correct way to use
Metaclasses or re-bind builtins then any way that someone sees fit to
do it *is* the right way.  We all know that is a ridiculous claim.
Macros are like any other sufficiently powerful technology.  If they
aren't used right, they will complicate a program not simplify it.

I believe the crux of our difference is that you don't want to give
expressive power because you believe it will be misused.  I on the
other hand want to give expressive power because I believe it could be
used correctly most of the time.  For the times when it's not, well
that's why I have debugging skills.  Sadly not eveyone uses looping
the way I would, but using my brain I can figure out what they are
doing.
>> however they also reduce the total number of lines.  Reducing program
>> length is to date the only effective method I have seen of reducing
>> complexity.
>
>For some (handwaving-defined) "appropriate" approach to measuring
>"length" (and number of lines is most definitely not it), it is ONE

Both from my experience and Fred Brooks it's the only actual way I've
seen of measuring the time it will take to write a program.

>important way.  But you're missing another crucial one, which is
>the count of interactions, actual and potential, between "parts"
>of the program -- the key reason why global effects do not in fact
>effectively reduce complexity, but rather bid fair to increase it,
>even though they might often "reduce the total [[length]]", is
>exactly this. 

I understand this point very well.  That's why I believe in building
layered software, and using good high order constructs to acheive
this.  As I've said before, your statements reveal your fundamental
mis-understanding of the way Macro's work.  To support Metaclasses,
classes, functions, first order functions etc as tools to support this
concept while at the same time reviling macros is simply showing an
un-educated bias about Macros.  I wouldn't be suprised to hear you
respond with some argument about how you've read the writings by
people who have used Macros (as you've done in the past), but I
believe you do not have sufficient understanding to make the claims
you are making.  If you really understood macros, I don't believe you
would be making such statements.

> E.g., if large parts of my program needed all kinds
>of comparisons between strings (including comparison-related
>functionality such as hashing) to be case-insensitive, it might
>make my program 'shorter' if I could set case insensitivity as
>the global default -- but it might easily mess up totally unrelated
>and otherwise stable modules that rely on the usual case sensitive
>operations, causing weird, hard-to-trace malfunctionings.  I've
>mentioned my youthful APL experiences: with its quad-IO to globally
>set index origin for arrays, and its quad-I forget what to globally
>set comparison tolerance in all comparisons between floating point
>numbers, APL was a prime example of this (among other things,
>reusability-destroying) global-effects risk.  Sure, it was cool
>and made my program shorter to be able to check if "a < b" and
>have this IMPLICITLY mean "to within N significant digits" (or
>whatever) -- but it regularly broke other otherwise-stable modules
>and thus destroyed reuse.  Not to mention the mind-boggling effects
>when a<b, a>b and a=b can ALL be 'true' at once thanks to the
>"to within N significant digits" IMPLICIT proviso...
>

Well that was a long winded digression into something that is
completely un-related to Macros.  Seems like a good argument why
re-binding the buildins is bad though
.
>Complexity is not just program length, and reducing program length
>not the only important thing in reducing complexity.  Removing
>*repetition* (boilerplate), sure, that's nice -- and if there was
>a way to constrain macros to ONLY do that (as opposed to ending up
>with examples such as 'with-condition-maintained', see above) I
>would be very interested in seeing it.  I doubt there is one, though.
>
I agree that reducing complexity is the goal.  I disagree that you can
*ever* guarantee a high order construct is always used correctly
though.
>
>> If you truly believe what you are saying, you really should be
>> programming in Java.  Everything is explicit, and most if not all of
>
>Hmmm, one wonders -- are you a liar, or so totally ignorant of what
>you're talking about that you don't even KNOW that one of Java's
>most "cherished" features is that the "self." is just about ALWAYS
>implicit...?  Anyway, in my text which you quoted and characterized
>as "pure un-mitigated non-sense" I was speaking of UNIFORMITY as
>a plus -- and Java's use of { } for example ensures NON-uniformity
>on a lexical plane, since everybody has different ideas about where
>braces should go:-).
>
Where braces should go is a trivial issues.  However if braces is an
issue that seriously concerns you then I can see why macros are giving
you a heart attack.

>But I've NEVER argued in favour of boilerplate, of repetitiousness.
>I think that the occasional error that you can catch by forcing
>redundancy is generally outweighed by all the errors that just
>would not be there if the language let me state things "once, and
>only once".  So, for example, when I write
>    x = 23
>I most definitely don't WANT to have to redundantly state that,
>by the way, there is a variable x, and, whaddyaknow, x refers
>to an integer.  As to whether it makes more sense to later let
>the same name x in the same scope refer to OTHER objects (of
>the same type; or, of any type) -- I still don't know; maybe
>a single-assignment kind of functional language would in fact be
>preferable, or maybe Python's relaxed attitude about re-bindings
>is best, or maybe something in-between, allowing re-bindings but
>only within a single type's items (for "re-bindings" you may
>choose to read "assignments" if you wish, I'm not trying to
>reopen THAT particular lexical flamewar for further debate;-).
>
>So far, I'm pretty happy with Python's permissive approach to
>mutation and re-binding, but I notice I don't mind (differently
>from many others) the inability to re-bind SOME references
>(e.g., items of tuples, or lexically-outer names) -- and in
>Haskell or ML I don't recall ever feeling confined by the
>inability to have the same name refer to different values at
>successive times (in the same scope).  [I _do_ recall some
>unease at being unable to mutate "large" data structures, as
>opposed to rebinding simple names, so it's not as if I can
>claim any natural affinity for the functional [immutable-data]
>approach to programming -- I just wonder if perhaps the current
>widespread _emphasis_ on rebinding and mutation may not be a
>TAD overdone -- but, enough for this aside].
>
>I do, of course, truly believe in what I'm saying -- what
>WOULD have stopped me from taking up any of a zillion different
>languages, instead of Python, when I started studying it
>about four years ago?  Indeed, my opportunities for making
>money, and the audience for my books, would be vaster if I
>had stuck with what I was mainly using at work then (mostly C++,
>some Java, VB, Perl), my academic respectability higher if I
>had stuck with Haskell or some ML.  But while I don't mind
>money, nor fans, I care most about other values -- and the
>amount to which "Python fits my brain" and makes me most
>comfortable and productive meets and exceeds all claims I had
>heard to this effect, PLUS, I have experiential proof (enough
>to convince me personally, if nobody else:-) that it's just
>as comfortable and productive for many others, from programming
>newbies to highly experienced professionals.  Sure, Java would
>let me program my cellphone (which currently doesn't support
>Python) -- oh well, I'll have to eschew that crucial pursuit
>for a while longer now...
>
>
The ironic thing is that I'm not bashing Python.  I really like
python.  It's a great language.  I think we both use Python and Lisp
(for me) for the same reasons.  If I wanted a higher paying job I'd be
using Java.  I have aspirations to write books as well, I agree that
Python and Lisp aren't the biggest markets, and yet I use them because
they fit my brain also.

What I am in point of fact upset by is your constant barrage against
Macros.  I feel that your stance is based on ignorance and
mis-information.  You certainly don't have significant first hand
exposure to Lisp style Macros or you wouldn't be making statements
that were so obviously incorrect.  Why don't you seriously try to
learn them?  If you don't care to, why argue about them so much?  I
haven't seen anyone bring up (I could've missed it) putting Macro's
into Python again.  I personally don't think Macros would work very
well in Python, at least not as well as they do in Lisp.  So
understanding that I'm not pushing for Macro's in python, why are you
so vehement against them?  Are you on campaign to get Macros out of
Lisp?

Doug
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwqbktm63seq94@news.nscp.aoltw.net>
On Wed, 08 Oct 2003 15:31:21 GMT, Doug Tolton <····@nospam.com> wrote:
> On Wed, 08 Oct 2003 14:22:43 GMT, Alex Martelli <·····@aleax.it>
>> Doug Tolton wrote:
>> ...
>>> Alex, this is pure un-mitigated non-sense.
>>
>> Why, thanks!  Nice to see that I'm getting on the nerves of _some_
>> people, too, not just having them get on mine.
>
> Yes, this discussion is frustrating.  It's deeply frustrating to hear
> someone without extensive experience with Macros arguing why they are
> so destructive.

You know I think that this thread has so far set a comp.lang.* record for 
civilitiy in the face of a massively cross-posted language comparison 
thread. I was even wondering if it was going to die a quiet death, too.

Ah well, We all knew it was too good to last. Have at it, lads!

Common Lisp is an ugly language that is impossible to understand with 
crufty semantics

Scheme is only used by ivory-tower academics and is irerelevant to real 
world programming

Python is a religion that worships at the feet of Guido vanRossum
combining the syntactic flaws of lisp with a bad case of feeping 
creaturisms taken from languages more civilized than itself

There. Is everyone pissed off now?

david rush
-- 
Taking bets on how many more messages before Godwin's law kicks in...
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3ce3cvhz.fsf@ccs.neu.edu>
David Rush <·····@aol.net> writes:

> You know I think that this thread has so far set a comp.lang.* record
> for civilitiy in the face of a massively cross-posted language
> comparison thread. I was even wondering if it was going to die a quiet
> death, too.
>
> Ah well, We all knew it was too good to last. Have at it, lads!
>
> Common Lisp is an ugly language that is impossible to understand with
> crufty semantics
>
> Scheme is only used by ivory-tower academics and is irerelevant to
> real world programming
>
> Python is a religion that worships at the feet of Guido vanRossum
> combining the syntactic flaws of lisp with a bad case of feeping
> creaturisms taken from languages more civilized than itself
>
> There. Is everyone pissed off now?

No, that seems about right.
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm224f$gk$0@216.39.172.122>
On Wed, 08 Oct 2003 16:41:44 -0400, Joe Marshall <···@ccs.neu.edu> wrote:

>David Rush <·····@aol.net> writes:
>
>> You know I think that this thread has so far set a comp.lang.* record
>> for civilitiy in the face of a massively cross-posted language
>> comparison thread. I was even wondering if it was going to die a quiet
>> death, too.
>>
>> Ah well, We all knew it was too good to last. Have at it, lads!
>>
>> Common Lisp is an ugly language that is impossible to understand with
>> crufty semantics
>>
>> Scheme is only used by ivory-tower academics and is irerelevant to
>> real world programming
>>
>> Python is a religion that worships at the feet of Guido vanRossum
>> combining the syntactic flaws of lisp with a bad case of feeping
>> creaturisms taken from languages more civilized than itself
>>
>> There. Is everyone pissed off now?
>
>No, that seems about right.
LOL ;-)

Regards,
Bengt Richter
From: Karl A. Krueger
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm21am$l4m$1@baldur.whoi.edu>
In comp.lang.lisp David Rush <·····@aol.net> wrote:
> Ah well, We all knew it was too good to last. Have at it, lads!
> 
> Common Lisp is an ugly language that is impossible to understand with 
> crufty semantics
> 
> Scheme is only used by ivory-tower academics and is irerelevant to real 
> world programming
> 
> Python is a religion that worships at the feet of Guido vanRossum
> combining the syntactic flaws of lisp with a bad case of feeping 
> creaturisms taken from languages more civilized than itself
> 
> There. Is everyone pissed off now?

This seems like a good juncture to post my list of common myths and
misconceptions about popular programming languages.  Contributions are
welcome; flames only if they're funny.  Anyone who needs to see :) on
things to know they're meant in jest should stop reading now.


		    == Programming Language Myths ==

BASIC Myth:  People who learn BASIC go on to learn other languages.
Reality:  Most people who learn BASIC go on to find less nerdy ways of
          writing "Mr. Gzabowski is a lame teacher" over and over again.

C Myth:  C programs are insecure, full of buffer overflows and such.
Reality:  C programs are only insecure if written by imperfect programmers.
          Since all C programmers know that they are perfect, there's no
          problem.

COBOL Myth:  COBOL is dead.
Reality:  It stalks from out the ancient vaults of death, its putrid mind
          drawn to the blood of the living.

Forth Myth:  Forth makes no sense.
Reality:  backwards. think to have just you sense, perfect makes Forth

Java Myth:  You need Java to do business applications.
Reality:  You need Java to get a job.

Lisp Myth:  Lisp is an interpreted language.
Reality:  Lisp is COMPILED DAMMIT COMPILED!  IT'S IN THE FUCKING STANDARD!!!

Pascal Myth:  Pascal is a toy.
Reality:  Oh, wait, that is not a myth, it is true ...

Perl Myth:  Perl is impossible to read.
Reality:  You are not taking enough psychedelics.

Python Myth:  Python's only problem is the whitespace thing.
Reality:  Python's only problem is that it is fucking slow.  

-- 
Karl A. Krueger <········@example.edu>
Woods Hole Oceanographic Institution
Email address is spamtrapped.  s/example/whoi/
"Outlook not so good." -- Magic 8-Ball Software Reviews
From: Dave Benjamin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <YK0hb.109$_f.55@news1.central.cox.net>
Karl A. Krueger wrote:

> This seems like a good juncture to post my list of common myths and
> misconceptions about popular programming languages.  Contributions are
> welcome; flames only if they're funny.  Anyone who needs to see :) on
> things to know they're meant in jest should stop reading now.

Haha... that's really funny... except the last one. Not that I'm a 
Python purist (a big fan, yes, but not a purist), but I rarely complain 
about its slowness. Java is too easy of a target for that one... =)

Python Myth:  Python's only problem is the whitespace thing.
Reality:  Python's only problem is that it is not Common Lisp.

How about that?

Dave
From: Karl A. Krueger
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm29a2$o03$1@baldur.whoi.edu>
In comp.lang.lisp Dave Benjamin <····@3dex.com> wrote:
> Karl A. Krueger wrote:
>> This seems like a good juncture to post my list of common myths and
>> misconceptions about popular programming languages.  Contributions are
>> welcome; flames only if they're funny.  Anyone who needs to see :) on
>> things to know they're meant in jest should stop reading now.
> 
> Haha... that's really funny... except the last one. Not that I'm a 
> Python purist (a big fan, yes, but not a purist), but I rarely complain 
> about its slowness. Java is too easy of a target for that one... =)

*laugh*  I use Python more often in my job than I use Lisp, Perl, or any
other language, except possibly the Unix shell.  It really is not among
the speedier ones for a lot of tasks.  (Neither is Java, but I have
thankfully avoided having to do any real work in Java.)  Python's
strength, for the kind of projects I work on in it, is its regularity
and the extensive standard library for things like talking to network
applications.

I moved to Python for such things from Perl, after realizing that I
really did not want to implement a database-backed application in a
language that required messy explicit dereferencing when dealing with
complex data structures.  I'd much rather deal with a list of lists of
tuples than a list of references to lists of references to tuples,
getting back things like "ARRAY<#fhqwhgads>" when I missed a dereference
character.

But you're taking my list of myths too seriously.  Not all C programs
are riddled with security bugs either.  :)

Incidentally, I regard objections to "the whitespace thing" in Python
and objections to "the parenthesis thing" in Lisp as more or less the
same.  People who raise these objections are usually just saying "Ick!
This looks so unfamiliar to me!" in the language of rationalizations.
I guess a philosopher would say that I am an emotivist about notation
criticisms.

-- 
Karl A. Krueger <········@example.edu>
Woods Hole Oceanographic Institution
Email address is spamtrapped.  s/example/whoi/
"Outlook not so good." -- Magic 8-Ball Software Reviews
From: Ingvar Mattsson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87k77ekb94.fsf@gruk.tech.ensign.ftech.net>
"Karl A. Krueger" <········@example.edu> writes:

[SNIP]
> Incidentally, I regard objections to "the whitespace thing" in Python
> and objections to "the parenthesis thing" in Lisp as more or less the
> same.  People who raise these objections are usually just saying "Ick!
> This looks so unfamiliar to me!" in the language of rationalizations.
> I guess a philosopher would say that I am an emotivist about notation
> criticisms.

My main problem with "indentation controls scoping" is taht I've
actually had production python code die because of whitespace being
mangled in cutting&pasting between various things. It looks a bit odd,
but after having written BASIC, Pascal, APL, Forth, PostScript, Lisp,
C and Intercal looking "odd" only requires looking harder. Killing a
production system due to whitespace-mangling isn't.

And, yes, I probably write more Python code than lisp code in an
average week.

//Ingvar
-- 
Ingvar Mattsson; ······@hexapodia.net;
You can get further with a kind word and a 2x4
than you can with just a kind word.             Among others, Marcus Cole
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87llrvs4yw.fsf@bird.agharta.de>
On Wed, 08 Oct 2003 23:05:28 GMT, Dave Benjamin <····@3dex.com> wrote:

> Python Myth:  Python's only problem is the whitespace thing.
> Reality:  Python's only problem is that it is not Common Lisp.
> 
> How about that?

A good one... :)

Edi.
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <rq1hb.59488$nU6.10037081@twister.nyc.rr.com>
Edi Weitz wrote:

> On Wed, 08 Oct 2003 23:05:28 GMT, Dave Benjamin <····@3dex.com> wrote:
> 
> 
>>Python Myth:  Python's only problem is the whitespace thing.
>>Reality:  Python's only problem is that it is not Common Lisp.
>>
>>How about that?
> 
> 
> A good one... :)

I think Python's problem is its success. Whenever something is 
succesful, the first thing people want is more features. Hell, that is 
how you know it is a success. The BDFL still talks about simplicity, but 
that is history. GvR, IMHO, should chased wish-listers away with "use 
Lisp" and kept his gem small and simple.


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Paul Rubin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7xu16jmf57.fsf@ruckus.brouhaha.com>
Kenny Tilton <·······@nyc.rr.com> writes:
> I think Python's problem is its success. Whenever something is
> succesful, the first thing people want is more features. Hell, that is
> how you know it is a success. The BDFL still talks about simplicity,
> but that is history. GvR, IMHO, should chased wish-listers away with
> "use Lisp" and kept his gem small and simple.

That's silly.  Something being successful means people want to use it
to get things done in the real world.  At that point they start
needing the tools that other languages provide for dealing with the
real world.  The real world is not a small and simple place, and small
simple systems are not always enough to cope with it.  If GVR had kept
his gem small and simple, it would have remained an academic toy, and
I think he had wide-reaching ambitions than that.
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <uZjhb.27673$pv6.9360@twister.nyc.rr.com>
Paul Rubin wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
>>I think Python's problem is its success. Whenever something is
>>succesful, the first thing people want is more features. Hell, that is
>>how you know it is a success. The BDFL still talks about simplicity,
>>but that is history. GvR, IMHO, should chased wish-listers away with
>>"use Lisp" and kept his gem small and simple.
> 
> 
> That's silly.  Something being successful means people want to use it
> to get things done in the real world.  At that point they start
> needing the tools that other languages provide for dealing with the
> real world.  The real world is not a small and simple place, and small
> simple systems are not always enough to cope with it.  If GVR had kept
> his gem small and simple, it would have remained an academic toy, and
> I think he had wide-reaching ambitions than that.

I agree with everything you said except that last bit, and I only 
disagree with that because of what I have heard from Pythonistas, so 
maybe I missed something. I did not think Python (or GVR or both) had 
aspirations of being a full-blown language vs just being a powerful 
scripting language.

Do they ever plan to do a compiler for it?

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Lulu of the Lotus-Eaters
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065735324.2880.python-list@python.org>
Kenny Tilton <·······@nyc.rr.com> wrote previously:
|Do they ever plan to do a compiler for it [Python]?

You mean like Psyco?

Been there, done that. (and it's great, and getting better).

--
·····@  | The specter of free information is haunting the `Net!  All the
gnosis  | powers of IP- and crypto-tyranny have entered into an unholy
.cx     | alliance...ideas have nothing to lose but their chains.  Unite
        | against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Jsmhb.27968$pv6.19754@twister.nyc.rr.com>
Lulu of the Lotus-Eaters wrote:

> Kenny Tilton <·······@nyc.rr.com> wrote previously:
> |Do they ever plan to do a compiler for it [Python]?
> 
> You mean like Psyco?
> 
> Been there, done that. (and it's great, and getting better).

Oh, excellent name. OK, the context was "what are Python's aspirations?" 
. Is Python now no longer content to be a (very powerful) scripting 
language? Or is it just tired of being ragged on for being slow?

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Lulu of the Lotus-Eaters
Subject: The compiler canard
Date: 
Message-ID: <mailman.1065749602.12438.python-list@python.org>
|> |Do they ever plan to do a compiler for it [Python]?
|> You mean like Psyco?

Kenny Tilton <·······@nyc.rr.com> wrote previously:
|Oh, excellent name.  OK, the context was "what are Python's
|aspirations?"  Is Python now no longer content to be a (very powerful)
|scripting language?  Or is it just tired of being ragged on for being
|slow?

Python never had an "aspiration" of being "just a scripting language",
nor WAS it ever such a thing.  From its release, Python was obviously a
language very well suited to large scale application development (as
well as to short one-off scripts).

There -is- sometimes a misguided allegation that Python is slow.  It's
not.  Certainly Python is faster than most of the languages with
commercial backers who make such claims (e.g.  Java, VB).  But indeed,
for a class of applications, pure Python is not a good choice--for
long-running, complex, scientific calculation, Fortran or C are much
better (becaue they run many times faster).

There are several approaches, however, to making applications written
mostly in Python faster (in the fairly unusual case that it needs to be
faster).  One is to use extension modules--usually coded in C--to handle
the bottlenecks.  Y'know, 90% of program time spent in 10% of the code,
or whatever--rewrite that 10% in C. Numerical Python is a widely used
example of this approach.

A second approach is similar:  You can use Pyrex to write these
extension modules in a language that is *almost* Python.  While Pyrex
syntax is close to Python, under-the-hood, it acts like a code generator
for C... so in the end, you still get an extension module.

A third approach is the simplest of all (for the end programmer, not for
Armin Rigo :-)):  Use the Python Specializing Compiler (Psyco).  Psyco
is a cool tool to dynamically generator x86 assembly for code paths in
Python bytecodes.  Basically, the same thing as a JIT/HotSpot
environment for Java (there are some differences in exactly how it
works, but from 30,000 feet it's the same idea).  Of course, no one has
ported Psyco to my Macs yet... but using it on my PCs amounts to adding
less than a half dozen (boilerplate) lines to my existing applications,
and speeds up many applications by 5-10x.

Even with the ease of Psyco, I only bother adding it to maybe 5% of the
apps I write.  My 3 year old CPU runs faster than I generally need for
most pure-Python tasks.  Sure, maybe I could speed up some command-line
tool that runs in 5 seconds so that they only take 1 second--but it's
quite rare that I care.  And all the apps that mostly wait on sockets,
keystrokes, etc. just couldn't go any faster either way, since the
constraint is external.

Yours, Lulu...

--
·····@  | The specter of free information is haunting the `Net!  All the
gnosis  | powers of IP- and crypto-tyranny have entered into an unholy
.cx     | alliance...ideas have nothing to lose but their chains.  Unite
        | against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------
From: Kenny Tilton
Subject: Re: The compiler canard
Date: 
Message-ID: <5wohb.28483$pv6.8846@twister.nyc.rr.com>
Lulu of the Lotus-Eaters wrote:

> |> |Do they ever plan to do a compiler for it [Python]?
> |> You mean like Psyco?
> 
> Kenny Tilton <·······@nyc.rr.com> wrote previously:
> |Oh, excellent name.  OK, the context was "what are Python's
> |aspirations?"  Is Python now no longer content to be a (very powerful)
> |scripting language?  Or is it just tired of being ragged on for being
> |slow?
> 
> Python never had an "aspiration" of being "just a scripting language",
> nor WAS it ever such a thing.  From its release, Python was obviously a
> language very well suited to large scale application development 

Oh. Well then you better add macros. <g>

(as
> well as to short one-off scripts).
> 
> There -is- sometimes a misguided allegation that Python is slow. 

Welcome to the club. :)

kenny

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Alex Martelli
Subject: Re: The compiler canard
Date: 
Message-ID: <qvBhb.195642$hE5.6615822@news1.tin.it>
Lulu of the Lotus-Eaters wrote:
   ...
> Python never had an "aspiration" of being "just a scripting language",

Hmmm, at the start it sure seemed like that.  Check out 

http://www.python.org/search/hypermail/python-1992/0001.html

actually from late '91.  By 1991 Guido was already calling Pyhton
"a prototyping language" and "a programming language" (so, the
"just a scripting language" was perhaps only accurate in 1990), but
in late '91 he still wrote:

"""
The one thing that Python definitely does not want to be is a GENERAL
purpose programming language. Its lack of declarations and general laziness
about compile-time checking is definitely aimed at small-to-medium-sized
programs.
"""

Apparently, it took us (collectively speaking) quite a while to realize
that the lack of declarations and compile-time checks aren't really a
handicap for writing larger programs (admittedly, Lispers already knew
it then -- so did I personally, thanks also to experiences with e.g.
Rexx -- but I didn't know of Python then).  So, it _is_ historically
interesting to ascertain when the issue of large programs first arose.

> nor WAS it ever such a thing.  From its release, Python was obviously a
> language very well suited to large scale application development (as

Well, clearly that was anything but obvious to Guido, from the above
quote.  Or maybe you mean by "release" the 1.0.0 one, in 1994?  At
that time, your contention becomes quite defensible (though I can't
find a Guido quote to support it, maybe I'm just not looking hard
enough), e.g. http://www.python.org/search/hypermail/python-1994q1/0050.html
where Bennett Todd muses
"""
I think Python will outstrip every other language out there, and Python
(extended where necessary in C) will be the next revolutionary programming
tool ... Perl seems (in my experience) to be weak for implementing large
systems, and having them run efficiently and be clear and easy to maintain.
I hope Python will do better.
"""
So, here, the idea or hope that Python "will do better" (at least wrt
Perl) "for implementing large systems" seems already in evidence, though
far from a community consensus yet.


I do find it fascinating that such primary sources are freely available
on the net -- a ball for us amateur historians...!-)



Alex
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pZKdnfe7dvjdixuiU-KYiA@comcast.com>
"Kenny Tilton" <·······@nyc.rr.com> wrote in message
··························@twister.nyc.rr.com...
>
> > You mean like Psyco?
> >
> > Been there, done that. (and it's great, and getting better).
>
> Oh, excellent name.

PYthon Specializing COmpiler, slightly permuted.  Also somehow apt for
something that dynamically compiles bytecode to type-specific machine
code.  Many of us did not quite believe it until the pudding was
cooked.

> OK, the context was "what are Python's aspirations?"
> . Is Python now no longer content to be a (very powerful) scripting
> language?

Prime focus is still correct and readable code with execution speed
somewhat secondary but not ignored.  The interpreter slowly speeds up;
more compiled C extension modules appear; other compilation options
appear; and 3 gig processors run Python about as fast as P125s did
with compiled C.

> Or is it just tired of being ragged on for being slow?

I suspect that that pushes a bit too, but I can't speak for anyone in
particular.

Terry J. Reedy
From: Ingvar Mattsson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ad89icl0.fsf@gruk.tech.ensign.ftech.net>
Kenny Tilton <·······@nyc.rr.com> writes:

> Paul Rubin wrote:
> 
> > Kenny Tilton <·······@nyc.rr.com> writes:
> >
> >>I think Python's problem is its success. Whenever something is
> >>succesful, the first thing people want is more features. Hell, that is
> >>how you know it is a success. The BDFL still talks about simplicity,
> >>but that is history. GvR, IMHO, should chased wish-listers away with
> >>"use Lisp" and kept his gem small and simple.
> > That's silly.  Something being successful means people want to use it
> > to get things done in the real world.  At that point they start
> > needing the tools that other languages provide for dealing with the
> > real world.  The real world is not a small and simple place, and small
> > simple systems are not always enough to cope with it.  If GVR had kept
> > his gem small and simple, it would have remained an academic toy, and
> > I think he had wide-reaching ambitions than that.
> 
> I agree with everything you said except that last bit, and I only
> disagree with that because of what I have heard from Pythonistas, so
> maybe I missed something. I did not think Python (or GVR or both) had
> aspirations of being a full-blown language vs just being a powerful
> scripting language.
> 
> Do they ever plan to do a compiler for it?

Python always compiles to byte-code, saved in a ".pyc" file, apart
(possibly) from the main file. Things that get "imported" will eb
compiled and saved out and re-compiled if the source-file is ewer than
the dumped compiled code.

//Ingvar
-- 
(defun p(i d)(cond((not i)(terpri))((car i)(let((l(cadr i))(d(nthcdr(car i)d
)))(princ(elt(string(car d))l))(p(cddr i)d)))(t(princ #\space)(p(cdr i)d))))
(p'(76 2 1 3 1 4 1 6()0 5()16 10 0 7 0 8 0 9()2 6 0 0 12 4 23 4 1 4 8 8)(sort
(loop for x being the external-symbols in :cl collect (string x)) #'string<))
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <edehb.16$KR3.2251@typhoon.nyu.edu>
David Rush wrote:
> You know I think that this thread has so far set a comp.lang.* record 
> for civilitiy in the face of a massively cross-posted language 
> comparison thread. I was even wondering if it was going to die a quiet 
> death, too.
> 
> Ah well, We all knew it was too good to last. Have at it, lads!
> 
> Common Lisp is an ugly language that is impossible to understand with 
> crufty semantics
> 
> Scheme is only used by ivory-tower academics and is irerelevant to real 
> world programming
> 
> Python is a religion that worships at the feet of Guido vanRossum
> combining the syntactic flaws of lisp with a bad case of feeping 
> creaturisms taken from languages more civilized than itself
> 
> There. Is everyone pissed off now?

You forgot the INTERCAL crowd :)

Cheers
--
Marco
From: Lulu of the Lotus-Eaters
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065643759.5938.python-list@python.org>
Alex Martelli:
|>Why, thanks!  Nice to see that I'm getting on the nerves of _some_
|>people, too, not just having them get on mine.

Doug Tolton <····@nospam.com> wrote previously:
|Yes, this discussion is frustrating.  It's deeply frustrating to hear
|someone without extensive experience with Macros arguing why they are
|so destructive.

If that is meant to address Alex Martelli, it is very deeply misguided.
If there is anyone who I can say with confidence has much more
experience--and much better understanding--of macros (or of all things
Lisp) than does Doug Tolton, it is Alex.

Yours, Lulu...
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <e9%gb.5709209$cI2.807889@news.easynews.com>
Lulu of the Lotus-Eaters wrote:

> Alex Martelli:
> |>Why, thanks!  Nice to see that I'm getting on the nerves of _some_
> |>people, too, not just having them get on mine.
> 
> Doug Tolton <····@nospam.com> wrote previously:
> |Yes, this discussion is frustrating.  It's deeply frustrating to hear
> |someone without extensive experience with Macros arguing why they are
> |so destructive.
> 
> If that is meant to address Alex Martelli, it is very deeply misguided.
> If there is anyone who I can say with confidence has much more
> experience--and much better understanding--of macros (or of all things
> Lisp) than does Doug Tolton, it is Alex.
> 
> Yours, Lulu...
> 

That was an interestingly ingorant statement.  I'm very suprised that 
you would feel the *least* bit qualified to offer that statement.  You 
don't know me or my background.  Alex has stated on many occasions that 
he has not worked with Macros, but that he is relying on second hand 
information.

I don't claim to be a guru on Lisp, however I believe I understand it 
far better than Alex does.  If the people who actually know and use 
Common Lisp think I am mis-speaking and mis-representing Lisp, please 
let me know and I will be quiet.

What is your background with Common Lisp David?  Why do you feel so 
eminently qualified to offer yourself as the expert on Lisp?  I have 
seen some FP from you, but I haven't seen much in the way of Lisp code. 
  Did you study it in school?  Have you really tried to build production 
quality system with Lisp?

Like I said, I'm not an expert at Lisp, but I think I understand the 
spirit and semantics of Lisp far better than Alex, and from what I've 
seen you say I wouldn't be suprised if I knew it better than you do as well.

-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <krghb.254517$R32.8255713@news2.tin.it>
Doug Tolton wrote:
   ...
> don't know me or my background.  Alex has stated on many occasions that
> he has not worked with Macros, but that he is relying on second hand
> information.

I never used Common Lisp in production: in the period of my life when I
was hired (by Texas Instruments) specifically for my knowledge of "Lisp",
that meant Scheme and a host of other dialects (mostly but not entirely now
forgotten).  I did use things that "passed for" macros in those dialects:
I had no choice, since each TI lab or faction within the lab was using a
different divergent mutant thing, all named "lisp" (save a few were named
"scheme" -- hmmm, I do believe that some were using Prolog, too, but I
did not happen to use it in TI), with some of the divergence hinging on
locally developed sets of macros (and some on different vendors/versions).

For all I know, CLisp's macros are SO head and shoulders above any of a
quarter century ago that any vaguely remembered technical problem from 
back then may be of purely historical interest.  I do believe that the
divergence problem has more to do with human nature and sociology, and 
that putting in a language features that encourage groups and subgroups 
of users to diverge that language cannot be compensated by technical
enhancements -- it _will_, in my opinion, cause co-workers in any middle- 
or large-sized organization to risk ending up standing on each others' 
feet, rather than on each others' shoulders. (Remedies must of course 
be sociological and lato sensu political first and foremost, but the way
the language & tools are designed CAN help or hinder).

So, I'm nowhere near an _expert_ -- over 20 years' hiatus ensures I
just can't be.  But neither is it totally 2nd hand information, and if
I gave the mistaken impression of never having used macros in a
production setting I must have expressed myself badly.  I do know I
jumped on the occasion of moving to IBM Research, and the fact that
this would mean going back to APL instead of "lisp" (in the above
vague sense) did matter somewhat in my glee, even though I still 
primarily thought of myself as a hardware person then (the programming 
was needed to try out algorithms, simulate possible hardware 
implementations thereof, etc -- it was never an end in itself).


> I don't claim to be a guru on Lisp, however I believe I understand it
> far better than Alex does.  If the people who actually know and use
> Common Lisp think I am mis-speaking and mis-representing Lisp, please
> let me know and I will be quiet.

Give that I've heard "everything and its opposite" (within two constant
parameters only: S-expressions are an unalloyed good -- macros are good,
some say unconditionally, others admit they can be prone to abuse) from
posters on this thread from "people who actually know and use" Lisp, I
don't know how you could "mis-speak and mis-represent" as long as you
stick to the two tenets of party doctrine;-).


> Like I said, I'm not an expert at Lisp, but I think I understand the
> spirit and semantics of Lisp far better than Alex, and from what I've

If by Lisp you mean Common Lisp and exclude Scheme, I'm sure you do; if
Scheme is to be included, then I'm not sure (but it's quite possible,
nevertheless) -- at least the "spirit" of the small core and widespread
HOFs w/single-namespace seem to be things I understand more (but the
"spirit" of why it's so wonderful to have extensible syntax isn't:-).


Alex
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Lghhb.26952$pv6.25455@twister.nyc.rr.com>
Alex Martelli wrote:
> ... I do believe that the
> divergence problem has more to do with human nature and sociology, and 
> that putting in a language features that encourage groups and subgroups 
> of users to diverge that language ....

Can someone write a nifty Python hack to figure out how many times 
Lispniks have tried to get Alex to explain how macros are any different 
than high-order functions or new classes when it comes to The Divergence 
Problem? I love that we have given it a name, by the way.

One popular macro is WITH-OUTPUT-TO-FILE. My budding RoboCup starter kit 
was a vital WITH-STD-ATTEMPT macro. Oh god, no! I need to see the ANSI 
Lisp commands for these things so I can really understand them. Better 
yet...

why not the disassembly? preferably without meaningful symbols from the 
HLL source. I think we are finally getting somewhere with TDP. Those 
high order classes, functions, and macros keep me from seeing what is 
really going on. Now if I could only see the microcode....

:)

kenny

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcv4qyiqnca.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> One popular macro is WITH-OUTPUT-TO-FILE. My budding RoboCup starter kit 
> was a vital WITH-STD-ATTEMPT macro. Oh god, no! I need to see the ANSI 
> Lisp commands for these things so I can really understand them. Better 
> yet...
> 
> why not the disassembly?

Fortunately for insane, paranoid programmers like Kenny who don't read
docstrings, and refuse to believe that others' libraries might work
correctly, Lisp is quite accomidating.  You want to see what a macro
call expands to?  Hey, I think we have tools for just that problem.
Disassembly?  Now I could be mistaken, but I remember it being far
easier than in most languages ... oh yeah, DISASSEMBLE.  Wow, I didn't
have to dig through a whole object file, or anything!

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <%6ihb.27208$pv6.25692@twister.nyc.rr.com>
Thomas F. Burdick wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>One popular macro is WITH-OUTPUT-TO-FILE. My budding RoboCup starter kit 
>>was a vital WITH-STD-ATTEMPT macro. Oh god, no! I need to see the ANSI 
>>Lisp commands for these things so I can really understand them. Better 
>>yet...
>>
>>why not the disassembly?
> 
> 
> Fortunately for insane, paranoid programmers like Kenny who don't read
> docstrings, and refuse to believe that others' libraries might work
> correctly, Lisp is quite accomidating.  You want to see what a macro
> call expands to?  Hey, I think we have tools for just that problem.
> Disassembly?  Now I could be mistaken, but I remember it being far
> easier than in most languages ... oh yeah, DISASSEMBLE.  Wow, I didn't
> have to dig through a whole object file, or anything!
> 

<rofl> yer right! Lisp is sick. I am going to go disassemble DOTIMES 
right now, find out once and for all what those plotters over at Franz 
are up to.

kenny

ps. Arnold is your governor, Arnold is your governor, nyeah, nyeah, nya, 
nyeah, nyeah.


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yShhb.255119$R32.8279501@news2.tin.it>
Kenny Tilton wrote:

> Alex Martelli wrote:
>> ... I do believe that the
>> divergence problem has more to do with human nature and sociology, and
>> that putting in a language features that encourage groups and subgroups
>> of users to diverge that language ....
> 
> Can someone write a nifty Python hack to figure out how many times
> Lispniks have tried to get Alex to explain how macros are any different
> than high-order functions or new classes when it comes to The Divergence
> Problem? I love that we have given it a name, by the way.

The very 'feature' that was touted by Erann Gat as macros' killer advantage
in the WITH-CONDITION-MAINTAINED example he posted is the crucial
difference: functions (HO or not) and classes only group some existing code
and data; macros can generate new code based on examining, and presumably to
some level *understanding*, a LOT of very deep things about the code 
arguments they're given.  If all you do with your macros is what you could
do with HOF's, it's silly to have macros in addition to HOF's -- just 
MTOWTDItis encouraging multiple different approaches to solve any given 
problem -- this, of course, in turn breeds divergence when compared to a
situation in which just one approach is encouraged.  If you do use the 
potential implied in that example from Gat, to do things that functions and 
classes just couldn't _begin_ to, it's worse -- then you're really 
designing your own private divergent language (which most posters from
the Lisp camp appear to assert is an unalloyed good, although admittedly
far from all).  This is far from the first time I'm explaining this, btw.

Oh, and if you're one of those who disapprove of Gat's example feel free
to say so, but until I hear a substantial majority denouncing it as idiotic 
(and I haven't seen anywhere near this intensity of disapproval for it from 
your camp) I'm quite justifyied in taking it as THE canonical example of a 
macro doing something that is clearly outside the purview of normal tools 
such as functions and classes.  As I recall there was a lot of that going
on in TI labs, too -- instead of writing and using compilers for hardware
description languages, circuit simulators, etc, based on appropriate and
specialized languages processed with the help general-purpose ones,
the specialized languages (divergent and half-baked) were embedded in
programs coded in the general-purpose languages (Lisp variants, including 
Scheme; that was in 1980) using macros that were supposed to do
everything but serve you coffee while you were waiting -- of course when
the snippets you passed (to represent hardware operation) were correct
from the GP language viewpoint but outside the limited parts thereof that
the macros could in fact process significantly down to circuit design &c,
the error messages you got (if you were lucky enough to get error
messages rather than just weird behavior) were QUITE interesting.


> One popular macro is WITH-OUTPUT-TO-FILE. My budding RoboCup starter kit
> was a vital WITH-STD-ATTEMPT macro. Oh god, no! I need to see the ANSI

Do they do things a HOF or class could do?  If so why bother using such
an over-powered tool as macros instead of HOFs or classes?  If not, how do
they specially process and understand code snippets they're passed?


Alex
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvy8vup64p.fsf@famine.OCF.Berkeley.EDU>
Alex Martelli <·····@aleax.it> writes:

> Kenny Tilton wrote:
> 
> > Alex Martelli wrote:
> >> ... I do believe that the
> >> divergence problem has more to do with human nature and sociology, and
> >> that putting in a language features that encourage groups and subgroups
> >> of users to diverge that language ....
> > 
> > Can someone write a nifty Python hack to figure out how many times
> > Lispniks have tried to get Alex to explain how macros are any different
> > than high-order functions or new classes when it comes to The Divergence
> > Problem? I love that we have given it a name, by the way.
> 
> The very 'feature' that was touted by Erann Gat as macros' killer advantage
> in the WITH-CONDITION-MAINTAINED example he posted is the crucial
> difference: functions (HO or not) and classes only group some existing code
> and data; macros can generate new code based on examining, and presumably to
> some level *understanding*, a LOT of very deep things about the code 
> arguments they're given.

Yes!  Macros can generate code, and compiler-macros can transform
perfectly ordinary, easy-to-read code into efficient code.  Anyone who
has worked in a domain where efficiency matters has run into the
problem most languages have: abstraction *or* efficiency.  Custom,
domain-specific transforms are something you can't always expect the
compiler to do.  With Lisp, you're not at the mercy of your vendor; if
you know damn well that some readable code A can be transformed into
equivalent, but efficient code B, you can cause it to happen!

>  If all you do with your macros is what you could do with HOF's,

But you can do more with macros, so there's no point in looking at the
conclusion to this sentance.

> Oh, and if you're one of those who disapprove of Gat's example feel free
> to say so, but until I hear a substantial majority denouncing it as idiotic 
> (and I haven't seen anywhere near this intensity of disapproval for it from 
> your camp)

Of course not, it's a lovely example of one use of macros.

> I'm quite justifyied in taking it as THE canonical example of a
> macro doing something that is clearly outside the purview of normal
> tools such as functions and classes.

No, you're not justified at all.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <0djhb.4401$dn6.162@newsread4.news.pas.earthlink.net>
Thomas F. Burdick:
> With Lisp, you're not at the mercy of your vendor; if
> you know damn well that some readable code A can be transformed into
> equivalent, but efficient code B, you can cause it to happen!

Not at the mercy of your vendor unless you want to use something
which isn't in the standard, like unicode (esp "wide" unicode, >16bit),
regular expressions (esp. regexps of unicode), sockets, or ffi?

But that's just flaming -- ignore me.  ;)

                    Andrew
                    ·····@dalkescientific.com
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <vIAhb.20$KR3.5653@typhoon.nyu.edu>
Andrew Dalke wrote:

> Thomas F. Burdick:
> 
>>With Lisp, you're not at the mercy of your vendor; if
>>you know damn well that some readable code A can be transformed into
>>equivalent, but efficient code B, you can cause it to happen!
> 
> 
> Not at the mercy of your vendor unless you want to use something
> which isn't in the standard, like unicode (esp "wide" unicode, >16bit),

Given that there are more than 1.84 implementations of Common Lisp, yes, 
you are at the mercy of the implementor to have access to a good UNICODE 
implementation.  (Now, whn is the last time I really really really 
needed to write error messages in Tamil script?  >:| )

> regular expressions (esp. regexps of unicode),

There are several completely portable regexps libraires.  For UNICODE 
see above.

> sockets,

There are at least two completely portable sockets libraries for CL.

> or ffi?

Last I checked UFFI did pretty much the right thing.

> 
> But that's just flaming -- ignore me.  ;)

I am a fireman :)

Cheers
--
Marco
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0910031337180001@k-137-79-50-101.jpl.nasa.gov>
In article <························@news2.tin.it>, Alex Martelli
<·····@aleax.it> wrote:

>  then you're really 
> designing your own private divergent language (which most posters from
> the Lisp camp appear to assert is an unalloyed good, although admittedly
> far from all).

FWIW, IMO "designing your own private divergent language" is not an
unalloyed good, but having the *ability* to design your own private
divergent language quickly and easily is.  Also, the "private divergent
languages" that most people design using Lisp macros are supersets of
Lisp, so that limits the extent to which divergence happens in practice.

Your position against macros and in favor of HOFs strikes me as being very
similar to those who want to ban model rocketry on the grounds that it is
too dangerous.  Yes, macros (and model rockets) can be dangerous.  If
you're not careful you can put your eye out with them.  But if you are
careful you can do very cool things with them and -- almost as important
-- learn a lot in the process.  (And what you learn from Lisp and model
rocketry are deep truths about the world, not a bunch of random kabuki
juju like what you fill your brain with when you learn C++.)  This
mindset, that anything that is potentially dangerous ought to be avoided
because it is potentially dangerous, is IMHO a perverse impediment to
progress.  There is no reward without risk.

Life is short.  It's not hard to produce a reasonable estimate of the
total number of keystrokes that you will be able to execute in a lifetime,
and it's a pretty small number in the grand and glorious scheme of
things.  If you have no ambitions beyond writing
yet-another-standard-web-app then macros are not for you.  But if your
goals run grander than that then the extra leverage that you get from
things like macros becomes very precious indeed.  Once your ambitions pass
a certain point the only option open to you is to teach your computer to
write code for you, because you don't have time to do it yourself.  For
example, there is no reason it should take multiple work years to write an
operating system.  There is no fundamental reason why one could not build
a computational infrastructure that would allow a single person to write
an operating system from scratch in a matter of days, maybe even hours or
minutes.  But such a system is going to have to have a fairly deep
understanding of the relationship of code to hardware.  You may want to
write things like:

(define-hardware-type ethernet-controller ...)

or

(define-hardware-standards-hierarchy
  (networking
    (ethernet
       (standard-ethernet
         (NE2000 ....))
       (fast-ethernet ...)
       (gigabit-ethernet ...))
    (fddi ...)
    (fibre-channel ...)
    ...)
  (mass-storage
    (hard-drive
      (ide ...)
      (scsi ...))

or

(is-a ne2000 standard-ethernet-card)

or

(define-register-layout ...)

God only knows.  Only one thing is certain: with macros and readtables you
will be limited only by your imagination.  With anything less you will be
limited by something else.

E.
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3smm25g4b.fsf@rigel.goldenthreadtech.com>
Alex Martelli <·····@aleax.it> writes:

> Kenny Tilton wrote:
> 
> > Alex Martelli wrote:
> >> ... I do believe that the
> >> divergence problem has more to do with human nature and sociology, and
> >> that putting in a language features that encourage groups and subgroups
> >> of users to diverge that language ....
> > 
> > Can someone write a nifty Python hack to figure out how many times
> > Lispniks have tried to get Alex to explain how macros are any different
> > than high-order functions or new classes when it comes to The Divergence
> > Problem? I love that we have given it a name, by the way.
> 
> The very 'feature' that was touted by Erann Gat as macros' killer advantage
> in the WITH-CONDITION-MAINTAINED example he posted is the crucial
> difference: functions (HO or not) and classes only group some existing code
> and data; macros can generate new code based on examining, and presumably to
> some level *understanding*, a LOT of very deep things about the code 
> arguments they're given.

Are you really this dense?  For crying out loud - functions can
generate code as well and just as easily as macros.  In fact macros
are just functions anyway so it really should go without saying.


>  If all you do with your macros is what you could do with HOF's,
> it's silly to have macros in addition to HOF's -- just

No it isn't, because they the mode of _expression_ may be better with
on in context A and better with the other in context B.



> MTOWTDItis encouraging multiple different approaches to solve any given 
> problem -- this, of course, in turn breeds divergence when compared to a

Actually it breeds better solutions to problems.  If you don't
understand this, you will never understand much of anything about good
problem solving.


> Oh, and if you're one of those who disapprove of Gat's example feel free
> to say so, but until I hear a substantial majority denouncing it as idiotic 

At the moment the only thing I am willing to denounce as idiotic are
your clueless rants.


/Jon
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <IMXhb.200809$hE5.6784896@news1.tin.it>
Jon S. Anthony wrote:
   ...
>> > Can someone write a nifty Python hack to figure out how many times
>> > Lispniks have tried to get Alex to explain how macros are any different
>> > than high-order functions or new classes when it comes to The
>> > Divergence Problem? I love that we have given it a name, by the way.
>> 
>> The very 'feature' that was touted by Erann Gat as macros' killer
>> advantage in the WITH-CONDITION-MAINTAINED example he posted is the
>> crucial difference: functions (HO or not) and classes only group some
>> existing code and data; macros can generate new code based on examining,
>> and presumably to some level *understanding*, a LOT of very deep things
>> about the code arguments they're given.
> 
> Are you really this dense?  For crying out loud - functions can
> generate code as well and just as easily as macros.  In fact macros
> are just functions anyway so it really should go without saying.

These assertions may hold in your favourite corner of the world, but
they surely don't in mine.  So, cry out just as loud as you want, and
keep insulting me at will, but you will hardly change my opinion: functions
_compute and return a result_ (which may be another function, but that's a 
detail) -- they cannot in any way break nor bend the syntax of the language 
[in non-pure-FP languages, including Python and lisp, functions can also 
have side effects, but that's another debate -- since c.f.programming is 
not in the list of groups targeted by this sub-sub-thread we probably don't 
need to pursue it].  Macros can.  Even Gat asserts that "in MOST cases" the
divergent language one builds with macros is a superset of lisp -- which
means it needs not be.  Without macros, you cannot alter the syntax and
make the language in which you embed your functions a different one,
perhaps not even a superset of the one you started with.  You can of
course implement a _separate_ language (hey, most language implementations
around today are probably coded in C, even for languages that have nothing 
at all to do with C), but that's quite different from mixing language and 
meta-language freely.


>>  If all you do with your macros is what you could do with HOF's,
>> it's silly to have macros in addition to HOF's -- just
> 
> No it isn't, because they the mode of _expression_ may be better with
> on in context A and better with the other in context B.

I care about "mode of expression" when I write poetry.  When I write
programs, I care about simplicity, clarity, directness.


>> MTOWTDItis encouraging multiple different approaches to solve any given
>> problem -- this, of course, in turn breeds divergence when compared to a
> 
> Actually it breeds better solutions to problems.  If you don't
> understand this, you will never understand much of anything about good
> problem solving.

Right: that's why I'm a decently-paid consultant and in my spare time write 
best-selling-in-niche books -- because I don't understand much of anything 
about good problem solving.  Flailing around between a zillion divergent
approaches is clearly the One True Way of problem-solving: that's why
perl, which glorifies that multiplicity, r00lez, right?

Meanwhile, while the perl-using team is halfway through the heated debate 
among the bazillion oh-so-EVER-clever and dazzling ways, the plodding, 
pragmatical, simplicity-oriented python-using team has delivered a clear, 
simple, maintainable solution and is well on its way towards the next one.

Easy pop quiz: of the designers of the languages Perl and Python, which
one was born in South California, which one in the Netherlands...;-?  [more
later about such geography-based stereotypes...]

Downside: nobody really gets entitled to feel smarter-than-thou for having
unearthed a solution so obscure it had escaped all the others; if you're in
the programming game for ego-boosting, a cleverness-requiring language
with a built-in competition for "stardom" may suit you better.  If you're 
into it to actually solve problems, egoless programming may be ok, though.

[[ back to stereotypes: now, lisp is clearly in-between, its designer being 
from Massachussets.  And just for a little self-satire -- if a language had
an _Italian_ designer, it probably would be little use for _programming_,
though it would likely be good for cuisine, fashion, major-scale graft, and  
seducing beautiful women [though come to think of it, I didn't do all that 
badly with Python on the latter -- Hi Anna!-)]  ]]


>> Oh, and if you're one of those who disapprove of Gat's example feel free
>> to say so, but until I hear a substantial majority denouncing it as
>> idiotic
> 
> At the moment the only thing I am willing to denounce as idiotic are
> your clueless rants.

Excellent!  I interpret the old saying "you can judge a man by the quality 
of his enemies" differently than most do: I'm _overjoyed_ that my enemies 
are the scum of the earth, and you, sir [to use the word loosely], look as 
if you're fully qualified to join that self-selected company.


Alex
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm9it8$6j5$1@newsreader2.netcologne.de>
Alex Martelli wrote:

> Jon S. Anthony wrote:
>    ...
> 
>>>>Can someone write a nifty Python hack to figure out how many times
>>>>Lispniks have tried to get Alex to explain how macros are any different
>>>>than high-order functions or new classes when it comes to The
>>>>Divergence Problem? I love that we have given it a name, by the way.
>>>
>>>The very 'feature' that was touted by Erann Gat as macros' killer
>>>advantage in the WITH-CONDITION-MAINTAINED example he posted is the
>>>crucial difference: functions (HO or not) and classes only group some
>>>existing code and data; macros can generate new code based on examining,
>>>and presumably to some level *understanding*, a LOT of very deep things
>>>about the code arguments they're given.
>>
>>Are you really this dense?  For crying out loud - functions can
>>generate code as well and just as easily as macros.  In fact macros
>>are just functions anyway so it really should go without saying.
> 
> 
> These assertions may hold in your favourite corner of the world, but
> they surely don't in mine.  So, cry out just as loud as you want, and
> keep insulting me at will, but you will hardly change my opinion: functions
> _compute and return a result_ (which may be another function, but that's a 
> detail) -- they cannot in any way break nor bend the syntax of the language 
> [in non-pure-FP languages, including Python and lisp, functions can also 
> have side effects, but that's another debate -- since c.f.programming is 
> not in the list of groups targeted by this sub-sub-thread we probably don't 
> need to pursue it].  Macros can.  Even Gat asserts that "in MOST cases" the
> divergent language one builds with macros is a superset of lisp -- which
> means it needs not be.  Without macros, you cannot alter the syntax and
> make the language in which you embed your functions a different one,
> perhaps not even a superset of the one you started with.  You can of
> course implement a _separate_ language (hey, most language implementations
> around today are probably coded in C, even for languages that have nothing 
> at all to do with C), but that's quite different from mixing language and 
> meta-language freely.

Macros are localized. When you see something like this:

(with-whatever ...
   ...)

You can be pretty sure that the effect of the macro spans only the 
extent of that macro.

This is similar to what you can do with local functions:

(flet ((print (x) ...))
   ...)

Now, in the scope of that local definition, the previously defined print 
function gets a new meaning.

Nothing breathtaking going here in both examples.


Does Python allow local function definitions? Can they shadow predefined 
functions?


Pascal
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <6WKdnf4hoZxoRRWiXTWJig@comcast.com>
"Pascal Costanza" <········@web.de> wrote in message
·················@newsreader2.netcologne.de...
> Does Python allow local function definitions?

Module level functions are local to the module unless imported by
another module.  Nested functions are local to the function they are
nested within unless explicitly returned.  Methods are local to
classes and subclasses.  Lambda expressions are very local unless
somehow passed around.

I am not sure which best meets your intention.

>Can they shadow predefined functions?

Yes, named objects, including functions can (locally) shadow
(override) builtins.  It is considered a bad habit/practice unless
done intentionally with a functional reason.

Terry J. Reedy
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmbunh$lgv$1@newsreader2.netcologne.de>
Terry Reedy wrote:

> "Pascal Costanza" <········@web.de> wrote in message
> ·················@newsreader2.netcologne.de...
> 
>>Does Python allow local function definitions?
> 
> 
> Module level functions are local to the module unless imported by
> another module.  Nested functions are local to the function they are
> nested within unless explicitly returned.  Methods are local to
> classes and subclasses.  Lambda expressions are very local unless
> somehow passed around.
> 
> I am not sure which best meets your intention.
> 
> 
>>Can they shadow predefined functions?
> 
> 
> Yes, named objects, including functions can (locally) shadow
> (override) builtins.  It is considered a bad habit/practice unless
> done intentionally with a functional reason.

Well, this proves that Python has a language feature that is as 
dangerous as many people seem to think macros are.

<irony>
What you say is that local function definitions can obscure the meaning 
of the Python language and/or its standard library, and this has the 
potential to split the language community and make it impossible to read 
each other's code. Heck, you really can't rely on the fact that sum(...) 
sums its arguments? This means that a local function definition is 
really a dangerous language feature, isn't it? Shouldn't it better be 
abandoned?
</irony>

That last paragraph sounds as non-sensical to your ears as the arguments 
against the inclusion of macros into a language because of their 
expressive power sound to our ears.

BTW, do you know the talk "Growing a Language" by Guy Steele? See 
http://www.research.avayalabs.com/user/wadler/steele-oopsla98.pdf - read 
it, it's very insightful (even though it talks about Java. ;)

Pascal
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <39hib.205605$hE5.6914649@news1.tin.it>
Pascal Costanza wrote:
   ...
>>>Does Python allow local function definitions?
   ...
>>>Can they shadow predefined functions?
   ...
>> Yes, named objects, including functions can (locally) shadow
>> (override) builtins.  It is considered a bad habit/practice unless
>> done intentionally with a functional reason.
> 
> Well, this proves that Python has a language feature that is as
> dangerous as many people seem to think macros are.

Indeed, a chorus of "don't do that" is the typical comment each
and every time a newbie falls into that particular mis-use.  Currently,
the --shadow option of PyChecker only warns about shadowing of
_variables_, not shadowing of _functions_, but there's really no
reason why it shouldn't warn about both.  Logilab's pylint does
diagnose "redefining built-in" with a warning (I think they mean
_shadowing_, not actually _redefining_, but this may be an issue
of preferred usage of terms).

"Nailing down" built-ins (at first with a built-in warning for overriding 
them, later in stronger ways -- slowly and gradually, like always, to 
maintain backwards compatibility and allow slow, gradual migration of the 
large existing codebase) is under active consideration for the next version 
of Python, expected (roughly -- no firm plans yet) in early 2005.

So, yes, Python is not perfect today (or else, we wouldn't be planning a
2.4 release...:-).  While it never went out of its way to give the user "as 
much rope as needed to shoot oneself in the foot", neither did it ever 
spend enormous energy in trying to help the user avoid many possible errors 
and dubious usage.  Such tools as PyChecker and pylint are a start, and
some of their functionality should eventually be folded back into the
core, just as tabnanny's was in the past with the -t switch.  I don't think
the fundamental Python will ever nag you for missing comments or
docstrings, too-short names, etc, the way pylint does by default (at
least, I sure hope not...!-), but there's quite a bit I _would_ like to have
it do in terms of warnings and, eventually, error messages for
"feechurs" that only exist because it was once simple to allow than
to forbid them, not by a deliberate design decision to have them there.

Note that SOME built-ins exist SPECIFICALLY for the purpose of
letting you override them.  Consider, for example, __import__ -- this
built-in function just exposes the inner mechanics of the import
statement (and friends) to let you get modules from some other
place (e.g., when your program must run off a relational database
rather than off a filesystem).  In other word, it's a rudimentary hook
in a "Template Method" design pattern (it's also occasionally handy
to let you import a module whose name is in a string, without
going to the bother of an 'exec', so it will surely stay for that purpose
even though we now have a shiny brand-new architecture for
import hooks -- but that's another story).  Having a single hook of
global effect has all the usual downsides, of course (which is exactly
why we DO have that new architecture;-): two or more complicated
packages doing import-hooks can't necessarily coexist within the
same Python application program (the only saving grace which let
us live with that simplistic hook for so many years is that importing
from strange places is typically a need of a certain deployment of
an overall application, not of a package -- still, such packages DO
exist, so the previous solution was far from perfect).

Anyway, back to your contention: I do not think that the fact that
the user can, within his functions, choose very debatable names,
such as those which shadow built-ins, is anywhere as powerful,
and therefore as dangerous, as macros.  My own functions using
'sum' will get the built-in one even if yours do weird things with
that same name as a local variable of their own.  The downsides
of shadowing are essentially as follows...

a newbie posts some fragment of his code asking for guidance,
and among other things that fragment has
    for i in range(length(thenumbers)):
        total = total + thenumbers[i]
he will receive many suggestions on how to make it better,
including the ideal one:
    total = sum(thenumbers, total)
But then he tries it out and reports "it breaks" (newbies rarely
are clueful enough to just copy and paste error messages).  And
we all waste lots of time finding out that this is because... the
hapless newbie had named HIS OWN FUNCTION 'sum', so
this was causing runaway recursion.  Having met similar issues
over and over, one starts to warn newbies against shadowing
and get sympathetic with the idea of forbidding it:-).

That doesn't really compare to an extra feature in the language
that is deliberately designed to let reasonably-clueful users do
their thing, isn't deprecated nor warned against by anybody at
all (with a few isolated voices speaking about "abuse" of macros
in this thread, but still with an appreciation for macros when
_well_ used), and is MEANT to do what newbies _accidentally_
do with shadowing & much more besides;-).


Alex
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmcbg5$cgl$1@newsreader2.netcologne.de>
Alex Martelli wrote:

> Pascal Costanza wrote:
>    ...
> 
>>>>Does Python allow local function definitions?
> 
>    ...
> 
>>>>Can they shadow predefined functions?
> 
>    ...
> 
>>>Yes, named objects, including functions can (locally) shadow
>>>(override) builtins.  It is considered a bad habit/practice unless
>>>done intentionally with a functional reason.
>>
>>Well, this proves that Python has a language feature that is as
>>dangerous as many people seem to think macros are.
> 
> 
> Indeed, a chorus of "don't do that" is the typical comment each
> and every time a newbie falls into that particular mis-use.  Currently,
> the --shadow option of PyChecker only warns about shadowing of
> _variables_, not shadowing of _functions_, but there's really no
> reason why it shouldn't warn about both.  Logilab's pylint does
> diagnose "redefining built-in" with a warning (I think they mean
> _shadowing_, not actually _redefining_, but this may be an issue
> of preferred usage of terms).
> 
> "Nailing down" built-ins (at first with a built-in warning for overriding 
> them, later in stronger ways -- slowly and gradually, like always, to 
> maintain backwards compatibility and allow slow, gradual migration of the 
> large existing codebase) is under active consideration for the next version 
> of Python, expected (roughly -- no firm plans yet) in early 2005.

OK, I understand that the Python mindset is really _a lot_ different 
than the Lisp mindset in this regard.

> Note that SOME built-ins exist SPECIFICALLY for the purpose of
> letting you override them.  Consider, for example, __import__ -- this
> built-in function just exposes the inner mechanics of the import
> statement (and friends) to let you get modules from some other
> place (e.g., when your program must run off a relational database
> rather than off a filesystem).  In other word, it's a rudimentary hook
> in a "Template Method" design pattern (it's also occasionally handy
> to let you import a module whose name is in a string, without
> going to the bother of an 'exec', so it will surely stay for that purpose
> even though we now have a shiny brand-new architecture for
> import hooks -- but that's another story).

Ah, you want something like final methods in Java, or better probably 
final implicitly as the default and means to make select methods 
non-final, right?

> Anyway, back to your contention: I do not think that the fact that
> the user can, within his functions, choose very debatable names,
> such as those which shadow built-ins, is anywhere as powerful,
> and therefore as dangerous, as macros.  My own functions using
> 'sum' will get the built-in one even if yours do weird things with
> that same name as a local variable of their own.  The downsides
> of shadowing are essentially as follows...

What makes you think that macros have farther reaching effects in this 
regard than functions? If I call a method and pass it a function object, 
I also don't know what the method will do with it.

Overriding methods can also be problematic when they break contracts. 
(Are you also considering to add DBC to Python? I would expect that by 
now given your reply above.)

Can you give an example for the presumably dangerous things macros 
supposedly can do that you have in mind?


Pascal
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <29kib.206536$hE5.6945256@news1.tin.it>
Pascal Costanza wrote:
   ...
>>>Well, this proves that Python has a language feature that is as
>>>dangerous as many people seem to think macros are.
   ...
>> Indeed, a chorus of "don't do that" is the typical comment each
>> and every time a newbie falls into that particular mis-use.  Currently,
   ...
>> large existing codebase) is under active consideration for the next
>> version of Python, expected (roughly -- no firm plans yet) in early 2005.
> 
> OK, I understand that the Python mindset is really _a lot_ different
> than the Lisp mindset in this regard.

As in, no lisper will ever admit that a currently existing feature is
considered a misfeature?-)


> Ah, you want something like final methods in Java, or better probably
> final implicitly as the default and means to make select methods
> non-final, right?

Not really, the issue I was discussing was specifically with importing.

Normally, an import statement "looks" for a module [a] among those
already loaded, [b] among the ones built-in to the runtime, [c] on
the filesystem (files in directories listed in sys.path).  "import hooks" 
can be used to let you get modules from other places yet (a database,
a server over the network, an encrypted version, ...).  The new architecture
I mentioned lets many import hooks coexist and cooperate, while the
old single-hook architecture made that MUCH more difficult, that's all.

"final implicitly as the default and means to make select methods
non-final" is roughly what C++ has -- the "means" being the "virtual"
attribute of methods.  Experience proves that's not what we want.
Rather, builtin (free, aka toplevel) _names_ should be locked down
just as today names of _attributes_ of builtin types are mostly
locked down (with specific, deliberate exceptions, yes).  But I think
I'm in a minority in wanting similar mechanisms for non-built-ins,
akin to the 'freeze' mechanism of Ruby (and I'm dismayed by reading
that experienced Rubystas say that freeze LOOKS like a cool idea
but in practice it's almost never useful -- they have the relevant
experience, I don't, so I have to respect their evaluation).


> What makes you think that macros have farther reaching effects in this
> regard than functions? If I call a method and pass it a function object,
> I also don't know what the method will do with it.

Of course not -- but it *cannot possibly* do what Gat's example of macros,
WITH-MAINTAINED-CONDITION, is _claimed_ to do... "reason" about the
condition it's meant to maintain (in his example a constraint on a variable
named temperature), about the code over which it is to be maintained
(three functions, or macros, that start, run, and stop the reactor), 
presumably infer from that code a model of how a reactor _works_, and
rewrite the control code accordingly to ensure the condition _is_ in fact
being maintained.  A callable passed as a parameter is _atomic_ -- you
call it zero or more times with arguments, and/or you store it somewhere
for later calling, *THAT'S IT*.  This is _trivially simple_ to document and
reason about, compared to something that has the potential to dissect
and alter the code it's passed to generate completely new one, most
particularly when there are also implicit models of the physical world being
inferred and reasoned about.  Given that I've seen nobody say, for days!, 
that Gat's example was idiotic, as I had first I thought it might be, and 
on the contrary I've seen many endorse it, I use it now as the simplest
way to show why macros are obviously claimed by their proponents to
be _scarily_ more powerful than functions.  (and if a few voices out of
the many from the macro-lovers camp should suddely appear to claim
that the example was in fact idiotic, while most others keep concurring
with it, that will scale down "their proponents" to "most of their
proponents", not a major difference after all).


> Overriding methods can also be problematic when they break contracts.

That typically only means an exception ends up being raised when
the method is used "inappropriately" - i.e. in ways depending on the
contract the override violates.  The only issue is ensuring that the
diagnostics of the error are clear and complete (and giving clear and
complete error diagnostics is often not trivial, but that is common to
just about _any_ classes of errors that programmers do make).

> (Are you also considering to add DBC to Python? I would expect that by
> now given your reply above.)

Several different implementations of DBC for Python are around, just
like several different architectures for interfaces (or, as I hope, 
Haskell-like typeclasses, a more powerful concept).   [Note that the
lack of macros stops nobody from playing around with concepts they
would like to see in Python: they just don't get to make new syntax
to go with them, and, thus, to fragment the language thereby:-)].

Guido has already declared that ONE concept of interfaces (or 
typeclasses, or protocols, etc) _will_ eventually get into Python -- but
_which one_, it's far too early to tell.  I would be surprised if whichever
version does make it into Python doesn't let you express contracts.
A contract violation will doubtlessly only mean a clear and early error
diagnostic, surely a good thing but not any real change in the
power of the language.


> Can you give an example for the presumably dangerous things macros
> supposedly can do that you have in mind?

I have given this repeatedly: they can (and in fact have) tempt programmers
using a language which offers macros (various versions of lisp) to, e.g.,
"embed a domain specific language" right into the general purpose language.
I.e., exactly the use which is claimed to be the ADVANTAGE of macros.  I
have seen computer scientists with modest grasp of integrated circuit design
embed half-baked hardware-description languages (_at least_ one different
incompatible such sublanguage per lab) right into the general-purpose
language, and tout it at conferences as the holy grail -- while competitors
were designing declarative languages intended specifically for the purpose
of describing hardware, with syntax and specifically limited semantics that
seemed to be designed in concert with the hardware guys who'd later be
USING the gd thing (and were NOT particularly interested in programming
except in as much it made designing hardware faster and cheaper).  The
effort of parsing those special-purpose language was of course trivial (even
at the time -- a quarter of a century ago -- yacc and flex WERE already
around...!), there was no language/metalanguage confusion, specialists in
the domain actually did a large part of the domain-specific language design
(without needing macro smarts for the purpose) and ended up eating our
lunch (well, except that I jumped ship before then...;-).

Without macros, when you see you want to design a special-purpose
language you are motivated to put it OUTSIDE your primary language,
and design it WITH its intended users, FOR its intended purposes, which
may well have nothing at all to do with programming.  You parse it with a
parser (trivial these days, trivial a quarter of a century ago), and off you 
go.  With macros, you're encouraged to do all the wrong things -- or, to
be more precise, encouraged to do just the things I saw causing the
many costly failures (one or more per lab, thanks to the divergence:-)
back in that my early formative experience.

I have no problem with macros _in a special-purpose language_ where
they won't tempt you to embed what you _should_ be "out-bedding",
so to speak -- if the problem of giving clear diagnostics of errors can be
mastered, denoting that some functions are to be called at compile
time to produce code in the SPL has no conceptual, nor, I think,
particular "sociological" problem.  It's only an issue of weighing their
costs and usefulness -- does the SPL embody other ways to remove
duplication and encourage refactoring thereby, are there overlap
among various such ways, etc, etc.  E.g., a purely declarative SPL,
with the purpose of describing some intricate structure, may have no
'functions' and thus no other real way to remove duplication than
macros (well, it depends on whether there may be other domain
specific abstractions that would be more useful than mere textual
expansions, of course -- e.g. inheritance/specialization, composition
of parts, and the like -- but they need not be optimal to capture some
inevitable "quasi-accidental duplications of SPL code" where a macro
might well be).


Alex
From: Henrik Motakef
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <868ynqvy9i.fsf@pokey.internal.henrik-motakef.de>
Alex Martelli <·······@yahoo.com> writes:

> > OK, I understand that the Python mindset is really _a lot_ different
> > than the Lisp mindset in this regard.
> 
> As in, no lisper will ever admit that a currently existing feature is
> considered a misfeature?-)

You might want to search google groups for threads about "logical
pathnames" in cll :-)

> Guido has already declared that ONE concept of interfaces (or 
> typeclasses, or protocols, etc) _will_ eventually get into Python -- but
> _which one_, it's far too early to tell. 

A propos interfaces in Python: The way they were done in earlier Zope
(with "magic" docstrings IIRC) was one of the things that led me to
believe language extensibilit was a must, together with the phletora
of SPLs the Java community came up with, either in comments (like
JavaDoc and XDoclet) or ad-hoc XML "configuration" files that grow and
grow until they are at least turing-complete at some point. (blech)

People /will/ extend the base language if it's not powerfull enough
for everything they want to do, macros or not. You can either give
them a powerfull, documented and portable standart way to do so, or
ignore it, hoping that the benevolent dictator will someday change the
core language in a way that blesses one of the extensions (most likely
a polished variant of an existing one) the "obvious", official one.

It is the difference between implementing a proper type system and
extending lint to check for consistent use of the hungarian notation
at the end of the day.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmcolo$1ab$1@newsreader2.netcologne.de>
Alex Martelli wrote:

> Pascal Costanza wrote:

>>What makes you think that macros have farther reaching effects in this
>>regard than functions? If I call a method and pass it a function object,
>>I also don't know what the method will do with it.
> 
> 
> Of course not -- but it *cannot possibly* do what Gat's example of macros,
> WITH-MAINTAINED-CONDITION, is _claimed_ to do... "reason" about the
> condition it's meant to maintain (in his example a constraint on a variable
> named temperature), about the code over which it is to be maintained
> (three functions, or macros, that start, run, and stop the reactor), 
> presumably infer from that code a model of how a reactor _works_, and
> rewrite the control code accordingly to ensure the condition _is_ in fact
> being maintained.

...but such a macro _exclusively_ reasons about the code that is passed 
to it. So the effects are completely localized. You don't do any damage 
to the rest of the language because of such a macro.

Of course, such a macro needs to be well-defined and well-documented. 
But that's the case for any code, isn't it?

>>(Are you also considering to add DBC to Python? I would expect that by
>>now given your reply above.)
[...]

> Guido has already declared that ONE concept of interfaces (or 
> typeclasses, or protocols, etc) _will_ eventually get into Python -- but
> _which one_, it's far too early to tell.  I would be surprised if whichever
> version does make it into Python doesn't let you express contracts.

OK, I think I understand the Python mindset a little bit better. Thanks.

>>Can you give an example for the presumably dangerous things macros
>>supposedly can do that you have in mind?
> 
> 
> I have given this repeatedly: they can (and in fact have) tempt programmers
> using a language which offers macros (various versions of lisp) to, e.g.,
> "embed a domain specific language" right into the general purpose language.
> I.e., exactly the use which is claimed to be the ADVANTAGE of macros.  I
> have seen computer scientists with modest grasp of integrated circuit design
> embed half-baked hardware-description languages (_at least_ one different
> incompatible such sublanguage per lab) right into the general-purpose
> language, and tout it at conferences as the holy grail

That's all? And you really think this has anything to do with macros?

Yes, macros allow you to write bad programs - but this is true for any 
language construct.

Your proposed model means that for each DSL you might need you also need 
to implement it as a separate language. Well, this has also been done 
over and over again, with varying degrees of success. You can probably 
name several badly designed "out-bedded" little languages. Does this 
mean that your propose sucks as well? It doesn't seem to guarantee good 
little languages, does it?

In reality, in both approaches we can just find both badly and well 
designed DSLs.

Bad languages, no matter whether embedded or "out-bedded", exist not 
because of the technology that is being used to implement them but 
because of the fact that humans can fail when they undertake something.

You surely can name some badly desigend libraries, even for Python. Does 
this mean that the respective languages suck? That the very concept of 
libraries suck?

Here is a one of my favorite quotes, by Guy Steele and Gerald Sussman: 
"No amount of language design can _force_ a programmer to write clear 
programs. If the programmer's conception of the problem is badly 
organized, then his program will also be badly organized. The extent to 
which a programming language can help a programmer to organize his 
problem is precisely the extent to which it provides features 
appropriate to his problem domain. The emphasis should not be on 
eliminating �bad� language constructs, but on discovering or inventing 
helpful ones." (from "Lambda - The Ultimate Imperative")


Pythonistas seem to think otherwise wrt language design that can force 
programmers to write clear programs. If you think that this is a good 
summary of the Python mindset then we can stop the discussion. I simply 
don't buy into such a mindset.


Pascal
From: Paolo Amoroso
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ekxhl2k4.fsf@plato.moon.paoloamoroso.it>
[The original followup was to comp.lang.python. But since Alex mostly
discusses Lisp features, and we probably both don't subscribe to each
other's group, I follow up to both of them]

Alex Martelli writes:

> As in, no lisper will ever admit that a currently existing feature is
> considered a misfeature?-)

Paul Graham is possibly the best known such lisper. You may check the
documents about the Arc dialect at his site.


 [Pascal Costanza]
>> What makes you think that macros have farther reaching effects in this
>> regard than functions? If I call a method and pass it a function object,
>> I also don't know what the method will do with it.
>
> Of course not -- but it *cannot possibly* do what Gat's example of macros,
> WITH-MAINTAINED-CONDITION, is _claimed_ to do... "reason" about the
> condition it's meant to maintain (in his example a constraint on a variable
> named temperature), about the code over which it is to be maintained
> (three functions, or macros, that start, run, and stop the reactor), 
> presumably infer from that code a model of how a reactor _works_, and
> rewrite the control code accordingly to ensure the condition _is_ in fact
> being maintained.  A callable passed as a parameter is _atomic_ -- you
> call it zero or more times with arguments, and/or you store it somewhere
> for later calling, *THAT'S IT*.  This is _trivially simple_ to document and
> reason about, compared to something that has the potential to dissect
> and alter the code it's passed to generate completely new one, most
> particularly when there are also implicit models of the physical world being
> inferred and reasoned about.  Given that I've seen nobody say, for days!, 

The word "reason" looks a bit too AI-sh: macros do much more mundane
things. If I correctly understand Erann Gat's example in the nuclear
reactor context, things would work like this.

Some domain primitives--e.g. for controlling temperature,
starting/stopping the reactor, etc.--would be written by, or with the
help of, nuclear reactor experts. These primitives, typically
implemented as ordinary functions/classes, would embody a model of how
the reactor works. At this point, there's nothing different with what
would be done with other languages.

Now suppose you have a code module in which you have to "maintain" a
certain condition in the reactor. By "maintain" I mean arrange a
possibly long sequence of calls to domain primitives in such a way
that the condition is maintained (e.g. call the function that starts
the reactor with appropriate arguments, call functions for getting
temperature sensor readings with other arguments, check the
temperature readings and take appropriate decisions based on the
values, etc.). I guess this is also what would be done with other
languages--and Lisp.

A WITH-MAINTAINED-CONDITION macro would just provide syntactic sugar
for that possibly long statement/expression sequence for "maintaining"
the condition. That's it. It would typically accept parameters
describing the condition, and would generate the right sequence of
domain primitives with appropriate parameters.

WITH-MAINTAINED-CONDITION wouldn't have its own nuclear reactor model,
or other physical model. It would merely generate code templates,
mostly calls to ordinary functions, that the programmer would write
anyway (or put into a higher level function). Documenting such a macro
would be as easy as documenting the individual functions and/or an
equivalent function with internal calls to domain primitives.

Erann: is my understanding correct?

Alex: how would this way of using macros be dangerous?


Paolo
-- 
Paolo Amoroso <·······@mclink.it>
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <gat-1410030512220001@10.0.2.126>
In article <··············@plato.moon.paoloamoroso.it>, Paolo Amoroso
<·······@mclink.it> wrote:

[A theory of with-maintained-condition]

> Erann: is my understanding correct?

Yep.  There are many plausible ways to implement
with-maintained-condition, and that's one of them.

E.
From: Matthew Kennedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <86he2c49qv.fsf@killr.ath.cx>
Alex Martelli <·······@yahoo.com> writes:

[...]

>
> Without macros, when you see you want to design a special-purpose
> language you are motivated to put it OUTSIDE your primary language,
> and design it WITH its intended users, FOR its intended purposes, which
> may well have nothing at all to do with programming.  You parse it with a
> parser (trivial these days, trivial a quarter of a century ago), and off you 
> go.  

...and off I go.  A parser for our new DSL syntax is one thing, but
now I'll need a compiler as well, a symbolic debugger understanding
the new syntax would be nice, and perhaps an interactive environment
(interpreter) would be helpful.  If we get time (ha!), lets create an
tools to edit the new syntax.

Seems like a lot of work.

I think I'll stay within Lisp and build the language up to problem
just as Paul Graham describes in On Lisp[1].  That way I get all of
the above for free and in much less time.

Footnotes: 
[1]  http://www.paulgraham.com/onlisp.html


-- 
Now, my ENTIRE LIFE is flashing before my EYES as I park my DODGE
 DART in your EXXON service area for a COMPLETE LUBRICATION!!
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3u16d3wz1.fsf@rigel.goldenthreadtech.com>
Alex Martelli <·······@yahoo.com> writes:

 > At the moment the only thing I am willing to denounce as idiotic are
> > your clueless rants.
> 
> Excellent!  I interpret the old saying "you can judge a man by the quality 
> of his enemies" differently than most do: I'm _overjoyed_ that my enemies 
> are the scum of the earth, and you, sir [to use the word loosely], look as 
> if you're fully qualified to join that self-selected company.

Whatever.

/Jon
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <atihb.27305$pv6.19284@twister.nyc.rr.com>
Alex Martelli wrote:

> Kenny Tilton wrote:
> 
> 
>>Alex Martelli wrote:
>>
>>>... I do believe that the
>>>divergence problem has more to do with human nature and sociology, and
>>>that putting in a language features that encourage groups and subgroups
>>>of users to diverge that language ....
>>
>>Can someone write a nifty Python hack to figure out how many times
>>Lispniks have tried to get Alex to explain how macros are any different
>>than high-order functions or new classes when it comes to The Divergence
>>Problem? I love that we have given it a name, by the way.
> 
> 
> The very 'feature' that was touted by Erann Gat as macros' killer advantage
> in the WITH-CONDITION-MAINTAINED example he posted is the crucial
> difference: functions (HO or not) and classes only group some existing code
> and data; macros can generate new code based on examining, and presumably to
> some level *understanding*, a LOT of very deep things about the code 
> arguments they're given.  

Stop, your scaring me. You mean to say there are macros out there whose 
output/behavior I cannot predict? And I am using them in a context where 
I need to know what the behavior will be? What is wrong with me? And 
what sort of non-deterministic macros are these, that go out and make 
their own conclusions about what I meant in some way not documeted?

I think the objection to macros has at this point been painted into a 
very small corner.


> ...If all you do with your macros is what you could
> do with HOF's, it's silly to have macros in addition to HOF's 

There is one c.l.l. denizen/guru who agrees with you. I believe his 
position is "evrything can be done with lambda". And indeed, many a 
groovy WITHOUT-CELL-DEPENDENCY expands straight into:

    (call-with-cell-dependency (lambda () ,yadayadayada))

But code with WITHOUT-CELL-DEPENDENCY looks prettier (I hope we can 
agree that that matters, esp. if you are a Pythonista).

-- just
> MTOWTDItis encouraging multiple different approaches to solve any given 
> problem -- this, of course, in turn breeds divergence when compared to a
> situation in which just one approach is encouraged.  If you do use the 
> potential implied in that example from Gat, to do things that functions and 
> classes just couldn't _begin_ to, it's worse -- then you're really 
> designing your own private divergent language (which most posters from
> the Lisp camp appear to assert is an unalloyed good, although admittedly
> far from all).  This is far from the first time I'm explaining this, btw.

Oh. OK, now that you mention it I have been skimming lately.

> 
>>One popular macro is WITH-OUTPUT-TO-FILE. My budding RoboCup starter kit
>>was a vital WITH-STD-ATTEMPT macro. Oh god, no! I need to see the ANSI
> 
> 
> Do they do things a HOF or class could do? 

Yes.

>... If so why bother using such
> an over-powered tool as macros instead of HOFs or classes?  

Hang on, we just agreed that in this case the only added value is 
prettier code. Nothing over-powered going on. (And that is, in this 
case, why I bother.)

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ue0ib.267972$R32.8718052@news2.tin.it>
Kenny Tilton wrote:
   ...
>> The very 'feature' that was touted by Erann Gat as macros' killer
>> advantage in the WITH-CONDITION-MAINTAINED example he posted is the
>> crucial difference: functions (HO or not) and classes only group some
>> existing code and data; macros can generate new code based on examining,
>> and presumably to some level *understanding*, a LOT of very deep things
>> about the code arguments they're given.
> 
> Stop, your scaring me. You mean to say there are macros out there whose
> output/behavior I cannot predict? And I am using them in a context where
> I need to know what the behavior will be? What is wrong with me? And
> what sort of non-deterministic macros are these, that go out and make
> their own conclusions about what I meant in some way not documeted?

Let's start with that WITH-CONDITION-MAINTAINED example of Gat.  Remember 
it?  OK, now, since you don't appear to think it was an idiotic example, 
then SHOW me how it takes the code for the condition it is to maintain and
the (obviously very complicated: starting a reactor, operating the reactor,
stopping the reactor -- these three primitives in this sequence) program 
over which it is to maintain it, and how does it modify that code to ensure
this purpose.  Surely, given its perfectly general name, that macro does not
contain, in itself, any model of the reactor; so it must somehow infer it 
(guess it?) from the innards of the code it's analyzing and modifying.

Do you need to know what the behavior will be, when controlling a reactor?
Well, I sort of suspect you had better.  So, unless you believe that Gat's 
example was utterly idiotic, I think you can start explaining from right 
there.

> I think the objection to macros has at this point been painted into a
> very small corner.

I drastically disagree.  This is just one example, that was given by one of 
the most vocal people from your side, and apparently not yet denounced
as idiotic, despite my asking so repeatedly about it, so presumably agreed
with by your side at large.  So, I'm focusing on it until its import is 
clarified.  Once that is done, we can tackle the many other open issues.

For example, the fact that Gat himself says that if what I want to write
are normal applications, macros are not for me: only for those who want
to push the boundaries of the possible are they worthwhile.  Do you think
THAT is idiotic, or wise?  Please explain either the reason of the drastic
disagreements in your camp, or why most of you do keep trying pushing
macros (and lisp in general) at those of us who are NOT particularly
interested in "living on the edge" and running big risks for their own sake,
accordingly to your answer to the preceding question, thanks.

"Small corner"?!  You MUST be kidding.  Particularly given that so many
on your side don't read what I write, and that you guys answer the same
identical questions in completely opposite ways (see below for examples
of both), I don't, in fact, see how this stupid debate will ever end, except
by exhaustion.  Meanwhile, "the objection to macros" has only grown
larger and larger with each idiocy I've seen spouted in macros' favour,
and with each mutual or self-contradiction among the macros' defenders.


>> ...If all you do with your macros is what you could
>> do with HOF's, it's silly to have macros in addition to HOF's
> 
> There is one c.l.l. denizen/guru who agrees with you. I believe his

...and there's another who has just answered in the EXACTLY opposite
way -- that OF COURSE macros can do more than HOF's.  So, collectively 
speaking, you guys don't even KNOW whether those macros you love so
much are really necessary to do other things than non-macro HOFs allow
(qualification inserted to try to divert the silly objection, already made 
by others on your side, that macros _are_ functions), or just pretty things
up a little bit.  Would y'all mind coming to some consensus among you
experienced users of macros BEFORE coming to spout your wisdom over
to us poor benigthed non-lovers thereof, THANKYOUVERYMUCH...?

>> far from all).  This is far from the first time I'm explaining this, btw.
> 
> Oh. OK, now that you mention it I have been skimming lately.

In this case, I think it was quite rude of you to claim I was not answering
questions, when you knew you were NOT READING what I wrote.


As you claim that macros are just for prettying things up, I will restate
(as you may not have read it) one of the many things I've said over and
over on this thread: I do not believe the minor advantage of prettying 
things up is worth the complication, the facilitation of language 
divergence between groups, and the deliberate introduction of multiple
equivalent ways to solve the same problem, which I guess you do know
I consider a bad thing, one that impacts productivity negatively.


Alex
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <gat-1210031917230001@dialin-099.jpl.nasa.gov>
In article <························@news2.tin.it>, Alex Martelli
<·······@yahoo.com> wrote:

> Let's start with that WITH-CONDITION-MAINTAINED example of Gat.  Remember 
> it?  OK, now, since you don't appear to think it was an idiotic example, 
> then SHOW me how it takes the code for the condition it is to maintain and
> the (obviously very complicated: starting a reactor, operating the reactor,
> stopping the reactor -- these three primitives in this sequence) program 
> over which it is to maintain it, and how does it modify that code to ensure
> this purpose.  Surely, given its perfectly general name, that macro does not
> contain, in itself, any model of the reactor; so it must somehow infer it 
> (guess it?) from the innards of the code it's analyzing and modifying.

It is not necessary to exhibit a theory of how WITH-CONDITION-MAINTAINED
actually works to understand that if one had such a theory one can package
that theory for use more attractively as a macro than as a function.  It
is not impossible to package up this functionality as a function, but it's
very awkward.  Control constructs exist in programming languages for a
reason, despite the fact that none of them are really "necessary".  For
example, we can dispense with IF statements and replace them with a purely
functional IF construct that takes closures as arguments.  Or we can do
things the Java way and create a new Conditional object or some such
thing.  But it's more convenient to write an IF statement.

The claim that macros are useful is nothing more and nothing less than the
claim that the set of useful control constructs is not closed.  You can
believe that or not.  To me it is self-evidently true, but I don't know
how to convince someone that it's true who doesn't already believe it. 
It's rather like arguing over whether the Standard Model of Physics covers
all the useful cases.  There's no way to know until someone stumbles
across a useful case that the Standard Model doesn't cover.

> For example, the fact that Gat himself says that if what I want to write
> are normal applications, macros are not for me: only for those who want
> to push the boundaries of the possible are they worthwhile.  Do you think
> THAT is idiotic, or wise?  Please explain either the reason of the drastic
> disagreements in your camp, or why most of you do keep trying pushing
> macros (and lisp in general) at those of us who are NOT particularly
> interested in "living on the edge" and running big risks for their own sake,
> accordingly to your answer to the preceding question, thanks.

I can't speak for anyone but myself of course, but IMO nothing worthwhile
is free of risks.  I also think you overstate the magnitude of the risk. 
You paint nightmare scenarios of people "changing the language"
willy-nilly in all sorts of divergent ways, but 1) in practice on a large
project people tend not to do that and 2) Lisp provides mechanisms for
isolating changes to the language and limiting the scope of their effect. 
So while the possibility exists that someone will change the language in a
radical way, in practice this is not really a large risk.  The risk of
memory corruption in C is vastly larger than the risk of "language
corruption" in Lisp, and most people seem to take that in stride.

> ...and there's another who has just answered in the EXACTLY opposite
> way -- that OF COURSE macros can do more than HOF's.  So, collectively 
> speaking, you guys don't even KNOW whether those macros you love so
> much are really necessary to do other things than non-macro HOFs allow
> (qualification inserted to try to divert the silly objection, already made 
> by others on your side, that macros _are_ functions), or just pretty things
> up a little bit.

But all any high level language does is "pretty things up a bit".  There's
nothing you can do in any language that can't be done in machine
language.  "Prettying things up a bit" is the whole point.  Denigrating
"prettying things up a bit" is like denigrating cars because you can get
from here to there just as well by walking, and all the car does is "speed
things up a bit".

E.
From: Russell McManus
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <874qyh4674.fsf@thelonious.dyndns.org>
Alex Martelli <·····@aleax.it> writes:

> Oh, and if you're one of those who disapprove of Gat's example feel free
> to say so, but until I hear a substantial majority denouncing it as idiotic 
> (and I haven't seen anywhere near this intensity of disapproval for it from 
> your camp) I'm quite justifyied in taking it as THE canonical example of a 
> macro doing something that is clearly outside the purview of normal tools 
> such as functions and classes.

My favorite example of the power of macros is the fact that CLOS,
the common lisp object system, could be added into a pre-CL lisp
just using defmacro.  This shows how lisp is a "programmable programming
language", as someone famous once said.

-russ
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <f0Bhb.21$KR3.5771@typhoon.nyu.edu>
Alex Martelli wrote:

> Kenny Tilton wrote:
> 
....
> 
> The very 'feature' that was touted by Erann Gat as macros' killer advantage
> in the WITH-CONDITION-MAINTAINED example he posted is the crucial
> difference: functions (HO or not) and classes only group some existing code
> and data; macros can generate new code based on examining, and presumably to
> some level *understanding*, a LOT of very deep things about the code 
> arguments they're given.  If all you do with your macros is what you could
> do with HOF's, it's silly to have macros in addition to HOF's -- just 
> MTOWTDItis encouraging multiple different approaches to solve any given 
> problem -- this, of course, in turn breeds divergence when compared to a
> situation in which just one approach is encouraged.  If you do use the 
> potential implied in that example from Gat, to do things that functions and 
> classes just couldn't _begin_ to, it's worse -- then you're really 
> designing your own private divergent language (which most posters from
> the Lisp camp appear to assert is an unalloyed good, although admittedly
> far from all).  This is far from the first time I'm explaining this, btw.

I am extremely careful to design new macros for my "extensions".  And 
when I do so I do it in my specialized packages.  Moreover, I am 
personally against blindly importing names when you do not actually need to.

This may or may not cause language divergence.  It is a social issue 
that is rather independent.  For example, people forget Greenspun's 
Tenth Rule of programming every other day and continue to diverge :)


> 
> Oh, and if you're one of those who disapprove of Gat's example feel free
> to say so, but until I hear a substantial majority denouncing it as idiotic 
> (and I haven't seen anywhere near this intensity of disapproval for it from 
> your camp) I'm quite justifyied in taking it as THE canonical example of a 
> macro doing something that is clearly outside the purview of normal tools 
> such as functions and classes.  As I recall there was a lot of that going
> on in TI labs, too -- instead of writing and using compilers for hardware
> description languages, circuit simulators, etc, based on appropriate and
> specialized languages processed with the help general-purpose ones,
> the specialized languages (divergent and half-baked) were embedded in
> programs coded in the general-purpose languages (Lisp variants, including 
> Scheme; that was in 1980) using macros that were supposed to do
> everything but serve you coffee while you were waiting -- of course when
> the snippets you passed (to represent hardware operation) were correct
> from the GP language viewpoint but outside the limited parts thereof that
> the macros could in fact process significantly down to circuit design &c,
> the error messages you got (if you were lucky enough to get error
> messages rather than just weird behavior) were QUITE interesting.

What people were doing not too long ago (1998) in a major electronic CAD 
company was to develop special intermediate languages to represent some 
design modules (we are talking about a not-so-cheap application here). 
Guess what.  They were using a tabbed format.  Going from version 1.0 of 
the product to version 2.0 involved writing a complex "migration" tool, 
as the previous format would break (not to mention the common place "cut 
and paste" errors).

How would you do that today?  You would write a XML DTD (or Schema, if 
you are so inclined) to achieve the same goal.  Now, given that XML is 
S-expr in a drag, Greenspun's Tenth applies again.

This has nothing to do with HOF vs Macros etc etc, but it shows that you 
are always using some "language design" thingy while you program.  After 
all, Stroustroup correctly said that "library design" is "language 
design".  Jumping back to the topic, the bottom line is that you want 
both macros and HOFs.  If you do not want both you are just reconfirming 
Greenspun's Tenth Rule of Programming :)


> 
>>One popular macro is WITH-OUTPUT-TO-FILE. My budding RoboCup starter kit
>>was a vital WITH-STD-ATTEMPT macro. Oh god, no! I need to see the ANSI
> 
> 
> Do they do things a HOF or class could do?  If so why bother using such
> an over-powered tool as macros instead of HOFs or classes?  If not, how do
> they specially process and understand code snippets they're passed?

Because you have them and because they are easier to use than a HOF.  If 
you have both you can make the best of both.  If you miss either, you 
have one less tool in your belt.  As for the previous examples, you do 
not necessarily need to understand the code snippets that are passed to 
the macros.  Most of the time macros are used as code transformations. 
If you use them carefully, then your (Common Lisp) programs get more 
succinct and more readable (and, incidentally more efficient, as Common 
Lisp can use macros to shortcut the road to the *NATIVE CODE* compiler). 
You cannot achieve this effect if you do not have both.

Cheers
--
marco
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F85A6E4.3050402@nospam.com>
Alex Martelli wrote:

> Doug Tolton wrote:
>    ...
> 
>>don't know me or my background.  Alex has stated on many occasions that
>>he has not worked with Macros, but that he is relying on second hand
>>information.
> 
> 
> I never used Common Lisp in production: in the period of my life when I
> was hired (by Texas Instruments) specifically for my knowledge of "Lisp",
> that meant Scheme and a host of other dialects (mostly but not entirely now
> forgotten).  I did use things that "passed for" macros in those dialects:
> I had no choice, since each TI lab or faction within the lab was using a
> different divergent mutant thing, all named "lisp" (save a few were named
> "scheme" -- hmmm, I do believe that some were using Prolog, too, but I
> did not happen to use it in TI), with some of the divergence hinging on
> locally developed sets of macros (and some on different vendors/versions).
> 
> For all I know, CLisp's macros are SO head and shoulders above any of a
> quarter century ago that any vaguely remembered technical problem from 
> back then may be of purely historical interest.  I do believe that the
> divergence problem has more to do with human nature and sociology, and 
> that putting in a language features that encourage groups and subgroups 
> of users to diverge that language cannot be compensated by technical
> enhancements -- it _will_, in my opinion, cause co-workers in any middle- 
> or large-sized organization to risk ending up standing on each others' 
> feet, rather than on each others' shoulders. (Remedies must of course 
> be sociological and lato sensu political first and foremost, but the way
> the language & tools are designed CAN help or hinder).
I can understand and respect honest differences of opinions.  I too 
believe that causes of divergence are largely sociological.  I differ 
though in thinking that features which allow divergence will necessarily 
result in divergence.

I have this personal theory (used in the non-strict sense here) that 
given enough time any homogenous group will split into at least two 
competing factions.  This "theory" of mine had it's roots in a nice 
dinner at Medieval Times in California.  We had arrived for dinner and 
we were waiting to be seated, everyone was milling around in a sort of 
shop/museum area.  We had been given "crowns" for dinner, but no one 
paid much attention to them.  We were one large group of people, bound 
by nothing and separated by nothing.  Then the one of the staff took a 
microphone and began giving us instructions.  She told us the color of 
our hats indicated the color of the Knight we would be rooting for, and 
tha we would be sitting only with people of similar colored crowns. 
Immediately the group (without instructions from the hostess) began 
separating into similarly colored groups.  Then they began calling the 
groups by color to be seated.  When they called out group, and we were 
ascending the staircase, I looked over my shoulder at the remaining 
groups.  I was utterly shocked to see apparent hatred and revulsion of 
our group on people's faces.  To me this was a game, but to some people 
in the crowd, having a different colored crown was a serious cause for 
emnity.

I have long looked back on that incident, and I have since compared it 
to many situations I have observed.  Over time it seems to me that human 
beings are incapable of remaining as one single cohesive group, rather 
that they will always separate into several competing factions.  Or at 
the very least groups will splinter off the main group and form their 
own group.

So it doesn't surprise me when groups splinter and diverge if they are 
not strictly controlled from an organizational or sociological point of 
view.

However in the opensource world I expect splinters to happen frequently, 
simply because there is little to no organizational control.  Even 
Python hasn't been immune to this phenomenon with both Jython and 
Stackless emerging.

Some people want power and expressiveness.  Some people want control and 
uniformity.  Others still will sacrifice high level constucts for raw 
pedal to the metal speed, while others wouldn't dream of this sacrifice.

What I'm getting at is that I can understand why people don't like 
Macros.  As David Mertz said, some people are just wired in dramatically 
different ways.

> 
> So, I'm nowhere near an _expert_ -- over 20 years' hiatus ensures I
> just can't be.  But neither is it totally 2nd hand information, and if
> I gave the mistaken impression of never having used macros in a
> production setting I must have expressed myself badly.  I do know I
> jumped on the occasion of moving to IBM Research, and the fact that
> this would mean going back to APL instead of "lisp" (in the above
> vague sense) did matter somewhat in my glee, even though I still 
> primarily thought of myself as a hardware person then (the programming 
> was needed to try out algorithms, simulate possible hardware 
> implementations thereof, etc -- it was never an end in itself).
> 
Thank you for that clarification.  I must have been mis-interpreting 
something, because I did think you had never used them.
> 
> 
>>I don't claim to be a guru on Lisp, however I believe I understand it
>>far better than Alex does.  If the people who actually know and use
>>Common Lisp think I am mis-speaking and mis-representing Lisp, please
>>let me know and I will be quiet.
> 
> 
> Give that I've heard "everything and its opposite" (within two constant
> parameters only: S-expressions are an unalloyed good -- macros are good,
> some say unconditionally, others admit they can be prone to abuse) from
> posters on this thread from "people who actually know and use" Lisp, I
> don't know how you could "mis-speak and mis-represent" as long as you
> stick to the two tenets of party doctrine;-).
> 
For me it isn't about party doctrine. :-p  My mindset very closely 
matches Paul Grahams.  I can understand why other people have a 
different mindset, and from what you've said I can even understand why 
you don't like Macros, I just have a different viewpoint.

What get's me is when people (and I do this sometimes as well) expess an 
opinion as fact, and that all rational people will agree with them.  So, 
for what it' worth, for the times I have expressed my opinion as the one 
true way of thinking, I'm sorry.
> 
> 
>>Like I said, I'm not an expert at Lisp, but I think I understand the
>>spirit and semantics of Lisp far better than Alex, and from what I've
> 
> 
> If by Lisp you mean Common Lisp and exclude Scheme, I'm sure you do; if
> Scheme is to be included, then I'm not sure (but it's quite possible,
> nevertheless) -- at least the "spirit" of the small core and widespread
> HOFs w/single-namespace seem to be things I understand more (but the
> "spirit" of why it's so wonderful to have extensible syntax isn't:-).

Honestly I've only used scheme in trivial things.  My preference has 
been more towards Common Lisp, primarily because I need it for building 
real systems, rather than doing language research.

I'm sure there many things that you know that I don't.  From what I 
understand you've been at this a bit longer than I have.  I've only been 
  doing serious programming for a little over ten years now.  In that 
time I have been involved with some very large projects on a very large 
scale.  I think I understand the concepts of abstraction and code reuse 
pretty well, and how to build large systems that integrate the efforts 
of numerous people.

I personally just don't believe macros are "evil" per se.  I believe 
they like any other tool can be used effectively, or misused 
effectively.  However most of my problems don't come from people who 
misuse advanced features of the language, rather they come from people 
who don't understand basic concepts of optimization and code reuse.

In any event, I think Lisp and Python are both great languages.  I use 
Python every day at work, and I work on learning more about Lisp (and a 
top secret pet project ;) ) every day.  I very much respect your 
knowledge Alex, because I do believe you have some good insights, and I 
do enjoy discussing issues that we disagree on (when we aren't being 
"bristly" ;) ) because you have many times helped me to understand my 
own point of view better.  So even though we don't always agree, I still 
appreciate your opinions.

-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1pjhb.4408$dn6.1383@newsread4.news.pas.earthlink.net>
Doug Tolton:
> I have this personal theory (used in the non-strict sense here) that
> given enough time any homogenous group will split into at least two
> competing factions.

Reminds me of Olaf Stapledon's "First and Last Men"?  His
civilizations often had two roughtly equal but opposing components.

Also reminds me of learning about the blue eyed/brown eyed
experiment in my sociology class in high school.  As it turns out,
I was the only blue-eyed person in the class of 25 or so.  :)

> Over time it seems to me that human
> beings are incapable of remaining as one single cohesive group, rather
> that they will always separate into several competing factions.  Or at
> the very least groups will splinter off the main group and form their
> own group.

Not necessarily "competing", except in a very general sense.  Is
Australian English in competition with Canadian English?

> However in the opensource world I expect splinters to happen frequently,
> simply because there is little to no organizational control.  Even
> Python hasn't been immune to this phenomenon with both Jython and
> Stackless emerging.

As well as PyPy and (more esoterically) Vyper.

Excepting the last, all have had the goal of supporting the C Python
standard library where reasonably possible.  When not possible
(as the case with Jython and various C extensions), then supporting
the native Java libraries.

> "bristly" ;)

Ohh!  Good word!  I had forgotten about it.

                    Andrew
                    ·····@dalkescientific.com
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <0Kjhb.5763034$cI2.814308@news.easynews.com>
Andrew Dalke wrote:

> Doug Tolton:
> 
>>I have this personal theory (used in the non-strict sense here) that
>>given enough time any homogenous group will split into at least two
>>competing factions.
> 
> 
> Reminds me of Olaf Stapledon's "First and Last Men"?  His
> civilizations often had two roughtly equal but opposing components.
I haven't read it, I may have to check it out.
> 
> Also reminds me of learning about the blue eyed/brown eyed
> experiment in my sociology class in high school.  As it turns out,
> I was the only blue-eyed person in the class of 25 or so.  :)
I'm not familiar with this experiment.  What is it about, and what are 
the results?
> 
> 
>>Over time it seems to me that human
>>beings are incapable of remaining as one single cohesive group, rather
>>that they will always separate into several competing factions.  Or at
>>the very least groups will splinter off the main group and form their
>>own group.
> 
> 
> Not necessarily "competing", except in a very general sense.  Is
> Australian English in competition with Canadian English?
I guess it comes more into play when there is some limited resource put 
into play (eg Darwin), such as winning a prize, making money, number of 
people using your system.  I agree not everything is a direct 
competition, but I bet if you started comparing Australian English to 
Canadian English with both types of speakers, eventually serious 
disagreement about some minute point would break out.
> 
> 
>>However in the opensource world I expect splinters to happen frequently,
>>simply because there is little to no organizational control.  Even
>>Python hasn't been immune to this phenomenon with both Jython and
>>Stackless emerging.
> 
> 
> As well as PyPy and (more esoterically) Vyper.
> 
> Excepting the last, all have had the goal of supporting the C Python
> standard library where reasonably possible.  When not possible
> (as the case with Jython and various C extensions), then supporting
> the native Java libraries.
I'm not saying they aren't good choices, or that they can even decide to 
work together, rather that over time groups tend to diverge.  Look at 
Unix/Linux/FreeBsd as an example.  I'm sure there are times when 
divergent groups die out and re-enter the main branch as well.
> 
> 
>>"bristly" ;)
> 
> 
> Ohh!  Good word!  I had forgotten about it.
> 
I have to give the credit to David Mertz on that one.  He used it in 
correspondence with me, and I liked it a lot too.

-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pO0ib.202192$hE5.6822673@news1.tin.it>
Doug Tolton wrote:
   ...
> I can understand and respect honest differences of opinions.  I too

If so, that makes you an exception in the chorus of lispers who are
screaming against my alleged idiocy and cluelessness (though I
seem to remember you also did, but I may be confusing people "on
your side" -- it's been a LONG and unpleasant thread).

> believe that causes of divergence are largely sociological.  I differ
> though in thinking that features which allow divergence will necessarily
> result in divergence.

I don't think it _necessarily_ will, just that it increases probability by 
enough to be a concausal factor.


> I have this personal theory (used in the non-strict sense here) that
> given enough time any homogenous group will split into at least two
> competing factions.  This "theory" of mine had it's roots in a nice

Unless there's a common enemy who's perceived to be threatening
enough to the whole group -- this is probably the single strongest
unifying factor ("united we stand, divided we fall" -- if people are scared
enough to believe this, they may then remain united).

But the amount of time and other external factors needed to eventually 
promote divergence varies with internal factors -- and in cases where
technology plays a key role in the group, then the details of that
technology matter.  Some technological aspects intrinsically promote
convergence and cooperation and thus may help counteract sociological
factors working in the other direction -- other technological aspects
facilitate divergence.  "In the long run we're all dead" (Keynes), so if
the time needed for divergence is not enough, divergence will not
happen within the group's lifetime;-).


> However in the opensource world I expect splinters to happen frequently,
> simply because there is little to no organizational control.  Even

And you would be wrong: forks are much less frequent than your theory
predicts.  Read some Eric Raymond to understand this, he's got good
ideas about these issues.

> Python hasn't been immune to this phenomenon with both Jython and
> Stackless emerging.

Neither of them is a fork, nor a splinter, nor a split.  Jython tracks the 
Python standard (as much as it can with far too few core developers)
and the Python standard has been modified to allow Jython to conform
on some points (e.g. timing of garbage collection).  Stackless has been
rewritten to become a patch as small as possible on standard Python.

And if you look at the people involved, well, I've seen Samuele Pedroni
(Jython's chief maintainer), Christian Tismer (Mr Stackless), Guido van
Rossum (Mr Python) -- and many others, including yours truly -- sitting in 
the same room hacking at the same project during a "sprint" this summer.
And happily guzzling beer and/or wine at the barbecue afterwards, of course.

There's just no "splinter" effect in all of this -- just different 
technology needs (e.g. a need to cooperate with some Java libraries 
seamlessly), requiring different implementations of the same language, 
Python.

> Some people want power and expressiveness.  Some people want control and
> uniformity.  Others still will sacrifice high level constucts for raw
> pedal to the metal speed, while others wouldn't dream of this sacrifice.

And people who have freely chosen Python appear to share enough core
values (simplicity, one obvious way to do it, etc) to be very far from any
splintering yet.  Why does that surprise you?

> What I'm getting at is that I can understand why people don't like
> Macros.  As David Mertz said, some people are just wired in dramatically
> different ways.

Well, it's nice that you understand this.  I just wish more people on your
side did -- most seem to think I'm crazy, my posts boggle the mind, etc.


> What get's me is when people (and I do this sometimes as well) expess an
> opinion as fact, and that all rational people will agree with them.  So,
> for what it' worth, for the times I have expressed my opinion as the one
> true way of thinking, I'm sorry.

I don't think there's anything worth apologizing for, in believing the 
opinion you hold is the true one.  Insulting people who hold a different
rational opinion is of course another issue.


> top secret pet project ;) ) every day.  I very much respect your
> knowledge Alex, because I do believe you have some good insights, and I
> do enjoy discussing issues that we disagree on (when we aren't being
> "bristly" ;) ) because you have many times helped me to understand my
> own point of view better.  So even though we don't always agree, I still
> appreciate your opinions.

Likewise -- for you and the other reasonable people on your side (right
now Pascal Costanza is the only one who comes to mind, but, as I said,
it's easy to start confusing people after a thread as long and confused
as this one).


I don't think macros are evil, either -- I just don't want them in 
Python:-).  Let me give an example: one thing my main client is working on
is a specialized language that represents information-models (actions in
them are in embedded Python), presentation-data to guide generic clients
for GUI / web / print presentation, etc.  I do think we need macros there 
sooner or later (and sooner would be better;-) -- simply to help remove 
redundancy and duplication, because in this purely declarative language 
there are no "functions".  (Were it not for language/metalanguage confusion 
risks, and the issues of ensuring the clarity of error-diagnostics, python 
functions emitting code in the specialized language [which gets compiled
into Python], i.e. "functions that run at compile-time", would be the 
obvious solution, and we could hack them in within an afternoon -- but we
DO want to provide very clear and precise error diagnostics, of course, 
and the language/metalanguage issue is currently open).  You will note
that this use of macros involves none of the issues I have expressed about
them (except for the difficulty of providing good error-diagnostics, but 
that's of course solvable).


Alex
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <gqohb.28451$pv6.190@twister.nyc.rr.com>
Lulu of the Lotus-Eaters wrote:

> Alex Martelli:
> |>Why, thanks!  Nice to see that I'm getting on the nerves of _some_
> |>people, too, not just having them get on mine.
> 
> Doug Tolton <····@nospam.com> wrote previously:
> |Yes, this discussion is frustrating.  It's deeply frustrating to hear
> |someone without extensive experience with Macros arguing why they are
> |so destructive.
> 
> If that is meant to address Alex Martelli, it is very deeply misguided.
> If there is anyone who I can say with confidence has much more
> experience--and much better understanding--of macros (or of all things
> Lisp) than does Doug Tolton, it is Alex.
> 
> Yours, Lulu...
> 

Hey! No pulling rank! :) Actually, I think  we heard Mr. Martelli say 
something along these lines at one point, tho I grok that he does know 
his stuff.  As for having "a better understanding", hmmm, check your 
lotus, I think you'll find something in there about Beginner's Mind.

Alex reports his experience of The Divergence Problem and blames macros. 
Hell, I worked in Tall Buildings for years. I saw Divergence, 
Convergence, /and/ the dread Regurgitation Problems everywhere I went. 
No macros, tho, just groups of programmers.

So I think the groups are the problem.


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Z_Ahb.195516$hE5.6610440@news1.tin.it>
Kenny Tilton wrote:
   ...
>> Doug Tolton <····@nospam.com> wrote previously:
>> |Yes, this discussion is frustrating.  It's deeply frustrating to hear
>> |someone without extensive experience with Macros arguing why they are
>> |so destructive.
   ...
> Hey! No pulling rank! :) Actually, I think  we heard Mr. Martelli say
> something along these lines at one point, tho I grok that he does know
> his stuff.  As for having "a better understanding", hmmm, check your
> lotus, I think you'll find something in there about Beginner's Mind.

Doug was not talking about understanding, but experience.  I've had
such experience -- perhaps not "extensive" enough for him? -- and I
have personally experienced and suffered the problems.


> Alex reports his experience of The Divergence Problem and blames macros.
> Hell, I worked in Tall Buildings for years. I saw Divergence,
> Convergence, /and/ the dread Regurgitation Problems everywhere I went.
> No macros, tho, just groups of programmers.
> 
> So I think the groups are the problem.

I never claimed that without macros there would be no possible problems
whatsoever.  Human biology guarantees that such sociological problems
remain possible.  However, technology aspects, as well as cultural ones,
can either ameliorate or exacerbate the issues.  Python's overall culture
of consensus and simplicity matters: at a BOF as OSCON, somebody was
asking "...so I don't know if I should just do the simple thing here or
rather do something clever..." and the audience immediately gave their
feedback -- if you think of it as "something clever", _don't do it_.
(Not in production code, not in code that you AND more relevantly many
others will have to maintain, enhance, and change for years to come).

Are you familiar with the "JAPH" idea, those bazillion clever ways that
Perl programmers have dreamed up to emit the string "just another perl
hacker" in delightfully contorted ways?  Well, somebody once asked how
a Pythonista would go about it -- and the answer was unanimous:
    print "Just another Python hacker"
Sure, this will get you no kudos for cleverness, but the point is that
cleverness does NOT garner kudos among Pythonistas.  Simplicity, clarity,
explicitness, directness -- these are the community's core values.  Do
we all always live by them?  No way -- we're not saints, just practical
guys trying to get our jobs done -- and perhaps make the world a little
better along the way.

Technological aspects interplay with the cultural ones.  Again speaking
in terms of ideals and targets, I quote Antoine de Saint-Exupery:
"La perfection est atteinte non quand il ne reste rien � ajouter, mais 
quand il ne reste rien � enlever." (perfection is achieved not when
nothing is left to add, but when nothing is left to take away).  Now,
since "practicality beats purity", one doesn't (e.g.) remove 'if' just
because it can reasonably be substituted by 'while' -- we're not talking,
in fact, about truly minimalist practice.  But the only apparently
irreducible use of macros would appear to be in (some form of) code
that "reasons about itself" (not just by simple reflection and
introspection, quite easy to achieve without macros, but in that
"with-condition-maintained" example which was apparently [or allegedly]
able to analyze and modify reactor-control code to affect the reactor's
temperature limits).  Do I need or want such exoterica in the kind of
code that I am interested in writing, and helping others write?  No way:
such "creative", deep merging of discourse and meta-discourse does not
appear to be at all necessary in these endeavours -- and if it not
strictly necessary, I would MUCH rather use a simpler, lighter-weight
tool that does not support it.  When I need to modify (e.g.) some
class's constructor at runtime, I can do it by such blazingly obvious
code as
    someclass.__new__ = staticmethod(costructor_implementation)
though the Lisp'er originally proposing such needs, in an attempt to
show how complicated Python's approach was, used a hugely messy call to
type.__setattr__ with a weirdly and unjustifiably long lambda in it.

Won't fly, friends.  We're simple, down-to-earth folks, doing simple,
down-to-earth things.  I suspect some kind of 10/90 rules apply: our
simple tools may be barely 10% of what CL has got, but they cover the
needs arising in 90% of applications.  (Maybe it's 15/85 or whatever:
no, I don't have scientific studies in the matter to quote so you
can exert your ingenuity at shooting them down:-).  When we need to
process some specialized language we may use roughly-traditional parser
technology, keeping language and meta-language separated, rather than
embed and entwine them inside each other.

My perhaps-not-extensive-enough experience with macros showed them
being used to merge language and meta-language -- in widely different
ways in different labs or even within a given lab -- while at the
same time other firms were using languages without macros (APL and
variants thereof) and processing them with different and separate
metalanguages AND thereby managing to achieve better (intra-firm, at
least) cooperation.  As "adventures in programming", those glorious
lisp-dialects-cum-hardware-description-languages-inside-them were,
no doubt, a hoot.  For somebody looking for a more productive way to
design chips, and particularly to foster cooperation in this design
task, they looked (and in retrospect still look) sub-optimal to me.

The macros ended up being used to bend and stretch the general
purpose language to express specialized issues (about hardware design,
in that case) which it was not optimally suited to express -- and
since it WAS a case of bending and stretching, it was inevitable that
each different lab and faction would stretch and bend in divergent
directions.  The computer-scientists in question were no doubt happy
as larks with their toys and in some cases their shiny new lisp
machines (I think TI ended up making a LM of their own a bit later,
but that was after my time); us engineers weren't _quite_ as happy,
though.  And the chips didn't get designed as well, nor as fast...


Alex
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <6CZgb.3273$dn6.860@newsread4.news.pas.earthlink.net>
Doug Tolton:
> I believe the crux of our difference is that you don't want to give
> expressive power because you believe it will be misused.  I on the
> other hand want to give expressive power because I believe it could be
> used correctly most of the time.  For the times when it's not, well
> that's why I have debugging skills.  Sadly not eveyone uses looping
> the way I would, but using my brain I can figure out what they are
> doing.

That point has been made over and over to you.  The argument is
that expressive power for a single developer can, for a group of
developers and especially those comprised of people with different
skill sets and mixed expertise, reduce the overall effectiveness of the
group.

If this is indeed the crux, then any justification which says "my brain"
and "I" is suspect, because that explicitly ignores the argument.  By
comparison, Alex's examples bring up
  - teaching languages to others
  - interference between his code and others' (the APL example)
  - production development
      "Imagine a group of, say, a dozen programmers, working together ...
       to develop a typical application program of a few tens of thousands
of
       function points -- developing about 100,000 new lines of delivered
code
       plus about as much unit tests,  and reusing roughly the same amount"
  - writing books for other people

which at the very least suggests the expertise and background
by which to evaluate the argument.  It may be that his knowledge of
how and when to use macros is based on the statements of people he
respects rather than personal experience, but given the discussions on
this topic and the exhibited examples of when macros are appropriately
used, it surely does seem that metaclasses, higher-level functions, and
iterators can be used to implement a solution with a roughly equal amount
of effort and clarity.  Th only real advantage to macros I've seen is the
certainty of "compile-time" evaluation, hence better performance than
run-time evaluation

Alex:
> >For some (handwaving-defined) "appropriate" approach to measuring
> >"length" (and number of lines is most definitely not it), it is ONE

You:
> Both from my experience and Fred Brooks it's the only actual way I've
> seen of measuring the time it will take to write a program.

You mean "estimating"; for measuring I suspect you can use a
combination of a clock and a calendar.  (This from a guy who recently
posted that the result of 1+1 is 4.  ;)

You should use McConnell as a more recent reference than Brooks.
(I assume you are arguing from Mythical Man Month?  Or from his
more recent writings?)  In any case,  in Rapid Development McConnell
considers various alternatives then suggests using LOC, on the view
that LOC is highly correlated with function points (among 3rd
generation programming languages! see below) and that LOC has a
good correlation to development time, excluding extremes like APL
and assembly.  However, his main argument is that LOC is an easy
thing to understand.

The tricky thing about using McConnell's book is the implications
of table 31-2 in the section "Using Rapid Development Languages",
which talks about languages other than the 3rd generation ones used
to make his above estimate.

  Table 31-2 shows the approximate "language levels" for a wider
  variety of languages than Table 31-1.  The "language level" is
   intended to be a more specific replacement for the level implied
   by the phrases "third-generation language" and "fourth-generation
   language."  It is defined as the number of assembler statements
   that would be needed to replace one statement in the higher-level
   language.  ...

   The numbers ... are subject to a lot of error, but they are the best
   numbers available at this time, and they are accurate enough to
   support this point:  from a development poing of view, you should
   implement your projects in the highest-level language possible.  If
   you can implement something in C, rather than assembler, C++
   rather than C, or Visual Basic rather than C++, you can develop
   faster.

And here's Table 31-2

                           Statements per
Language          Level    Function Point
--------          -----    --------------
Assembler          1           320
Ada 83             4.5          70
AWK               15            25
C                  2.5         125
C++                6.5          50
Cobol (ANSI 85)    3.5          90
dBase IV           9            35
spreadsheets      ~50            6
Focus               8           40
Fortran 77          3          110
GW Basic            3.25       100
Lisp                5           65
Macro assembler     1.5        215
Modula 2            4           80
Oracle              8           40
Paradox             9           35
Pascal              3.5         90
Perl               15           25
Quick Basic 3       5.5         60
SAS, SPSS, etc.    10           30
Smalltalk (80 & V) 15           20
Sybase              8           40
Visual Basic 3     10           30

  Source: Adapted from data in 'Programming Languages
                                    Table' (Jones 1995a)


I'll use Perl as a proxy for Python; given that that was pre-OO
Perl I think it's reasonable that that sets a minimum level for
Python.  Compare the Lisp and Perl numbers

Lisp                5           65
Perl               15           25

and the differences in "statements per function point" (which isn't
quite "LOC per function point") is striking.  It suggests that
Python is more than twice as concise as Lisp, so if LOC is
used as the estimate for implementation time then it's a strong
recommendation to use Python instead of Lisp because it
will take less time to get the same thing done.  And I do believe
Lisp had macros back in the mid-1990s.

Sadly, this is a secondary reference and I don't have a
copy of
  Jones, Capers, 1995a. "Software Productivity Research
     Programming Languages Table," 7th ed. March 1995.
and the referenced URL of www.spr.com/library/langtbl.htm
is no longer valid and I can't find that table on their site.


> Well that was a long winded digression into something that is
> completely un-related to Macros.  Seems like a good argument why
> re-binding the buildins is bad though

It was a long winded digression into how LOC can be a
wrong basis by which to judge the appropriateness of a
language feature.

> >a plus -- and Java's use of { } for example ensures NON-uniformity
> >on a lexical plane, since everybody has different ideas about where
> >braces should go:-).
> >
> Where braces should go is a trivial issues.  However if braces is an
> issue that seriously concerns you then I can see why macros are giving
> you a heart attack.

See that smiley and the "--"?  This is a throwaway point at the end
of the argument, and given Alex's noted verboseness, if it was a
serious point he would have written several pages on the topic.

                    Andrew
                    ·····@dalkescientific.com
From: Rainer Joswig
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <joswig-6AE02B.15545208102003@news.fu-berlin.de>
In article <··················@newsread4.news.pas.earthlink.net>,
 "Andrew Dalke" <······@mindspring.com> wrote:

snip
 
> And here's Table 31-2
> 
>                            Statements per
> Language          Level    Function Point
> --------          -----    --------------
> Assembler          1           320
> Ada 83             4.5          70
> AWK               15            25
> C                  2.5         125
> C++                6.5          50
> Cobol (ANSI 85)    3.5          90
> dBase IV           9            35
> spreadsheets      ~50            6
> Focus               8           40
> Fortran 77          3          110
> GW Basic            3.25       100
> Lisp                5           65
> Macro assembler     1.5        215
> Modula 2            4           80
> Oracle              8           40
> Paradox             9           35
> Pascal              3.5         90
> Perl               15           25
> Quick Basic 3       5.5         60
> SAS, SPSS, etc.    10           30
> Smalltalk (80 & V) 15           20
> Sybase              8           40
> Visual Basic 3     10           30
> 
>   Source: Adapted from data in 'Programming Languages
>                                     Table' (Jones 1995a)

I thought these numbers were bogus. Weren't many
of them just guesses with actually zero data
or methodology behind them???


snip
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3r81no4bq.fsf@javamonkey.com>
Rainer Joswig <······@lispmachine.de> writes:

> In article <··················@newsread4.news.pas.earthlink.net>,
>  "Andrew Dalke" <······@mindspring.com> wrote:
> 
> snip
>  
> > And here's Table 31-2
> > 
> >                            Statements per
> > Language          Level    Function Point
> > --------          -----    --------------
> > Assembler          1           320
> > Ada 83             4.5          70
> > AWK               15            25
> > C                  2.5         125
> > C++                6.5          50
> > Cobol (ANSI 85)    3.5          90
> > dBase IV           9            35
> > spreadsheets      ~50            6
> > Focus               8           40
> > Fortran 77          3          110
> > GW Basic            3.25       100
> > Lisp                5           65
> > Macro assembler     1.5        215
> > Modula 2            4           80
> > Oracle              8           40
> > Paradox             9           35
> > Pascal              3.5         90
> > Perl               15           25
> > Quick Basic 3       5.5         60
> > SAS, SPSS, etc.    10           30
> > Smalltalk (80 & V) 15           20
> > Sybase              8           40
> > Visual Basic 3     10           30
> > 
> >   Source: Adapted from data in 'Programming Languages
> >                                     Table' (Jones 1995a)
> 
> I thought these numbers were bogus. Weren't many of them just
> guesses with actually zero data or methodology behind them???

Well, here are some other interesting entries (from the table on p.89
of Jones's _Applied Software Measurement_):

Language          Level    Function Point
--------          -----    --------------
CLOS               12.0        27
KSH                12.0        27
PERL               12.0        27 [it had 27, while the the other table had 25]
MAKE               15.0        21

I'm not sure what to make of CLOS being separate from Common Lisp, but
there it is. But it's sort of moot because by this measure, MAKE is a
higher level language than either Lisp, Perl, or C++. Personally, I
think I'll be looking for another metric.

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Rainer Joswig
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <joswig-E79F9B.17403808102003@news.fu-berlin.de>
In article <··············@javamonkey.com>,
 Peter Seibel <·····@javamonkey.com> wrote:

> Rainer Joswig <······@lispmachine.de> writes:
> 
> > In article <··················@newsread4.news.pas.earthlink.net>,
> >  "Andrew Dalke" <······@mindspring.com> wrote:
> > 
> > snip
> >  
> > > And here's Table 31-2
> > > 
> > >                            Statements per
> > > Language          Level    Function Point
> > > --------          -----    --------------
> > > Assembler          1           320
> > > Ada 83             4.5          70
> > > AWK               15            25
> > > C                  2.5         125
> > > C++                6.5          50
> > > Cobol (ANSI 85)    3.5          90
> > > dBase IV           9            35
> > > spreadsheets      ~50            6
> > > Focus               8           40
> > > Fortran 77          3          110
> > > GW Basic            3.25       100
> > > Lisp                5           65
> > > Macro assembler     1.5        215
> > > Modula 2            4           80
> > > Oracle              8           40
> > > Paradox             9           35
> > > Pascal              3.5         90
> > > Perl               15           25
> > > Quick Basic 3       5.5         60
> > > SAS, SPSS, etc.    10           30
> > > Smalltalk (80 & V) 15           20
> > > Sybase              8           40
> > > Visual Basic 3     10           30
> > > 
> > >   Source: Adapted from data in 'Programming Languages
> > >                                     Table' (Jones 1995a)
> > 
> > I thought these numbers were bogus. Weren't many of them just
> > guesses with actually zero data or methodology behind them???
> 
> Well, here are some other interesting entries (from the table on p.89
> of Jones's _Applied Software Measurement_):
> 
> Language          Level    Function Point
> --------          -----    --------------
> CLOS               12.0        27
> KSH                12.0        27
> PERL               12.0        27 [it had 27, while the the other table had 25]
> MAKE               15.0        21
> 
> I'm not sure what to make of CLOS being separate from Common Lisp, but
> there it is. But it's sort of moot because by this measure, MAKE is a
> higher level language than either Lisp, Perl, or C++. Personally, I
> think I'll be looking for another metric.
> 
> -Peter

Just look at this:

http://www.theadvisors.com/langcomparison.htm

And read:

  The languages and levels in Table 2 were gathered in four ways.

    * Counting Function Points and Source Code
    * Counting Source Code
    * Inspecting Source Code
    * Researching Languages

and

  Researching Languages

  Research was done by reading descriptions and genealogies
  of languages and making an educated guess as to their levels. KL,
  CLOS, TWAICE, and FASBOL are examples of languages that were
  assigned tentative levels merely from descriptions of the
  language, rather than from actual counts.

Well, I guess CLOS is, ... about, say, hmm, scratching my head, hmm,
let's say 73.

Right?

Let's say it differently, the comparison is a BAD joke.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <4R%gb.3438$dn6.2083@newsread4.news.pas.earthlink.net>
Peter Seibel:
> PERL               12.0        27 [it had 27, while the the other table
had 25]

I double checked.  McConnell lists "25".

> MAKE               15.0        21
>
> I'm not sure what to make of CLOS being separate from Common Lisp, but
> there it is. But it's sort of moot because by this measure, MAKE is a
> higher level language than either Lisp, Perl, or C++. Personally, I
> think I'll be looking for another metric.

McConnell said that if you *could* do it in a given higher level
language then you should.  Eg, spreadsheets are listed as a very
high level language, but you wouldn't write a word processor
in one.

I don't know the background behind the paper you referenced.
I suspect is has the same qualifier.  If so, it's quite true that
using make for its domain is more appropriate than a more general
general purpose language.

                    Andrew
                    ·····@dalkescientific.com
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm1s9t$n0d$1@newsreader2.netcologne.de>
Rainer Joswig wrote:
> In article <··················@newsread4.news.pas.earthlink.net>,
>  "Andrew Dalke" <······@mindspring.com> wrote:
> 
> snip
>  
> 
>>And here's Table 31-2
>>
>>                           Statements per
>>Language          Level    Function Point
>>--------          -----    --------------
>>Assembler          1           320
>>Ada 83             4.5          70
>>AWK               15            25
>>C                  2.5         125
>>C++                6.5          50
>>Cobol (ANSI 85)    3.5          90
>>dBase IV           9            35
>>spreadsheets      ~50            6
>>Focus               8           40
>>Fortran 77          3          110
>>GW Basic            3.25       100
>>Lisp                5           65
>>Macro assembler     1.5        215
>>Modula 2            4           80
>>Oracle              8           40
>>Paradox             9           35
>>Pascal              3.5         90
>>Perl               15           25
>>Quick Basic 3       5.5         60
>>SAS, SPSS, etc.    10           30
>>Smalltalk (80 & V) 15           20
>>Sybase              8           40
>>Visual Basic 3     10           30
>>
>>  Source: Adapted from data in 'Programming Languages
>>                                    Table' (Jones 1995a)
> 
> 
> I thought these numbers were bogus. Weren't many
> of them just guesses with actually zero data
> or methodology behind them???

Apart from that, what does the author mean by "Lisp"? Is it Common Lisp 
or some other Lisp dialect? Scheme?

According to this table, Modula-2 and Lisp are in the same league - I 
have used both languages, and this just doesn't align with my experience.

Furthermore, CLOS can be regarded as a superset of Smalltalk. How can it 
be that Smalltalk is more than three times better than Lisp? Even if you 
take Scheme that doesn't come with an object system out of the box, you 
can usually add one that is at least as powerful as Smalltalk. Or did 
they add the LOC of infrastructure libraries to their results?


Pascal
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <n30hb.3450$dn6.315@newsread4.news.pas.earthlink.net>
Rainer Joswig
> > I thought these numbers were bogus. Weren't many
> > of them just guesses with actually zero data
> > or methodology behind them???

Pascal Costanza
> Apart from that, what does the author mean by "Lisp"? Is it Common Lisp
> or some other Lisp dialect? Scheme?

As I mentioned, I don't have the primary sources, so I can't
give any more information about the data.

In general, there are very few methodological studies on the
effectiveness of different languages on general purpose
programming problems when used by sets of people with
roughly comparable experience.  The only other one I have
is Prechelt's "An empirical comparison ..."
        http://www.ipd.uka.de/~prechelt/Biblio/
with the followup of Java v. Lisp at
        http://www.flownet.com/gat/papers/lisp-java.pdf
That data also suggests that Tcl/Perl/Python/Lisp development time
is comparable.

> According to this table, Modula-2 and Lisp are in the same league - I
> have used both languages, and this just doesn't align with my experience.

Good thing I didn't try to skew the data by leaving that out.  ;)

> Furthermore, CLOS can be regarded as a superset of Smalltalk. How can it
> be that Smalltalk is more than three times better than Lisp? Even if you
> take Scheme that doesn't come with an object system out of the box, you
> can usually add one that is at least as powerful as Smalltalk. Or did
> they add the LOC of infrastructure libraries to their results?

Again, I don't have the primary source.

                    Andrew
                    ·····@dalkescientific.com
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87vfqz2ulx.fsf@thalassa.informatimago.com>
"Andrew Dalke" <······@mindspring.com> writes:
> In general, there are very few methodological studies on the
> effectiveness of different languages on general purpose
> programming problems when used by sets of people with
> roughly comparable experience.  The only other one I have
> is Prechelt's "An empirical comparison ..."
>         http://www.ipd.uka.de/~prechelt/Biblio/
> with the followup of Java v. Lisp at
>         http://www.flownet.com/gat/papers/lisp-java.pdf
> That data also suggests that Tcl/Perl/Python/Lisp development time
> is comparable.

I'd be  interested in  a comparison of  maintenance time.   Perl feels
like a write-only language.


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <AQ_gb.129542$pZ5.1421881@news.easynews.com>
Andrew Dalke wrote:

> Doug Tolton:
> 
>>I believe the crux of our difference is that you don't want to give
>>expressive power because you believe it will be misused.  I on the
>>other hand want to give expressive power because I believe it could be
>>used correctly most of the time.  For the times when it's not, well
>>that's why I have debugging skills.  Sadly not eveyone uses looping
>>the way I would, but using my brain I can figure out what they are
>>doing.
> 
> 
> That point has been made over and over to you.  The argument is
> that expressive power for a single developer can, for a group of
> developers and especially those comprised of people with different
> skill sets and mixed expertise, reduce the overall effectiveness of the
> group.
Yes and I have repeatedly stated that I disagree with it.  I simply do 
not by that allowing expressiveness via high level constructs detracts 
from the effectiveness of the group.  That argument is plainly 
ridiculous, if it were true then Python would be worse than Java, 
because Python is *far* more expressive.
> 
> If this is indeed the crux, then any justification which says "my brain"
> and "I" is suspect, because that explicitly ignores the argument.  
Apparently you can't read very well.  I simply stated that I believe our 
point of contention to be that issue, I never stated I believe that 
because it's some vague theory inside my head.

> By
> comparison, Alex's examples bring up
>   - teaching languages to others
>   - interference between his code and others' (the APL example)
>   - production development
>       "Imagine a group of, say, a dozen programmers, working together ...
>        to develop a typical application program of a few tens of thousands
> of
>        function points -- developing about 100,000 new lines of delivered
> code
>        plus about as much unit tests,  and reusing roughly the same amount"
>   - writing books for other people
With the exception of writing books for other people, I have done all of 
those things.  I have worked on fairly large development teams > 20 
people.  I have built multi-million dollar systems.  I have taught 
people programming languages, both on the job and as a University 
Course.  So don't come off with this attitude of I have no idea what I'm 
talking about.

Macro's are precisely better for large groups of people.  Any time you 
are building systems with Large groups of people, and you want to have 
re-usable code, you abstract it.  There are all kinds of ways to do 
that, Macros are just one.  I have never seen any large successful 
coding project that does not abstract things well.  If you are incapable 
of abstracting software successful and usefully then no project will be 
successful, not if it's non-trivial.
> 
> which at the very least suggests the expertise and background
> by which to evaluate the argument.  It may be that his knowledge of
> how and when to use macros is based on the statements of people he
> respects rather than personal experience, but given the discussions on
> this topic and the exhibited examples of when macros are appropriately
> used, it surely does seem that metaclasses, higher-level functions, and
> iterators can be used to implement a solution with a roughly equal amount
> of effort and clarity.  Th only real advantage to macros I've seen is the
> certainty of "compile-time" evaluation, hence better performance than
> run-time evaluation
As I said to Alex, that's because you don't understand Macros.  Relying 
on what someone else says about Macros only gets you so far.  At some 
point, if you don't want to look like a complete idiot, you might want 
to really learn them or just shut up about them.  It's very difficult to 
have a conversation with someone who really doesn't know what they are 
talking about, but is instead just spouting an opinion they picked up 
from someone else.  The discussion doesn't go anywhere at that point.

Macros are like any things else, a tool in your tool box.  If you know 
how to use them they can be used very effectively.  If you don't, you 
can probably work around the problem and solve it a different way. 
However as the toolset differential gets bigger, the person with more 
tools in their arsenal will be able to outperform the people with less 
tools.
> 
> Alex:
> 
>>>For some (handwaving-defined) "appropriate" approach to measuring
>>>"length" (and number of lines is most definitely not it), it is ONE
> 
> 
> You:
> 
>>Both from my experience and Fred Brooks it's the only actual way I've
>>seen of measuring the time it will take to write a program.
> 
> 
> You mean "estimating"; for measuring I suspect you can use a
> combination of a clock and a calendar.  (This from a guy who recently
> posted that the result of 1+1 is 4.  ;)
No, what I was referring to wasn't estimation.  Rather I was referring 
to the study that found that programmers on average write the same 
number of lines of code per year regardless of the language they write 
in.  Therefore the only way to increase productivity is to write 
software in a language that uses less lines to accomplish something 
productive.  See Paul Grahams site for a discussion.
> 
> You should use McConnell as a more recent reference than Brooks.
> (I assume you are arguing from Mythical Man Month?  Or from his
> more recent writings?)  In any case,  in Rapid Development McConnell
> considers various alternatives then suggests using LOC, on the view
> that LOC is highly correlated with function points (among 3rd
> generation programming languages! see below) and that LOC has a
> good correlation to development time, excluding extremes like APL
> and assembly.  However, his main argument is that LOC is an easy
> thing to understand.
> 
> The tricky thing about using McConnell's book is the implications
> of table 31-2 in the section "Using Rapid Development Languages",
> which talks about languages other than the 3rd generation ones used
> to make his above estimate.
> 
>   Table 31-2 shows the approximate "language levels" for a wider
>   variety of languages than Table 31-1.  The "language level" is
>    intended to be a more specific replacement for the level implied
>    by the phrases "third-generation language" and "fourth-generation
>    language."  It is defined as the number of assembler statements
>    that would be needed to replace one statement in the higher-level
>    language.  ...
> 
>    The numbers ... are subject to a lot of error, but they are the best
>    numbers available at this time, and they are accurate enough to
>    support this point:  from a development poing of view, you should
>    implement your projects in the highest-level language possible.  If
>    you can implement something in C, rather than assembler, C++
>    rather than C, or Visual Basic rather than C++, you can develop
>    faster.
> 
> And here's Table 31-2
> 
>                            Statements per
> Language          Level    Function Point
> --------          -----    --------------
> Assembler          1           320
> Ada 83             4.5          70
> AWK               15            25
> C                  2.5         125
> C++                6.5          50
> Cobol (ANSI 85)    3.5          90
> dBase IV           9            35
> spreadsheets      ~50            6
> Focus               8           40
> Fortran 77          3          110
> GW Basic            3.25       100
> Lisp                5           65
> Macro assembler     1.5        215
> Modula 2            4           80
> Oracle              8           40
> Paradox             9           35
> Pascal              3.5         90
> Perl               15           25
> Quick Basic 3       5.5         60
> SAS, SPSS, etc.    10           30
> Smalltalk (80 & V) 15           20
> Sybase              8           40
> Visual Basic 3     10           30
> 
>   Source: Adapted from data in 'Programming Languages
>                                     Table' (Jones 1995a)
> 
> 
> I'll use Perl as a proxy for Python; given that that was pre-OO
> Perl I think it's reasonable that that sets a minimum level for
> Python.  Compare the Lisp and Perl numbers
> 
> Lisp                5           65
> Perl               15           25
You are saying that Python and Perl are similarly compact?!?
You have got to be kidding right?
Perl is *far* more compact than Python is.  That is just ludicrous.
> 
> and the differences in "statements per function point" (which isn't
> quite "LOC per function point") is striking.  It suggests that
> Python is more than twice as concise as Lisp, so if LOC is
> used as the estimate for implementation time then it's a strong
> recommendation to use Python instead of Lisp because it
> will take less time to get the same thing done.  And I do believe
> Lisp had macros back in the mid-1990s.
> 
> Sadly, this is a secondary reference and I don't have a
> copy of
>   Jones, Capers, 1995a. "Software Productivity Research
>      Programming Languages Table," 7th ed. March 1995.
> and the referenced URL of www.spr.com/library/langtbl.htm
> is no longer valid and I can't find that table on their site.
> 
It's always nice just to chuck some arbitrary table into the 
conversation which conveniently backs some poitn you were trying to 
make, and also conveniently can't be located for anyone to check the 
methodology.

If you want some real world numbers on program length check here:
http://www.bagley.org/~doug/shootout/

Most of those programs are trivially small, and didn't use Macros. 
Macros as well as high order functions etc only come into play in 
non-trivial systems.

I just don't buy these numbers or the chart from Mcconell on faith.  I 
would have to see his methodolgy, and understand what his motivation in 
conducting the test was.

> 
> 
>>Well that was a long winded digression into something that is
>>completely un-related to Macros.  Seems like a good argument why
>>re-binding the buildins is bad though
> 
> 
> It was a long winded digression into how LOC can be a
> wrong basis by which to judge the appropriateness of a
> language feature.
It still wasn't relevant to Macros.  However, because neither of you 
understand Macros, you of course think it is relevant.
> 
> 
>>>a plus -- and Java's use of { } for example ensures NON-uniformity
>>>on a lexical plane, since everybody has different ideas about where
>>>braces should go:-).
>>>
>>
>>Where braces should go is a trivial issues.  However if braces is an
>>issue that seriously concerns you then I can see why macros are giving
>>you a heart attack.
> 
> 
> See that smiley and the "--"?  This is a throwaway point at the end
> of the argument, and given Alex's noted verboseness, if it was a
> serious point he would have written several pages on the topic.
This is something we are very much in agreement on.
My response was just a little dig, because it does seem to be indicative 
of his attitude in general IMO.
> 
>                     Andrew
>                     ·····@dalkescientific.com
> 
> 


-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ls1hb.3523$dn6.387@newsread4.news.pas.earthlink.net>
Doug Tolton:
> Yes and I have repeatedly stated that I disagree with it.  I simply do
> not by that allowing expressiveness via high level constructs detracts
> from the effectiveness of the group.  That argument is plainly
> ridiculous, if it were true then Python would be worse than Java,
> because Python is *far* more expressive.

I disagree with your summary.  Compare:

  The argument is that expressive power for a single developer can, for
  a group of developers and especially those comprised of people with
  different skill sets and mixed expertise, reduce the overall effectiveness
  of the group.

Notice the "can".   Now your summary is:

  ...allowing expressiveness via high level constructs detracts
  from the effectiveness of the group

That implies that at least I assert that *all* high level constructs
detract from group effectiveness, when clearly I am not saying
that.


> > If this is indeed the crux, then any justification which says "my brain"
> > and "I" is suspect, because that explicitly ignores the argument.
> Apparently you can't read very well.  I simply stated that I believe our
> point of contention to be that issue, I never stated I believe that
> because it's some vague theory inside my head.

Nor can you, because I did not say that.  I said that the arguments you
use to justify your assertions could be stronger if you were to include
cases in your history and experience which show that you understand
the impacts of a language feature on both improving and detracting from
a group effort.  Since you do have that experience, bring it up.  But
since your arguments are usually along the lines of "taking tools out
of your hands", they carry less weight for this topic.

(Ambiguity clarification: "your hands" is meant as 2nd person singular
possessive and not 2nd person plural. :)

> No, what I was referring to wasn't estimation.  Rather I was referring
> to the study that found that programmers on average write the same
> number of lines of code per year regardless of the language they write
> in.

McConnell's book has the same study, with outliers for assembly
and APL.  Indeed, I mentioned this in my reply:
> > ... and that LOC has a
> > good correlation to development time, excluding extremes like APL
> > and assembly.

>  Therefore the only way to increase productivity is to write
> software in a language that uses less lines to accomplish something
> productive.  See Paul Grahams site for a discussion.

I assume you refer to "Succinctness is Power" at
  http://www.paulgraham.com/power.html

It does not make as strong a case as you state here.  It argues
that "succintness == power" but doesn't make any statement
about how much more succinct Lisp is over Python.  He doesn't
like Paul Prescod's statement, but there's nothing to say that
Python can't be both easier to read and more succinct.  (I am
not making that claim, only pointing out that that essay is pure
commentary.)

Note also that it says nothing about group productivity.
If it takes me 5% longer to write a program in language X
then language Y, but where I can more easily use code and
libraries developed by others then it might be a good choice
for me to use a slightly less succinct language.

Why don't people use APL/J/K with it's succinctness?

I also disagree with Graham's statement:
> the most accurate measure of the relative power of
> programming languages might be the percentage of
> people who know the language who will take any job
> where they get to use that language, regardless of the
> application domain.

I develop software for computational life sciences.  I would
do so in Perl, C++, Java, even Javascript because I find
the domain to be very interesting.  I would need to be very
low on money to work in, say, accounting software, even if
I had the choice of using Python.


> You are saying that Python and Perl are similarly compact?!?
> You have got to be kidding right?
> Perl is *far* more compact than Python is.  That is just ludicrous.

Yes.  In this I have a large body of expertise by which to compare
things.  Perl dominates bioinformatics sofware development, and the
equivalent Python code is quite comparable in side -- I argue that
Python is easier to understand, but it's still about the same size.

> It's always nice just to chuck some arbitrary table into the
> conversation which conveniently backs some poitn you were trying to
> make, and also conveniently can't be located for anyone to check the
> methodology.

"Can't be located"!?!?!  I gave a full reference to the secondary material,
included the full quote (with no trimming to bias the table more my way),
gave the context to describe the headings, and gave you a reference
to the primary source!  And I made every reasonable effort to find both
sources online.

Since you can't be suggesting that I tracked down and destroyed
every copy of McConnell's book and of the primary literature (to make
it truely unlocatable) then what's your real complaint?  That things exist
in the world which aren't accessible via the web?  And how is that my
fault?

> If you want some real world numbers on program length check here:
> http://www.bagley.org/~doug/shootout/

If I want some real world numbers on program length, I do it myself:
  http://pleac.sourceforge.net/
I wrote most of the Python code there

Still, since you insist, I went to the scorecard page and changed
the weights to give LOC a multipler of 1 and the others a multiplier
of 0.  This is your definition of succinctness, yes?  This table
is sorted (I think) by least LOC to most.

            SCORES
Language Implementation Score Missing
Ocaml       ocaml        584     0
Ocaml       ocamlb       584     0
Ruby        ruby         582     0
Scheme      guile        578     0
Python      python       559     0
Pike        pike         556     0
Perl        perl         556     0
Common Lisp cmucl        514     0
Scheme      bigloo       506     1
Lua         lua          492     2
Tcl         tcl          478     3
Java        java         468     0
Awk         mawk         457     6
Awk         gawk         457     6
Forth       gforth       449     2
Icon        icon         437     7
C++         g++          435     0
Lisp        rep          427     3
Haskell     ghc          413     5
Javascript  njs          396     5
Erlang      erlang       369     8
PHP         php          347     9
Emacs Lisp  xemacs       331     9
C           gcc          315     0
SML         mlton        284     0
Mercury     mercury      273     8
Bash        bash         264     14
Forth       bigforth     264     10
SML         smlnj        256     0
Eiffel      se           193     4
Scheme      stalin       131     17

So:
  - Why aren't you using Ocaml?
  - Why is Scheme at the top *and* bottom of the list?
  - Python is right up there with the Lisp/Scheme languages
  -  ... and with Perl.

Isn't that conclusion in contradiction to your statements
that 1) "Perl is *far* more compact than Python is" and 2)
the implicit one that Lisp is significantly more succinct than
Python?  (As you say, these are small projects .. but you did
point out this site so implied it had some relevance.)

> I just don't buy these numbers or the chart from Mcconell on faith.  I
> would have to see his methodolgy, and understand what his motivation in
> conducting the test was.

I invite you to dig up the original paper (which wasn't McConnell)
and enlighten us.  Until then, I am as free to agree with McConnell --
more so because his book is quite good and comprehensive with
sound arguments comparing and contrasting the different
approaches and with no strong hidden agenda that I can detect.

> It still wasn't relevant to Macros.  However, because neither of you
> understand Macros, you of course think it is relevant.

My lack of knowledge not withstanding, the question I pose to
you is, in three parts:
  - is it possible for a language feature to make a single programmer
       more expressive/powerful while hindering group projects?
  - can you list three examples of situations where that's occured?
  - can you list one example where the increased flexibility was, in
       general, a bad idea?  That is, was there a language which would
       have been better without a language feature.

Note that I did not at all make reference to macros.  Your statements
to date suggest that your answer to the first is "no."

                    Andrew
                    ·····@dalkescientific.com
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm291n$agf$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> Doug Tolton:
> 

>> Therefore the only way to increase productivity is to write
>>software in a language that uses less lines to accomplish something
>>productive.  See Paul Grahams site for a discussion.
> 
> 
> I assume you refer to "Succinctness is Power" at
>   http://www.paulgraham.com/power.html
> 
> It does not make as strong a case as you state here.  It argues
> that "succintness == power" but doesn't make any statement
> about how much more succinct Lisp is over Python.

He provides more information at http://www.paulgraham.com/icad.html


Pascal
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <GK3hb.3651$dn6.3517@newsread4.news.pas.earthlink.net>
Pascal Costanza:
> He provides more information at http://www.paulgraham.com/icad.html

The page I referenced (http://www.paulgraham.com/power.html)
appears to be a refinement of some ideas on that page.

It's somewhat funny that on the page I mentioned he says:

   So any language comparison where you have to meet a predefined
   spec is testing slightly the wrong thing.

while on the page you reference he gives a comparison between various
languages based on a predefined spec.  And he uses as his test case
something I've not needed.  By comparison, following Kenny Tilton's
lead, the Bagley Shootout Page suggests that in an aggregate of small
but non-trivial problems, OCaml is the most succinct language, with
Python roughly comparable to Lisp/Scheme.

I have run across his pages before, and have a hard time
symphathizing with his view of things.  For example, the start of
the icad essay mentions that Lisp is already "kind of unusual"
compared to C because it includes a full interpreter.  But
effectively all Python programs shipped include a full interpreter
as well, and many give access to that interpreter, so I don't
see what's unusual about it.  Ditto for Tcl apps.  Even some of
my command-line perl apps included a way to pass in perl
code on the command line, as for a search filter.

The phrase "they had hard-headed engineering reasons for
making the syntax look so strange." reminds me of the statement
"better first rate salespeople and second rate engineers than
second rate salespeople and first rate engineers" (and better
first rate both).  That's saying *nothing* about the languages;
it's saying that his viewpoint seems to exclude the idea that
there are hard-headed non-engineering reasons for doing things."

Consider one of those "hard-headed engineering reasons", at
http://www.paulgraham.com/popular.html

   It has sometimes been said that Lisp should use first and
   rest instead of car and cdr, because it would make programs
   easier to read. Maybe for the first couple hours. But a hacker
   can learn quickly enough that car means the first element
   of a list and cdr means the rest. Using first and rest means
   50% more typing. And they are also different lengths, meaning
   that the arguments won't line up when they're called,

That to me is a solid case of post hoc ergo proper.  The
words "1st" and "rst" are equally as short and easier to
memorize.  And if terseness were very important, then
what about using "." for car and ">" for cdr?  No, the reason
is that that's the way it started and it will stay that way
because of network effects -- is that a solid engineering
reason?  Well, it depends, but my guess is that he wouldn't
weight strongly the impact of social behaviours as part of
good engineering.  I do.

And entirely off the topic of programming, his essay at
 http://www.paulgraham.com/nerds.html
has little resonance with my memory of high school.

                    Andrew
                    ·····@dalkescientific.com
From: Daniel Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Pine.GSO.4.58.0310082249400.13914@denali.ccs.neu.edu>
On Thu, 9 Oct 2003, Andrew Dalke wrote:
> Consider one of those "hard-headed engineering reasons", at
> http://www.paulgraham.com/popular.html
>
>    It has sometimes been said that Lisp should use first and
>    rest instead of car and cdr, because it would make programs
>    easier to read. Maybe for the first couple hours. But a hacker
>    can learn quickly enough that car means the first element
>    of a list and cdr means the rest. Using first and rest means
>    50% more typing. And they are also different lengths, meaning
>    that the arguments won't line up when they're called,
>
> That to me is a solid case of post hoc ergo proper.  The
> words "1st" and "rst" are equally as short and easier to
> memorize.  And if terseness were very important, then
> what about using "." for car and ">" for cdr?  No, the reason
> is that that's the way it started and it will stay that way
> because of network effects -- is that a solid engineering
> reason?  Well, it depends, but my guess is that he wouldn't
> weight strongly the impact of social behaviours as part of
> good engineering.  I do.

It hasn't stayed that way for me:

(define first car)
(define rest cdr)

:)

- Daniel
From: Michael Geary
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <vo9u53r5hf6a4b@corp.supernews.com>
Andrew Dalke:
> The phrase "they had hard-headed engineering reasons for
> making the syntax look so strange." reminds me of the statement
> "better first rate salespeople and second rate engineers than
> second rate salespeople and first rate engineers" (and better
> first rate both).  That's saying *nothing* about the languages;
> it's saying that his viewpoint seems to exclude the idea that
> there are hard-headed non-engineering reasons for doing things."
>
> Consider one of those "hard-headed engineering reasons", at
> http://www.paulgraham.com/popular.html
>
>    It has sometimes been said that Lisp should use first and
>    rest instead of car and cdr, because it would make programs
>    easier to read. Maybe for the first couple hours. But a hacker
>    can learn quickly enough that car means the first element
>    of a list and cdr means the rest. Using first and rest means
>    50% more typing. And they are also different lengths, meaning
>    that the arguments won't line up when they're called,
>
> That to me is a solid case of post hoc ergo proper.  The
> words "1st" and "rst" are equally as short and easier to
> memorize.  And if terseness were very important, then
> what about using "." for car and ">" for cdr?  No, the reason
> is that that's the way it started and it will stay that way
> because of network effects -- is that a solid engineering
> reason?  Well, it depends, but my guess is that he wouldn't
> weight strongly the impact of social behaviours as part of
> good engineering.  I do.

It's pretty funny when you consider that car and cdr were named after the
Contents of Address Register and Contents of Decrement Register on the IBM
704. Now that's a solid engineering reason!

(I'm not knocking Lisp; in fact, this discussion has whetted my appetite to
explore it.)

-Mike
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <NW6hb.150445$pZ5.1711681@news.easynews.com>
Michael Geary wrote:
> Andrew Dalke:
> 
>>The phrase "they had hard-headed engineering reasons for
>>making the syntax look so strange." reminds me of the statement
>>"better first rate salespeople and second rate engineers than
>>second rate salespeople and first rate engineers" (and better
>>first rate both).  That's saying *nothing* about the languages;
>>it's saying that his viewpoint seems to exclude the idea that
>>there are hard-headed non-engineering reasons for doing things."
>>
>>Consider one of those "hard-headed engineering reasons", at
>>http://www.paulgraham.com/popular.html
>>
>>   It has sometimes been said that Lisp should use first and
>>   rest instead of car and cdr, because it would make programs
>>   easier to read. Maybe for the first couple hours. But a hacker
>>   can learn quickly enough that car means the first element
>>   of a list and cdr means the rest. Using first and rest means
>>   50% more typing. And they are also different lengths, meaning
>>   that the arguments won't line up when they're called,
>>
>>That to me is a solid case of post hoc ergo proper.  The
>>words "1st" and "rst" are equally as short and easier to
>>memorize.  And if terseness were very important, then
>>what about using "." for car and ">" for cdr?  No, the reason
>>is that that's the way it started and it will stay that way
>>because of network effects -- is that a solid engineering
>>reason?  Well, it depends, but my guess is that he wouldn't
>>weight strongly the impact of social behaviours as part of
>>good engineering.  I do.
> 
> 
> It's pretty funny when you consider that car and cdr were named after the
> Contents of Address Register and Contents of Decrement Register on the IBM
> 704. Now that's a solid engineering reason!
> 
> (I'm not knocking Lisp; in fact, this discussion has whetted my appetite to
> explore it.)
> 
> -Mike
> 
> 
Graham does admit in that the reasons for the choice were mostly 
historical.  However, he uses them because he likes the fact that they 
are shorter than first and rest.

If you read his design goals for Arc you will note that he is a big fan 
of very terse operators.



-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Mk8hb.3993$dn6.1095@newsread4.news.pas.earthlink.net>
Doug Tolton:
> Graham does admit in that the reasons for the choice were mostly
> historical.  However, he uses them because he likes the fact that they
> are shorter than first and rest.

Not in that essay I referenced.  And I deliberately mentioned
"1st" and "rst" as alternatives to "car" and "cdr" which are exactly
the same length and are easier to remember.  The fact that "first"
and "rest" are longer doesn't immediately mean that there are
no other viable alternatives.

BTW, paulgraham.com/arcfaq.html says that car/cdr remain
because they are composable, as in "cadr".  Is that the same
as 2nd?

Ahh, the FAQ also says that [ and ] are "less directional"
than ( and ), which I can understand.  I don't understand
the objection with < and > ; they "lose because they don't
wrap around enough to enclose expressions long than tokens."
That makes no sense to me.  Is is that they aren't tall enough?

Couldn't a good development environment depict the delimiters
as, say Unicode characters 27E8 and 27E9?
  http://www.unicode.org/charts/PDF/U27C0.pdf
Those look like large "<" and ">"

Or is there a requirement that it be constrained to display
systems which can only show ASCII?  (Just like a good
Lisp editor almost requires the ability to reposition a
cursor to blink on matching open parens.  Granted, that
technology is a few decades old now while Unicode isn't,
but why restrict a new language to the display systems
of the past instead of the present?)

Heh-heh.  "Why not build Arc on top of Java/Parrot/.NET?"
  "We're trying to make something for the long term in Arc,
    something that will be useful to people in, say, 100 years."

Then build it on MMIX!  :)

> If you read his design goals for Arc you will note that he is a big fan
> of very terse operators.

Indeed.  It looks easier to understand to my untrained eye.
I disagree that "+" shouldn't work on strings because that
operation isn't commutative -- commutativity isn't a feature
of + it's a feature of + on a certain type of set.

He says that "programmers will be able to declare that
strings should be represented as traditional sequences of bytes."
which leads me to wonder about its Unicode support.

What's unicode support like in general for Lisp?  Found an
answer in  http://www.cliki.net/Unicode%20Support Digging
some more, it looks like CLisp uses .. UCS-4 and Unicode 3.2
(from clisp.cons.org).  But do regexps work on unicode strings?
How portable are unicode strings?  I figure they must be in
order to handle XML well.  ... "ACL does not support 4 byte
Unicode scalar values" says franz.com.  www.cl-xml.org says
"The processor passes 1749 of the 1812 tests .. when the base
implementation supports sixteen-bit charactrs." and that
MCL, LispWorks and the Allegro 5.0.1 international version
support 16-bit Unicode while Allegro ascii only supports 8bit.
So some have UCS-2 and some UCS-4.

Is there consensus on the Unicode API?

On the XML path, I found cl-xml.  Looking at the bugs section in
  http://pws.prserv.net/James.Anderson/XML/documentation/cl-xml.html
It says "the implementation form for HTTP support is determined
at compilation time." Is it really true that even HTTP handling is
different on the different implementations?

And the section under "porting" is .. strange.  It looks like to
use the XML API for a given Lisp I need to know enough
about the given implementation to configure various settings,
so if I wanted to learn Lisp by writing, say, a simple XML-RPC
client then I have to learn first what it means "to complete
definitions in the following files" and the details of "defsystem",
"package", "STREAM-READER / -WRITER", etc.

That reminds me of my confusion testing a biolisp package.
I needed to edit the file before it worked; something to do
with commenting/uncommenting the right way to handle
packages.  I prefer to start with working code.

                    Andrew
                    ·····@dalkescientific.com
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm39gd$uio$1@f1node01.rhrz.uni-bonn.de>
Andrew Dalke wrote:

>>If you read his design goals for Arc you will note that he is a big fan
>>of very terse operators.
> 
> Indeed.  It looks easier to understand to my untrained eye.
> I disagree that "+" shouldn't work on strings because that
> operation isn't commutative -- commutativity isn't a feature
> of + it's a feature of + on a certain type of set.

So what's the result of ("one" - "two") then? ;)

> He says that "programmers will be able to declare that
> strings should be represented as traditional sequences of bytes."
> which leads me to wonder about its Unicode support.

It's a myth that bytes are restricted to 8 bits. See 
http://www.wikipedia.org/wiki/Byte

> What's unicode support like in general for Lisp?  Found an
> answer in  http://www.cliki.net/Unicode%20Support Digging
> some more, it looks like CLisp uses .. UCS-4 and Unicode 3.2
> (from clisp.cons.org).  But do regexps work on unicode strings?
> How portable are unicode strings?  I figure they must be in
> order to handle XML well.  ... "ACL does not support 4 byte
> Unicode scalar values" says franz.com.  www.cl-xml.org says
> "The processor passes 1749 of the 1812 tests .. when the base
> implementation supports sixteen-bit charactrs." and that
> MCL, LispWorks and the Allegro 5.0.1 international version
> support 16-bit Unicode while Allegro ascii only supports 8bit.
> So some have UCS-2 and some UCS-4.
> 
> Is there consensus on the Unicode API?

No, not yet. ANSI CL was finalized in 1994.

> On the XML path, I found cl-xml.  Looking at the bugs section in
>   http://pws.prserv.net/James.Anderson/XML/documentation/cl-xml.html
> It says "the implementation form for HTTP support is determined
> at compilation time." Is it really true that even HTTP handling is
> different on the different implementations?

Again, not part of ANSI CL. Don't judge a standardized language with the 
measures of a single-vendor language - that's a different subject. 
(Apart from that, Jython also doesn't provide everything that Python 
provides, right?)

Pick the one Common Lisp implementation that provides the stuff you 
need. If no Common Lisp implementation provides all the stuff you need, 
write your own libraries or pick a different language. It's as simple as 
that.

> And the section under "porting" is .. strange.  It looks like to
> use the XML API for a given Lisp I need to know enough
> about the given implementation to configure various settings,
> so if I wanted to learn Lisp by writing, say, a simple XML-RPC
> client then I have to learn first what it means "to complete
> definitions in the following files" and the details of "defsystem",
> "package", "STREAM-READER / -WRITER", etc.
> 
> That reminds me of my confusion testing a biolisp package.
> I needed to edit the file before it worked; something to do
> with commenting/uncommenting the right way to handle
> packages.  I prefer to start with working code.

You can ask these things in comp.lang.lisp or in one of the various 
mailing lists. Common Lispniks are generally very helpful.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Rainer Deyke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <0_ghb.251516$mp.168001@rwcrnsc51.ops.asp.att.net>
Pascal Costanza wrote:
> Pick the one Common Lisp implementation that provides the stuff you
> need. If no Common Lisp implementation provides all the stuff you
> need, write your own libraries or pick a different language. It's as
> simple as that.

Coming from a C/C++ background, I'm surprised by this attitude.  Is
portability of code across different language implementations not a priority
for LISP programmers?


-- 
Rainer Deyke - ·······@eldwood.com - http://eldwood.com
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F85A0D7.EAE94C0A@setf.de>
Rainer Deyke wrote:
> 
> Pascal Costanza wrote:
> > Pick the one Common Lisp implementation that provides the stuff you
> > need. If no Common Lisp implementation provides all the stuff you
> > need, write your own libraries or pick a different language. It's as
> > simple as that.
> 
> Coming from a C/C++ background, I'm surprised by this attitude.  Is
> portability of code across different language implementations not a priority
> for LISP programmers?

there are some things which the standard does not cover.

...
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <OLihb.4377$dn6.3706@newsread4.news.pas.earthlink.net>
Rainer Deyke wrote:
> Is portability of code across different language implementations not a
priority
> for LISP programmers?

james anderson:
> there are some things which the standard does not cover.

"The standard" as I understand it, is some document written a decade
ago.  Can't a few of you all get together and say "hey, the world's
advanced.  Let's agree upon a few new libraries and APIs."?


                    Andrew
                    ·····@dalkescientific.com
From: Daniel Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Pine.GSO.4.58.0310091552320.1051@denali.ccs.neu.edu>
On Thu, 9 Oct 2003, Andrew Dalke wrote:
> Rainer Deyke wrote:
> > Is portability of code across different language implementations not a
> priority
> > for LISP programmers?
>
> james anderson:
> > there are some things which the standard does not cover.
>
> "The standard" as I understand it, is some document written a decade
> ago.  Can't a few of you all get together and say "hey, the world's
> advanced.  Let's agree upon a few new libraries and APIs."?

Isn't that what repositories like perl's CPAN are for?

Though it would be nice if everyone agreed on a single, simple
foreign-function interface...

- Daniel
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Cukhb.256213$R32.8320062@news2.tin.it>
Rainer Deyke wrote:

> Pascal Costanza wrote:
>> Pick the one Common Lisp implementation that provides the stuff you
>> need. If no Common Lisp implementation provides all the stuff you
>> need, write your own libraries or pick a different language. It's as
>> simple as that.
> 
> Coming from a C/C++ background, I'm surprised by this attitude.  Is
> portability of code across different language implementations not a
> priority for LISP programmers?

Libraries distributed as binaries are not portable across different C++
implementations on the same machine (as a rule).  If we're talking
about sources, I don't see why strict ANSI Lisp library source code should
be any less portable than strict ISO C++ library source code.  Even
different C++ implementations often come with additional vendor
specific libraries (e.g., on Windows, MFC and ATL for MS, ...) -- you
don't HAVE to use them, though the vendor's tools encourage you
to (to hook you in).

Personally, the only thing I find alien in Pascal's recommendation is
a glaring lack -- no mention of the possibility of downloading and
reusing open-source libraries from the net, just getting them as a
part of the implementation or else rolling your own.  Now _that_ is
something I find weird, and cannot explain.


Alex
From: Steven E. Harris
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <q67llru9fpp.fsf@raytheon.com>
Alex Martelli <·····@aleax.it> writes:

> Personally, the only thing I find alien in Pascal's recommendation
> is a glaring lack -- no mention of the possibility of downloading
> and reusing open-source libraries from the net, just getting them as
> a part of the implementation or else rolling your own.

Don't think it doesn't happen. Just today I downloaded and started
using both CL-PPCRE� and net-telent-date�.


Footnotes: 
� http://www.weitz.de/cl-ppcre/
� http://www.cliki.net/net-telent-date

-- 
Steven E. Harris        :: ········@raytheon.com
Raytheon                :: http://www.raytheon.com
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm4tl8$613$1@newsreader2.netcologne.de>
Rainer Deyke wrote:

> Pascal Costanza wrote:
> 
>>Pick the one Common Lisp implementation that provides the stuff you
>>need. If no Common Lisp implementation provides all the stuff you
>>need, write your own libraries or pick a different language. It's as
>>simple as that.
> 
> 
> Coming from a C/C++ background, I'm surprised by this attitude.  Is
> portability of code across different language implementations not a priority
> for LISP programmers?

IMHO it's better to first get you code right on the CL implementation 
you have chosen, and then worry about porting it to other CL 
implementations if the need arises, and not try to do both things at the 
same time.

But that's maybe just me.

Perhaps Kenny can better comment on this because he has already ported 
his Cells stuff to many CL implementations. Would you recommend to take 
care of portability from the start, or would you rather do it differently?


Pascal
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3jAhb.18$KR3.5643@typhoon.nyu.edu>
Rainer Deyke wrote:
> Pascal Costanza wrote:
> 
>>Pick the one Common Lisp implementation that provides the stuff you
>>need. If no Common Lisp implementation provides all the stuff you
>>need, write your own libraries or pick a different language. It's as
>>simple as that.
> 
> 
> Coming from a C/C++ background, I'm surprised by this attitude.  Is
> portability of code across different language implementations not a priority
> for LISP programmers?
> 

It is.  However, history has run against Lisp in this respect.  First of 
all, there are more than 1.84 implementations of Lisp (4 commercial 
ones) and the vendors do not have much incentive in making something 
completely portable.  OTOH *there are* cross platforms compatibility 
layers for many of the things you need.  But the problem facing any 
Common Lisp library writer is to decide how much to go in terms of cross 
  implementation and cross platform portability.

Having said that, lets note however, that the actual footprint of CL is 
large enough to allow you to write nice portable programs in a much 
easier way than e.g. in Scheme or in pre- (and, to some extent post-) 
STL C++.

Cheers
--
Marco
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pOhhb.4333$dn6.3820@newsread4.news.pas.earthlink.net>
Pascal Costanza:
> So what's the result of ("one" - "two") then? ;)

It's undefined on strings -- a type error.  Having + doesn't
mean that - must exist.

(A more interesting question would be to ask what
the result of  "throne" - "one" is.  But again, a type error.)

Pascal Costanza:
> It's a myth that bytes are restricted to 8 bits. See
> http://www.wikipedia.org/wiki/Byte

(I can't connect to the URL but I know what you're talking
about.)

Sure.  But I'm just barely old enough to have programmed on
a CDC Cyber.  When I see the word 'byte' I assume it means
8 bits unless told otherwise.  When I buy memory, I don't ask
the sales staff "so is this an 8 bit byte or a 60 bit byte?"  (And
yes, I know about the lawsuit against disk drive manufacturors
and their strange definition of "gigabyte", but even then, they
still use an 8 bit byte.)

Me:
> > Is there consensus on the Unicode API?

Pascal Costanza:
> No, not yet. ANSI CL was finalized in 1994.

Sure.  That's why I asked about consensus.  De facto rather
than de jure.  SAX for XML processing is a de facto standard
but portable across different implementations and even
portable across different languages (that is, there's a very
mechanical and obvious way to convert from one language
to another.)

> Again, not part of ANSI CL. Don't judge a standardized language with the
> measures of a single-vendor language - that's a different subject.

I understand your point of view.  OTOH, it's like when I used to
work with C.  It was standardized, but required that I download
a slew of packages in order to do things.  Eg, I had to evalutate
several different regexp packages before I found one which was
appropriate.  I know there are good reasons for a standard to
leave out useful packages, but I know there are good reasons for
an implementation to include a large number of useful packages.

Is there a free Lisp/Scheme implementation I can experiment with
which include in the distribution (without downloading extra
packages; a "moby" distribution in xemacs speak):
 - unicode
 - xml processing (to some structure which I can use XPath on)
 - HTTP-1.1 (client and server)
 - URI processing, including support for opening and reading from
        http:, file:, and https:
 - regular expressions on both 8-bit bytes and unicode
 - XML-RPC
 - calling "external" applications (like system and popen do for C)
 - POP3 and mailbox processing

As far as I can tell, there isn't.  I'll need to mix and match packages
from a variety of sources.  It isn't like these are highly unusual
requirements; I use them pretty frequently in Python.  For examples:

 - connect to my POP server, delete messages with .exe attachements
     on the assumption that it's spam
 - Use DAS (see http://www.biodas.org/) to get genomic sequence
      annotations.  Requires HTTP and XML processing (mostly
      Latin-1 encoding)
 - Make an XML-RPC server which takes as input molecular
     structure information (eg, "CCO" is ethanol) and calls several
     existing command-line packages to compute properties about
     the compound.  Parse the output with regular expressions and
    combine and return all the results.
 - Make a client which uses that server.

(Okay, looks like https isn't needed for these, but the rest are.)

> (Apart from that, Jython also doesn't provide everything that Python
> provides, right?)

No, but there is a good overlap.  I believe all of the above are
supported on both implementations.

> Pick the one Common Lisp implementation that provides the stuff you
> need. If no Common Lisp implementation provides all the stuff you need,
> write your own libraries or pick a different language. It's as simple as
> that.

Which Common Lisp *distribution* provides the above?  I
don't doubt that an implementation + some add-in packages do
all that, but each new package means one extra lump on the
barrier to entry and one extra worry when I want others to
use the code I've written.

I use Python in part because of the "batteries included"
philosophy.  There will always be 3rd party packages (PIL for
images, ReportLab for PDF generation, PyDaylight or OEChem
for chemical informatics), but there's a lot which comes in
the standard distributions.

> You can ask these things in comp.lang.lisp or in one of the various
> mailing lists. Common Lispniks are generally very helpful.

Understood.  I did managed to get the biolisp code working, btw.

                    Andrew
                    ·····@dalkescientific.com
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3oewq5fbh.fsf@rigel.goldenthreadtech.com>
"Andrew Dalke" <······@mindspring.com> writes:

> Pascal Costanza:
> > So what's the result of ("one" - "two") then? ;)
> 
> It's undefined on strings -- a type error.  Having + doesn't
> mean that - must exist.

No, but it makes the semantics odd for an operation named by "+".  Of
course it may not be obvious what the semantics should be, but then
the semantics of "hi" + "there" isn't obvious either.


> (A more interesting question would be to ask what
> the result of  "throne" - "one" is.  But again, a type error.)

Why?  This seems like a likely candidate for a string -.


> I understand your point of view.  OTOH, it's like when I used to
> work with C.  It was standardized, but required that I download
> a slew of packages in order to do things.

That's why there are _implementations_.  It's odd that the obvious
distinction between "compiler" (or interpreter or whatever) and
"language" is so hard to grasp.


> appropriate.  I know there are good reasons for a standard to
> leave out useful packages, but I know there are good reasons for
> an implementation to include a large number of useful packages.

Wow, this actually sounds right.


> Is there a free Lisp/Scheme implementation I can experiment with
> which include in the distribution (without downloading extra
> packages; a "moby" distribution in xemacs speak):
>  - unicode
>  - xml processing (to some structure which I can use XPath on)
>  - HTTP-1.1 (client and server)
>  - URI processing, including support for opening and reading from
>         http:, file:, and https:
>  - regular expressions on both 8-bit bytes and unicode
>  - XML-RPC
>  - calling "external" applications (like system and popen do for C)
>  - POP3 and mailbox processing

Yes. Allegro CL (ACL) for one.


> As far as I can tell, there isn't.  I'll need to mix and match packages

You obviously can't "tell" too well.


> > (Apart from that, Jython also doesn't provide everything that Python
> > provides, right?)
> 
> No, but there is a good overlap.  I believe all of the above are
> supported on both implementations.

Interaction with Java (to access it's libararies and whatnot) is also
in ACL.


> Which Common Lisp *distribution* provides the above?  I

One is pointed out above.


/Jon
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87oewqw2r0.fsf@bird.agharta.de>
On 09 Oct 2003 16:25:22 -0400, ·········@rcn.com (Jon S. Anthony) wrote:

> "Andrew Dalke" <······@mindspring.com> writes:
> 
> > Is there a free Lisp/Scheme implementation I can experiment with
> > which include in the distribution (without downloading extra
> > packages; a "moby" distribution in xemacs speak):
> >  - unicode
> >  - xml processing (to some structure which I can use XPath on)
> >  - HTTP-1.1 (client and server)
> >  - URI processing, including support for opening and reading from
> >         http:, file:, and https:
> >  - regular expressions on both 8-bit bytes and unicode
> >  - XML-RPC
> >  - calling "external" applications (like system and popen do for C)
> >  - POP3 and mailbox processing
> 
> Yes. Allegro CL (ACL) for one.
> 
> > As far as I can tell, there isn't.  I'll need to mix and match
> > packages
> 
> You obviously can't "tell" too well.

It is true that AllegroCL has all these features and it probably is
the only CL implementation that includes all of them out of the box
but it is not true that it is free (which was one of the things
Mr. Dalke asked for). At least it wasn't true the last time I talked
to the Franz guys some days ago. If that has changed in the last week
please let me know... :)

You might be able to get most of these features with "free" CL
implementations but not all at once I think. (AFAIK CLISP is currently
the only "free" CL which supports Unicode but it is lacking in some
other areas.)

As far as "mix and match" of packages is concerned: Use Debian
(testing) or Gentoo. I've been told it's just a matter of some
invocations of 'apt-get install' or 'emerge' to get the CL packages
you want. At least it shouldn't be harder than, say, getting stuff
from CPAN. What? You don't use Debian or Gentoo? Hey, you said you
wanted "free" stuff - you get what you pay for.

No, seriously. It'd definitely be better (for us Lispers) if we had
more freely available libraries plus a standardized installation
procedure � la CPAN. Currently we don't have that - there are
obviously far more people working on Perl or Python libraries.

So, here are your choices:

1. Buy a commercial Lisp. I've done that and I think it was a good
   decision.

2. Try to improve the situation of the free CL implementations by
   writing libraries or helping with the infrastructure. That's how
   this "Open Source" thingy is supposed to work. I'm also doing this.

3. Run around complaining that you can't use Lisp because a certain
   combination of features is not available for free. We have far too
   many of these guys on c.l.l.

4. Just don't use it. That's fine with me.

It currently looks like the number of people choosing #2 is
increasing. Looks promising. You are invited to take part - it's a
great language and a nice little community... :)

Edi.

PS: You might also want to look at

      <http://web.metacircles.com/cirCLe+CD>.
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m37k3e5bun.fsf@rigel.goldenthreadtech.com>
Edi Weitz <···@agharta.de> writes:

> but it is not true that it is free (which was one of the things
> Mr. Dalke asked for). At least it wasn't true the last time I talked

You are right.  My mistake.

/Jon
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <9_lhb.4591$dn6.1741@newsread4.news.pas.earthlink.net>
Edi Weitz
> As far as "mix and match" of packages is concerned: Use Debian
> (testing) or Gentoo. I've been told it's just a matter of some
> invocations of 'apt-get install' or 'emerge' to get the CL packages
> you want. At least it shouldn't be harder than, say, getting stuff
> from CPAN. What? You don't use Debian or Gentoo? Hey, you said you
> wanted "free" stuff - you get what you pay for.

Python's free.  And I've paid for it in my efforts.

My primary machine is Mac OS X.  I always got frustrated getting
fonts, sound, and movies working under the various Linux-based
distributions, and I suspect there are the same problems with
BSD-based distributions.

I downloaded (years ago) the Allegro demo package, but that
was to test a package from biolisp.org.  There being no other
code for doing bioinformatics, and given my known proclivities
for Python, I didn't see the justification of paying for the full
commercial version.

> So, here are your choices:
>
> 1. Buy a commercial Lisp. I've done that and I think it was a good
>    decision.

I'm already making my living from doing Python, so I've got an
incentive to stay with it.  ;)

In the scientific conferences I attend, no one I've seen uses Lisp
for their work, excepting those old enough that they started before
there were other high-quality high-level languages.

No one has told me they would hire me for contract work "if only
you were a Lisp programmer."

If the barrier to entry to do what are common-place tasks requires
I buy a commercial Lisp then it's much less likely others will use
my code.  I like having others use my code.

(Then why do I use Python?  It's a tradeoff, since writing Java/C++
is just too tedious.  And I like the people in Python (Hi Laura!).
And I'm picky the domain -- I like doing computational life sciences.)

> 2. Try to improve the situation of the free CL implementations by
>    writing libraries or helping with the infrastructure. That's how
>    this "Open Source" thingy is supposed to work. I'm also doing this.

And I'm doing it for Python.  For my domain, it seems like a much
better language choice, for reasons I've mentioned here several times.

> 3. Run around complaining that you can't use Lisp because a certain
>    combination of features is not available for free. We have far too
>    many of these guys on c.l.l.

Technically I'm cross-posting from c.l.py.  And I actually complain
for other reasons.  ;)

> 4. Just don't use it. That's fine with me.

So far I've made ... 4(?) half-hearted attempts at learning Lisp.
And 1 at learning Haskell.  And 0.1 at learning OCaml.

> It currently looks like the number of people choosing #2 is
> increasing. Looks promising. You are invited to take part - it's a
> great language and a nice little community... :)

"A rising tide lifts all boats".  The same is true in Python, in
Java, in Ruby, in ...

> PS: You might also want to look at
>
>       <http://web.metacircles.com/cirCLe+CD>.

*sigh*.  Another package that doesn't (err, won't) work on my
Mac.

                    Andrew
                    ·····@dalkescientific.com
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm4u9f$6nt$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> Edi Weitz
> 
>>As far as "mix and match" of packages is concerned: Use Debian
>>(testing) or Gentoo. I've been told it's just a matter of some
>>invocations of 'apt-get install' or 'emerge' to get the CL packages
>>you want. At least it shouldn't be harder than, say, getting stuff
>>from CPAN. What? You don't use Debian or Gentoo? Hey, you said you
>>wanted "free" stuff - you get what you pay for.
> 
> 
> Python's free.  And I've paid for it in my efforts.
> 
> My primary machine is Mac OS X.  I always got frustrated getting
> fonts, sound, and movies working under the various Linux-based
> distributions, and I suspect there are the same problems with
> BSD-based distributions.

Well, then you already know that free doesn't always mean better. BTW, 
Xanalys have just released the free personal edition of LispWorks 4.3 
which runs on Windows, Linux and Mac OS X. [1]


Pascal

[1] No, I don't work for them. ;)
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1xtlxm85.fsf@ccs.neu.edu>
"Andrew Dalke" <······@mindspring.com> writes:

> No one has told me they would hire me for contract work "if only
> you were a Lisp programmer."

Next time I'm hiring, I'll be sure to let you know.
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ad89mpsu.fsf@bird.agharta.de>
On Thu, 09 Oct 2003 23:15:17 GMT, "Andrew Dalke" <······@mindspring.com> wrote:

> My primary machine is Mac OS X.  I always got frustrated getting
> fonts, sound, and movies working under the various Linux-based
> distributions, and I suspect there are the same problems with
> BSD-based distributions.

Although I've been using Linux and/or FreeBSD since about 1999 I
understand what you mean. It's still much too hard to set up a machine
if you just want to get your work done and don't like fiddling with
the OS internals.

But there are a couple of free Common Lisps available for Mac OS X -
OpenMCL, CLISP, SBCL, ECL, maybe more. (Plus the trial versions of
MCL, AllegroCL and LispWorks the latter of which has a fantastic
cross-platform GUI toolkit.) What's missing is someone who integrates
these Lisps and the available packages with something like Fink to
make OS X as convenient as Debian as far as Lisp is concerned. I think
this wouldn't be too hard - AFAIK Fink uses the same package format -
but somebody's gotta do the work. (If someone's willing to donate an
iBook or PowerBook to me I'll do it... :)

Just to show you that the situation isn't as bleak as you might think
here's the list of Debian packages maintained by Kevin Rosenberg:

  <http://qa.debian.org/developer.php/developer.php?gpg_key=C4A3823E>

That's more than 110 and almost all of them are for Common Lisp. Plus,
there are Common Lisp packages maintained by other people, of
course. Still far less than what can be found on CPAN but a very good
base to start with. (And who needs Lingua::Romana::Perligata anyway?
Pardon me that all my examples are for Perl but I'm much more familiar
with Perl than with Python.)

> No one has told me they would hire me for contract work "if only you
> were a Lisp programmer."

No one has told me either. But I've had a lot of contract work in
Common Lisp since I started with it in 2000. If I were always waiting
for someone to tell me which language to use I'd probably be stuck
with Java, PHP, and Visual Basic forever. Yuck!

> > 3. Run around complaining that you can't use Lisp because a certain
> >    combination of features is not available for free. We have far too
> >    many of these guys on c.l.l.
> 
> Technically I'm cross-posting from c.l.py.  And I actually complain
> for other reasons.  ;)

Yes, I wasn't talking about you in particular.

> So far I've made ... 4(?) half-hearted attempts at learning Lisp.

Next time try it wholeheartedly... :)

> *sigh*.  Another package that doesn't (err, won't) work on my Mac.

Same answer as above. The CD is based on SBCL so it should be possible
to do something similar for OS X (should even be easier in theory
because you don't need the Knoppix stuff for HW detection). It's just
that someone has to do it...

Cheers,
Edi.
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <itAhb.19$KR3.4629@typhoon.nyu.edu>
Andrew Dalke wrote:

> Edi Weitz
...
> 
>>So, here are your choices:
>>
>>1. Buy a commercial Lisp. I've done that and I think it was a good
>>   decision.
> 
> 
> I'm already making my living from doing Python, so I've got an
> incentive to stay with it.  ;)
> 
> In the scientific conferences I attend, no one I've seen uses Lisp
> for their work, excepting those old enough that they started before
> there were other high-quality high-level languages.

Maybe thos of us "old enough" know that some high-level high-quality 
languages are better than others :)


> 
> No one has told me they would hire me for contract work "if only
> you were a Lisp programmer."
> 
> If the barrier to entry to do what are common-place tasks requires
> I buy a commercial Lisp then it's much less likely others will use
> my code.  I like having others use my code.
> 
> (Then why do I use Python?  It's a tradeoff, since writing Java/C++
> is just too tedious.  And I like the people in Python (Hi Laura!).
> And I'm picky the domain -- I like doing computational life sciences.)

Well, I am doing that too.  Do you know what is the core of 
Biocyc/Ecocyc/Metacyc written in?

>>2. Try to improve the situation of the free CL implementations by
>>   writing libraries or helping with the infrastructure. That's how
>>   this "Open Source" thingy is supposed to work. I'm also doing this.
> 
> 
> And I'm doing it for Python.  For my domain, it seems like a much
> better language choice, for reasons I've mentioned here several times.

Your reasons seem to boil down to the "I do not know Lisp enough" thingy 
you hear over and over.  I know I sound trite, but that is exactly the 
point.  Meanwhile, CL languishes because people don't understand 
Greespun's Tenth :)

I know I am whining :) I *am* an old geezer :)


> 
> 
>>3. Run around complaining that you can't use Lisp because a certain
>>   combination of features is not available for free. We have far too
>>   many of these guys on c.l.l.
> 
> 
> Technically I'm cross-posting from c.l.py.  And I actually complain
> for other reasons.  ;)
> 
> 
>>4. Just don't use it. That's fine with me.
> 
> 
> So far I've made ... 4(?) half-hearted attempts at learning Lisp.
> And 1 at learning Haskell.  And 0.1 at learning OCaml.
> 
> 
>>It currently looks like the number of people choosing #2 is
>>increasing. Looks promising. You are invited to take part - it's a
>>great language and a nice little community... :)
> 
> 
> "A rising tide lifts all boats".  The same is true in Python, in
> Java, in Ruby, in ...

With the main difference that Greespun's Tenth Rule of Programming does 
not apply in only one case :)

Cheers
--
marco
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87y8vuyrgi.fsf@thalassa.informatimago.com>
"Andrew Dalke" <······@mindspring.com> writes:

> Pascal Costanza:
> > So what's the result of ("one" - "two") then? ;)
> 
> It's undefined on strings -- a type error.  Having + doesn't
> mean that - must exist.

What about:

(defun nl-string-to-number (text)
  ;; Of course, you could program it more intelligently and more efficiently.
  (do* ((i 0                   (1+ i))
        (s (format nil "~r" i) (format nil "~r" i))
        )
      ((or (string-equal s text) (< (* 2 (length text)) (length s)))
       (when (string-equal s text) i)))
  );;nl-string-to-number

(defmacro def-s-op (name num-op)
  `(defun ,name (&rest args)
     (format nil "~r"
             (apply (function ,num-op)
                    (mapcar (function nl-string-to-number) args))))
  );;def-s-op


(def-s-op +s  +)
(def-s-op -s  -)
(def-s-op *s  *)
(def-s-op /s  /)
(def-s-op =s  =)
(def-s-op /=s /=)
(def-s-op <s  <)
(def-s-op <=s <=)
(def-s-op >s  >)
(def-s-op =>s <=)

(-s "one" "two")

==> "minus one"


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Rob Warnock
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <At6cnenMmq7-OBuiXTWc-w@speakeasy.net>
Andrew Dalke <······@mindspring.com> wrote:
+---------------
| (and yes, I know about the lawsuit against disk drive manufacturors
| and their strange definition of "gigabyte"... )
+---------------

Oh, you mean the fact that they use the *STANDARD* international
scientific/engineering notation for powers of 10 instead of the
broken, never-quite-right-except-in-a-few-cases pseudo-binary
powers of 10?!?!?  [Hmmm... Guess you can tell which side of *that*
debate I'm on, eh?]  The "when I write powers of 10 which are 3*N
just *asssume* that I meant powers of 2 which are 10*N" hack simply
fails to work correctly when *some* of the "powers of 10" are *really*
powers of 10. It also fails to work correctly with things that aren't
instrinsically quantized in powers of 2 at all.

Examples: I've had to grab people by the scruff of the neck and push
their faces into the applicable reference texts before they believe me
when I say that gigabit Ethernet really, really *is* 1000000000.0 bits
per second [peak payload, not encoded rate], not 1073741824, and that
64 kb/s DS0 telephone circuits really *are* 64,000.0 bits/sec, not 65536.
[And, yes, 56 kb/s circuits are 56000 bits/sec, not 57344.]

Solution: *Always* use the internationally-recognized binary prefixes
<URL:http://physics.nist.gov/cuu/Units/binary.html> when that's really
what you mean, and leave the old scientific/engineering notation alone,
as pure powers of 10. [Note: The historical notes on that page are well
worth reading.]


-Rob

p.s. If you're hot to file a lawsuit, go after the Infiniband Trade
Association for its repeated claims that 4x IB is "10 Gb/s". It isn't,
it's 8 Gb/s [peak user payload rate, not encoded rate]. Go read the
IBA spec if you don't believe me; it's right there.

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87he2hj979.fsf@thalassa.informatimago.com>
····@rpw3.org (Rob Warnock) writes:

> Andrew Dalke <······@mindspring.com> wrote:
> +---------------
> | (and yes, I know about the lawsuit against disk drive manufacturors
> | and their strange definition of "gigabyte"... )
> +---------------
> 
> Oh, you mean the fact that they use the *STANDARD* international
> scientific/engineering notation for powers of 10 instead of the
> broken, never-quite-right-except-in-a-few-cases pseudo-binary
> powers of 10?!?!? 


No  we mean  the  fact  that they  subreptitiously  switched from  the
industry standard of defining giga  as 2^30 to the scientific standard
of defining  giga as 10^9, which  allowed them to  display bigger size
while in fact  they did not have bigger hard drives.   That was a pure
marketing trick.   Happily, after these  lawsuits, they now  write the
exact number of  byte storable on their devices.   But be assured that
they would have never switched if 2^30 had been smaller than 10^9.


> [Hmmm... Guess you can tell which side of *that*
> debate I'm on, eh?]  The "when I write powers of 10 which are 3*N
> just *asssume* that I meant powers of 2 which are 10*N" hack simply
> fails to work correctly when *some* of the "powers of 10" are *really*
> powers of 10. It also fails to work correctly with things that aren't
> instrinsically quantized in powers of 2 at all.
> 
> Examples: I've had to grab people by the scruff of the neck and push
> their faces into the applicable reference texts before they believe me
> when I say that gigabit Ethernet really, really *is* 1000000000.0 bits
> per second [peak payload, not encoded rate], not 1073741824, and that
> 64 kb/s DS0 telephone circuits really *are* 64,000.0 bits/sec, not 65536.
> [And, yes, 56 kb/s circuits are 56000 bits/sec, not 57344.]

Yes,  that's  because  telecoms  are  not  computers.  In  particular,
telecoms were  invented long before  computers and binary  base became
interesting.

On the other hand, hard drives are purely computer stuff...
 

> Solution: *Always* use the internationally-recognized binary prefixes
> <URL:http://physics.nist.gov/cuu/Units/binary.html> when that's really
> what you mean, and leave the old scientific/engineering notation alone,
> as pure powers of 10. [Note: The historical notes on that page are well
> worth reading.]

Perhaps we  should start serriously to  use the kibi  (Ki), mibi (Mi),
gibi (Gi), tibi (Ti), etc, that have been proposed.


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F853D60.9E133724@setf.de>
i realize that this thread is hopelessly amorphous, but this post did
introduce some concrete issues which bear concrete responses...

Andrew Dalke wrote:
> 
> ...
> 
> What's unicode support like in general for Lisp?  Found an
> answer in  http://www.cliki.net/Unicode%20Support Digging
> some more, it looks like CLisp uses .. UCS-4 and Unicode 3.2
> (from clisp.cons.org).  But do regexps work on unicode strings?
> How portable are unicode strings?  I figure they must be in
> order to handle XML well.  ... "ACL does not support 4 byte
> Unicode scalar values" says franz.com.  www.cl-xml.org says
> "The processor passes 1749 of the 1812 tests .. when the base
> implementation supports sixteen-bit charactrs." and that
> MCL, LispWorks and the Allegro 5.0.1 international version
> support 16-bit Unicode while Allegro ascii only supports 8bit.
> So some have UCS-2 and some UCS-4.
> 
> Is there consensus on the Unicode API?

there are several problems with a "uniform" unicode implementation. if you
look through the info-mcl archives you will find a thread where i tried to
achieve some clarity as to what was necessary. 

i got only as far as the realization that, in order to be of any use, unicode
data management has to support the eventual primitive string operations. which
introduces the problem that, in many cases, these primitive operations
eventually devolve to the respective os api. which, if one compares apple and
unix apis are anything but uniform. it is simply not possible to provide them
with the same data and do anything worthwhile. if it is possible to give some
concrete pointers to how other languages provide for this i would be grateful.

given this situation. i posted several suggestions as to how they might
represent unicode and effect encoding and decoding such that variations were
at least managed in a uniform manner. i received one (1) answer, to the effect
that "that sound's ok to me." so i left the implementation the way it was, to
signal an error upon discovering surrogate pairs. i've yet to have anyone
suggest that that impedes processing. to be quite honest, that surprises me
and i have no idea what people do with surrogate pairs. 

this is effectively the same level of support as java, and i have to admit, i
don't understand what people really do with them in java either. the string
representation is effectively utf-16, so anything outside of the base plane is
not a first-class object. in which environment the "consensus" above should
actually be better spelled "chimera". 

> 
> On the XML path, I found cl-xml.  Looking at the bugs section in
>   http://pws.prserv.net/James.Anderson/XML/documentation/cl-xml.html
> It says "the implementation form for HTTP support is determined
> at compilation time." Is it really true that even HTTP handling is
> different on the different implementations?

yes, there are several available common-lisp implementations for http clients
and servers. they offer significant trade-offs in api complexity,
functionality, resource requirements and performance. you do need to pick one
according to your application needs and declare which one you have chosen. for
a default implementation of client functionality, cl-xml, as any other lisp
application, must take into acount that some necesary stream and
network-related functions are available through implementation-specific
libraries only. again, as for other common-lisp libraries, for the
implementation to which it has been ported, it does this automatically.

> 
> And the section under "porting" is .. strange.  It looks like to
> use the XML API for a given Lisp I need to know enough
> about the given implementation to configure various settings,
> so if I wanted to learn Lisp by writing, say, a simple XML-RPC
> client then I have to learn first what it means "to complete
> definitions in the following files" and the details of "defsystem",
> "package", "STREAM-READER / -WRITER", etc.

if one needs to _port_ it to a new lisp, yes. perhaps you skipped over the
list of lisps to which it has been ported. if you look at the #+/-
conditionalization, you may observe that the differences are not significant.

> 
> That reminds me of my confusion testing a biolisp package.
> I needed to edit the file before it worked; something to do
> with commenting/uncommenting the right way to handle
> packages.  I prefer to start with working code.

it is refreshing, that you describe it as "your" confusion. there was one
correspondent who, at the outset, judging from their initial enquiries, was
looking at their first '(' ever, but wrote in short order about processing
12MB files. should one have problems using a given common lisp library,
concrete questions and illustrations of points which are unclear are always
more productive than vague chacterizations.

...
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <v1ihb.4353$dn6.2228@newsread4.news.pas.earthlink.net>
james anderson:
> i realize that this thread is hopelessly amorphous, but this post did
> introduce some concrete issues which bear concrete responses...

Thank you for the commentary.

> i got only as far as the realization that, in order to be of any use,
unicode
> data management has to support the eventual primitive string operations.
which
> introduces the problem that, in many cases, these primitive operations
> eventually devolve to the respective os api. which, if one compares apple
and
> unix apis are anything but uniform. it is simply not possible to provide
them
> with the same data and do anything worthwhile. if it is possible to give
some
> concrete pointers to how other languages provide for this i would be
grateful.

Python does it by ignoring the respective os APIs, if I understand
your meaning and Python's implementation correctly.  Here's some
more information about Unicode in Python

http://www.python.org/peps/pep-0100.html
http://www.python.org/peps/pep-0261.html
http://www.python.org/peps/pep-0277.html

http://www.python.org/doc/current/ref/strings.html

http://www.python.org/doc/current/lib/module-unicodedata.html
http://www.python.org/doc/current/lib/module-codecs.html


> and i have no idea what people do with surrogate pairs.

See PEP 261 listed above for commentary, and you may want
to email the author of that PEP, Paul Prescod.  I am definitely
not the one to ask.

> yes, there are several available common-lisp implementations for http
clients
> and servers. they offer significant trade-offs in api complexity,
> functionality, resource requirements and performance.

And there are several available Python implementations for the same;
Twisted's being the most notable.  But the two main distributions (and
variants like Stackless) include a common API for it, which makes
it easy to start, and for most cases is sufficient.

I fully understand that it isn't part of the standard, but it would be
useful if there was a consensus that "packages X, Y, and Z will
always be included in our distributions."

> if one needs to _port_ it to a new lisp, yes. perhaps you skipped over the
> list of lisps to which it has been ported. if you look at the #+/-
> conditionalization, you may observe that the differences are not
significant.

You are correct, and I did skip that list.

                    Andrew
                    ·····@dalkescientific.com
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F85CEC3.D17BE65E@setf.de>
Andrew Dalke wrote:
> 
> ...
> 
> Python does it by ignoring the respective os APIs,

oh.

>   if I understand
> your meaning and Python's implementation correctly.  Here's some
> more information about Unicode in Python
> 
> http://www.python.org/peps/pep-0100.html
> http://www.python.org/peps/pep-0261.html
> http://www.python.org/peps/pep-0277.html
> 

pep-0261 was to the point. facit: if you build your python for 4-byte
characters you get the full range of scalar values (ie characters) as first
class objects. if you build your python for 2-byte characters you have to
model all scalar values outside of the basic plane as two disjoint code values.

it's analogous to wide/narrow characters in acl, and i recall there being an
open-source lisp which supported 4-byte builds. each catering to their users.
as the saying goes, everybody cooks with water. 

i'd be curious to hear:

was pep-0261 adopted?

has there been any data collected on how many installations are built in the
respective modes. for users in the 4-byte mode, has there been any data on
storage efficiency? on general string-related algorithm performance?

do python programmers really not care about using things like os-native
international type support? [0]


> ...
> 
> 
> I fully understand that it isn't part of the standard, but it would be
> useful if there was a consensus that "packages X, Y, and Z will
> always be included in our distributions."

that may be a market issue. vendors supply what their clients pay for. they
have an interest in product differentiation. open-source developers develop
what they need. they have an interest that their implmentation serves their
needs. there is some overlap, but evidently the market does not compel the
order of consolidation which you envision.

...

[0] http://developer.apple.com/intl/atsui.html
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Cdmhb.4610$dn6.1808@newsread4.news.pas.earthlink.net>
james anderson:
> was pep-0261 adopted?

Yes.

> has there been any data collected on how many installations are built in
the
> respective modes. for users in the 4-byte mode, has there been any data on
> storage efficiency? on general string-related algorithm performance?

Given that most people probably kill-threaded this discussion, you
might want to ask again on c.l.py with a new subject name.

> do python programmers really not care about using things like os-native
> international type support? [0]

I really am not the right person to talk to on this.  I can offer my
opinion, for what that's worth.

The link you gave is to an Apple API for internationalization.  If
both they and Python use the same Unicode encoding, then the
Python unicode data can be passed directly to the API.  I know
there are bindings between Python and the Apple framework --
Apple asked that Python 2.3 be ready in time for OS 10.3,
and I saw a demo using Apple's GUI builder to make code usable
by Python.  For that, see the current state of the MacPython project.

It seems to me then that all Python offers is a way to create and
manipulate the unicode string, and so long as the correct translations
are done at the interface level to platform-specific features (as
when Python's unicode strings are used for a unicode aware
filesystem like MS Windows') then all is fine.

> that may be a market issue. vendors supply what their clients pay for.
they
> have an interest in product differentiation. open-source developers
develop
> what they need. they have an interest that their implmentation serves
their
> needs. there is some overlap, but evidently the market does not compel the
> order of consolidation which you envision.

I listed a set of packages (regexps, unicode, XML, HTTP client&server)
which are included in the free version of Python.  There are also
commercial distributions which add extra modules, like the ones from
activestate and scipy, but it seems that the standard free Lisp distribution

comes with fewer useful modules than the standard Python one.

Conjecture: Is it that the commericial versions of Lisp pull away
some of the people who would otherwise help raise the default
functionality of the free version?  I don't think so... but then why?

                    Andrew
                    ·····@dalkescientific.com
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm4uf6$6oj$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> Conjecture: Is it that the commericial versions of Lisp pull away
> some of the people who would otherwise help raise the default
> functionality of the free version?  I don't think so... but then why?

It's probably just because the Common Lisp community is still relatively 
small at the moment. But this situation has already started to improve a 
lot.


Pascal
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-2AE2EF.19101809102003@news.service.uci.edu>
In article <············@newsreader2.netcologne.de>,
 Pascal Costanza <········@web.de> wrote:

> It's probably just because the Common Lisp community is still relatively 
> small at the moment. But this situation has already started to improve a 
> lot.

It's only been out, what, twenty years? And another twenty before that 
for other lisps... How much time do you think you need?

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <c1phb.28590$pv6.26636@twister.nyc.rr.com>
David Eppstein wrote:
> In article <············@newsreader2.netcologne.de>,
>  Pascal Costanza <········@web.de> wrote:
> 
> 
>>It's probably just because the Common Lisp community is still relatively 
>>small at the moment. But this situation has already started to improve a 
>>lot.
> 
> 
> It's only been out, what, twenty years? And another twenty before that 
> for other lisps... How much time do you think you need?
> 

Hey, we've been dead for thirty years, give us a break.

The bad news for other languages is that the evolution of programming 
languages, like baseball, is a game played without a clock. And the game 
is going our way: languages are evolving towards dynamism, reflection, 
and everything else Lisp invented and still does better than anyone. 
Python is promoting that sea change, and we Lispniks are forever grateful.

But will one of Perl, Python, Ruby, Dylan or Smalltalk steal the prize? 
The only way to do that is to adopt sexprs and macros, and you can't do 
those without becoming Lisp, at which point you lose if you do not match 
the CL spec.

All your bases are us!


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Lulu of the Lotus-Eaters
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065760768.15126.python-list@python.org>
Kenny Tilton <·······@nyc.rr.com> wrote previously:
|> It's only been out, what, twenty years? And another twenty before that
|> for other lisps... How much time do you think you need?

|Hey, we've been dead for thirty years, give us a break.
|The bad news for other languages is that the evolution of programming
|languages, like baseball, is a game played without a clock.

I would think Lisp is more like cricket:  wickets bracket both ends, no
one can actually understand the rules, but at least the players wear
white.

--
Keeping medicines from the bloodstreams of the sick; food from the bellies
of the hungry; books from the hands of the uneducated; technology from the
underdeveloped; and putting advocates of freedom in prisons.  Intellectual
property is to the 21st century what the slave trade was to the 16th.
From: Paul Foley
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m2r81l30tt.fsf@mycroft.actrix.gen.nz>
On Fri, 10 Oct 2003 00:34:10 -0400, Lulu of the Lotus-Eaters wrote:

> Kenny Tilton <·······@nyc.rr.com> wrote previously:
> |> It's only been out, what, twenty years? And another twenty before that
> |> for other lisps... How much time do you think you need?

> |Hey, we've been dead for thirty years, give us a break.
> |The bad news for other languages is that the evolution of programming
> |languages, like baseball, is a game played without a clock.

> I would think Lisp is more like cricket:  wickets bracket both ends, no
> one can actually understand the rules, but at least the players wear
> white.

Oh, come on!  Anyone can understand cricket!  There are two teams.
The team that's in sits out, except for two batsmen, and the other
team come out and try to get the men that are in out.  When a man goes
out, he goes in and another man comes out.  When the team that's in
are all out, except for the one who's not out, the other team goes in,
until they're all out, too; and then a second innings is played.
That's more or less all there is to it!

-- 
Cogito ergo I'm right and you're wrong.                 -- Blair Houghton

(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <n0c9w54o.fsf@ccs.neu.edu>
Paul Foley <···@below.invalid> writes:

> On Fri, 10 Oct 2003 00:34:10 -0400, Lulu of the Lotus-Eaters wrote:
>
>> Kenny Tilton <·······@nyc.rr.com> wrote previously:
>> |> It's only been out, what, twenty years? And another twenty before that
>> |> for other lisps... How much time do you think you need?
>
>> |Hey, we've been dead for thirty years, give us a break.
>> |The bad news for other languages is that the evolution of programming
>> |languages, like baseball, is a game played without a clock.
>
>> I would think Lisp is more like cricket:  wickets bracket both ends, no
>> one can actually understand the rules, but at least the players wear
>> white.
>
> Oh, come on!  Anyone can understand cricket!  There are two teams.
> The team that's in sits out, except for two batsmen, and the other
> team come out and try to get the men that are in out.  When a man goes
> out, he goes in and another man comes out.  When the team that's in
> are all out, except for the one who's not out, the other team goes in,
> until they're all out, too; and then a second innings is played.
> That's more or less all there is to it!

In other words, the man that's in may be out or in.  If he's in, he
can go back out, but if he's out, then he can't go back in.  Once
everyone is out, everyone goes out, then once the in team is out
again, the out team goes in again and everyone in can go out again.

Thanks for straightening that out!
From: Lulu of the Lotus-Eaters
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065809487.22919.python-list@python.org>
|Lulu of the Lotus-Eaters wrote:
|> I would think Lisp is more like cricket:  wickets bracket both ends, no
|> one can actually understand the rules, but at least the players wear
|> white.

Paul Foley <···@below.invalid> wrote previously:
|Oh, come on!  Anyone can understand cricket!  There are two teams.
|The team that's in sits out, except for two batsmen...

I apologize, I overstated it.  I meant "No American can understand..."

FWIW.  I very much enjoyed watching part of an amateur cricket match on
my vacation to Vancouver a few weeks back.  But exactly what they were
doing was as perplexing as the Lisp code in this thread :-).

Yours, Lulu...

P.S. It's odd that I hadn't KNOWN about my Dutch ancestry... but Python
fits my brain, so there must be some.

--
 ·····@   _/_/_/_/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY:_/_/_/_/ v i
gnosis  _/_/                    Postmodern Enterprises         _/_/  s r
.cx    _/_/  MAKERS OF CHAOS....                              _/_/   i u
      _/_/_/_/_/ LOOK FOR IT IN A NEIGHBORHOOD NEAR YOU_/_/_/_/_/    g s
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm66jn$pi8$1@f1node01.rhrz.uni-bonn.de>
David Eppstein wrote:
> In article <············@newsreader2.netcologne.de>,
>  Pascal Costanza <········@web.de> wrote:
> 
> 
>>It's probably just because the Common Lisp community is still relatively 
>>small at the moment. But this situation has already started to improve a 
>>lot.
> 
> 
> It's only been out, what, twenty years? And another twenty before that 
> for other lisps... How much time do you think you need?

AFAIK, Lisp was very popular in the 70's and 80's, but not so in the 
90's. At the moment, Common Lisp is attracting a new generation of 
programmers.

The basic idea of Lisp (programs = data) was developed in the 50's (see 
http://www.paulgraham.com/rootsoflisp.html ). This idea is fundamentally 
different and much more powerful than the approach taken by almost all 
other languages.

You can't argue that. You can argue whether you want that power or not, 
but Lisp is definitely more powerful than other languages in this 
regard. As Eric Raymond put it, "Lisp is worth learning for the profound 
enlightenment experience you will have when you finally get it; that 
experience will make you a better programmer for the rest of your days, 
even if you never actually use Lisp itself a lot."

And, as Paul Graham put it, if you take a language and "add that final 
increment of power, you can no longer claim to have invented a new 
language, but only to have designed a new dialect of Lisp". (see 
http://www.paulgraham.com/diff.html )

These are the essential reasons why it is just a matter of time that 
Lisp will be reinvented and/or rediscovered again and again, and will 
continue to attract new followers. It is a consequential idea once you 
have got it.

"What was once thought can never be unthought." - Friedrich D�rrenmatt

Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Paul F. Dietz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3J2cnRF7EuCHMBuiU-KYiQ@dls.net>
Pascal Costanza wrote:

> David Eppstein wrote:

>> It's only been out, what, twenty years? And another twenty before that 
>> for other lisps... How much time do you think you need?
> 
> 
> AFAIK, Lisp was very popular in the 70's and 80's, but not so in the 
> 90's. At the moment, Common Lisp is attracting a new generation of 
> programmers.

Early lisp usage was driven by government money and the AI bubble.
That declined in the late 1980s or in the 1990s.  Individuals could
not afford adequate hardware to run lisp until sometime in the 1990s.

But now, hardware has more than caught up with the demands of
lisp and individuals are carrying it forward.  This is something
that drives the newer languages also.  The cycle time for
improving the languages or their implementations goes down
as the hardware gets faster.

	Paul
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <wubdw62d.fsf@ccs.neu.edu>
Pascal Costanza <········@web.de> writes:

> AFAIK, Lisp was very popular in the 70's and 80's, but not so in the
> 90's. 

`Popular' in this case being somewhat relative, much like
the way pustular psoriasis is more popular than leprosy.
From: A. Lloyd Flanagan
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <e838aa6e.0310171522.41e694e3@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<············@f1node01.rhrz.uni-bonn.de>...
> David Eppstein wrote:
> > In article <············@newsreader2.netcologne.de>,
> >  Pascal Costanza <········@web.de> wrote:
> > 
> > 
> >>It's probably just because the Common Lisp community is still relatively 
> >>small at the moment. But this situation has already started to improve a 
> >>lot.
> > 
> > 
> > It's only been out, what, twenty years? And another twenty before that 
> > for other lisps... How much time do you think you need?
> 
> AFAIK, Lisp was very popular in the 70's and 80's, but not so in the 
> 90's. At the moment, Common Lisp is attracting a new generation of 
> programmers.
> 

I was a Lisp fan back when Common Lisp came out.  We went from a
stunningly simple language that could be described in a small booklet
to one that couldn't be adequately described in a 300-page tome.  It
was about that time that Lisp dropped off the radar.

Now I have a language called Python, which like the original Lisp can
be described simply but has extraordinary power.  And _it_ is what is
attracting a new generation of programmers.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmq177$pna$1@newsreader2.netcologne.de>
A. Lloyd Flanagan wrote:

> I was a Lisp fan back when Common Lisp came out.  We went from a
> stunningly simple language that could be described in a small booklet
> to one that couldn't be adequately described in a 300-page tome.  It
> was about that time that Lisp dropped off the radar.
> 
> Now I have a language called Python, which like the original Lisp can
> be described simply but has extraordinary power.  And _it_ is what is
> attracting a new generation of programmers.

Common Lisp still has a small core, and most of the stuff of the indeed 
large spec would rather be considered standard libraries in more 
conventional languages.

Yes, it would probably have been better if Common Lisp designers would 
have made this distinction clearer, for example by defining language 
layers. That's maybe the only real mistake they have made. [1]


Pascal

[1] Somewhere in this thread someone accused "us" Lispers that we don't 
admit that Lisp has "bad" features. The reason why wo don't admit 
anything here is not because it doesn't have bad features, but because 
the flexibility of Lisp always allows us to code around these 
misdesigns. And we don't have to wait for some language designer to 
release version x.y of the language to fix a feature of the language.

The fact that Common Lisp is large is indeed the only mistake that we 
can't "code around".
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3fzhr8jtb.fsf@javamonkey.com>
Pascal Costanza <········@web.de> writes:

> The fact that Common Lisp is large is indeed the only mistake that
> we can't "code around".

Well, if you really wanted to you could. Define your own set of
packages that export the right subsets of Common Lisp functionality to
make the language not look so big or to draw out the fact that it is
really a core and the a bunch of libraries on top of it. Then write
your own code in packages that never (:use "CL") but instead (:use
"TINYLISP-CORE" "TINYLISP-STRING" ...) as appropriate.

Of course people who worry about programmers being able to arbitrarily
invent their own dialect will probably have a serious MI if they see
this. (Thus I'm removing c.l.p from the distribution.)

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Gareth McCaughan
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <871xtbuiw9.fsf@g.mccaughan.ntlworld.com>
Peter Seibel wrote:

> Well, if you really wanted to you could. Define your own set of
> packages that export the right subsets of Common Lisp functionality to
> make the language not look so big or to draw out the fact that it is
> really a core and the a bunch of libraries on top of it. Then write
> your own code in packages that never (:use "CL") but instead (:use
> "TINYLISP-CORE" "TINYLISP-STRING" ...) as appropriate.
> 
> Of course people who worry about programmers being able to arbitrarily
> invent their own dialect will probably have a serious MI if they see
> this. (Thus I'm removing c.l.p from the distribution.)

MI = myocardial infarction?

-- 
Gareth McCaughan
.sig under construc
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8765ixmp5s.fsf@bird.agharta.de>
On Thu, 09 Oct 2003 23:31:46 GMT, "Andrew Dalke" <······@mindspring.com> wrote:

> Conjecture: Is it that the commericial versions of Lisp pull away
> some of the people who would otherwise help raise the default
> functionality of the free version?  I don't think so... but then
> why?

I'm pretty sure this is the case. If you lurk in c.l.l for a while
you'll see that a large part of the regular contributors aren't what
you'd call Open Source zealots. Maybe that's for historical reasons, I
don't know. But of course that's different from languages which have
always been "free" like Perl or Python.

To give one example: One of the oldest dynamic HTTP servers out there
is CL-HTTP.[1] I think it is very impressive but it has a somewhat
dubious license which doesn't allow for commercial deployment - it's
not "free." Maybe, I dunno, it would have a much higher market share
if it had been licensed like Apache when it was released. I'm sure
there's much more high-quality Lisp software out there that hasn't
even been released.

Edi.

[1] <http://www.ai.mit.edu/projects/iiip/doc/cl-http/home-page.html>

    Don't be fooled by the "Last updated" line. There's still active
    development - see

    <ftp://ftp.ai.mit.edu/pub/users/jcma/cl-http/devo>.
From: Paolo Amoroso
Subject: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and Scheme]
Date: 
Message-ID: <874qyhky8r.fsf_-_@plato.moon.paoloamoroso.it>
Edi Weitz writes:

> To give one example: One of the oldest dynamic HTTP servers out there
> is CL-HTTP.[1] I think it is very impressive but it has a somewhat
> dubious license which doesn't allow for commercial deployment - it's

Doesn't ITA Software use it?


Paolo
-- 
Paolo Amoroso <·······@mclink.it>
From: Edi Weitz
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and Scheme]
Date: 
Message-ID: <87he2goqqo.fsf@bird.agharta.de>
On Fri, 10 Oct 2003 15:39:48 +0200, Paolo Amoroso <·······@mclink.it> wrote:

> Edi Weitz writes:
> 
> > To give one example: One of the oldest dynamic HTTP servers out
> > there is CL-HTTP.[1] I think it is very impressive but it has a
> > somewhat dubious license which doesn't allow for commercial
> > deployment - it's
> 
> Doesn't ITA Software use it?

  ···@bird:~ > lynx -mime_header http://www.itasoftware.com/ | head -7
  HTTP/1.1 200 OK
  Date: Fri, 10 Oct 2003 19:06:02 GMT
  Server: Apache/1.3.22 (Unix)  (Red-Hat/Linux) PHP/4.1.2 mod_perl/1.24_01
  X-Powered-By: PHP/4.1.2
  Connection: close
  Content-Type: text/html

Not externally, it seems.

BTW, I'm just sheepishly repeating what I've heard about the CL-HTTP
license, I didn't bother to read it myself. But I've heard it quite
often. Maybe someone who knows more wants to comment? Rainer?

Edi.
From: Rainer Joswig
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and Scheme]
Date: 
Message-ID: <joswig-322FBF.16293310102003@news.fu-berlin.de>
In article <··············@bird.agharta.de>, Edi Weitz <···@agharta.de> 
wrote:

> On Fri, 10 Oct 2003 15:39:48 +0200, Paolo Amoroso <·······@mclink.it> wrote:
> 
> > Edi Weitz writes:
> > 
> > > To give one example: One of the oldest dynamic HTTP servers out
> > > there is CL-HTTP.[1] I think it is very impressive but it has a
> > > somewhat dubious license which doesn't allow for commercial
> > > deployment - it's
> > 
> > Doesn't ITA Software use it?
> 
>   ···@bird:~ > lynx -mime_header http://www.itasoftware.com/ | head -7
>   HTTP/1.1 200 OK
>   Date: Fri, 10 Oct 2003 19:06:02 GMT
>   Server: Apache/1.3.22 (Unix)  (Red-Hat/Linux) PHP/4.1.2 mod_perl/1.24_01
>   X-Powered-By: PHP/4.1.2
>   Connection: close
>   Content-Type: text/html
> 
> Not externally, it seems.
> 
> BTW, I'm just sheepishly repeating what I've heard about the CL-HTTP
> license, I didn't bother to read it myself. But I've heard it quite
> often. Maybe someone who knows more wants to comment? Rainer?
> 
> Edi.

Reading the license of any software you are using is always
a good thing.

CL-HTTP is available since 1994 and has been since provided
as a service to the Lisp community. It is not intended to
change that.

Still the CL-HTTP developer(s) don't want to give control
over CL-HTTP away - so it is NOT public domain and it is
NOT GPLed. And that is not about to be changed. 

Ports, contributions and extensions are always welcome and will
be integrated if possible.

Currently a new pre-release version of CL-HTTP is being prepared.
From: james anderson
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and  Scheme]
Date: 
Message-ID: <3F870F21.6306E660@setf.de>
given the number of time zones between the old world and the new, i suspect
the r.joswig is may not be in a position to respond.

it would not hurt to read the cl-http license.[0] i have heard these "dubious"
characterizations often, but the only things in it which could conceivably
give a fair-minded developer cause for concern could be the phrases about
derivative works and future licenses. conceivably. on the other hand, first, i
am not aware of events which could give one cause to believe that these
clauses would impede serious deployment. second, the recent experience with
linux should make clear the limits to the constraints which these clauses
could impose. third, if one followed the protracted discussions on the cmucl
list over the summer as they were considering how to unify the licenses
governing their distribution, the qualification "commerical use is allowed,
but if you want a commercial license we have to agree" is really just a
restatement of the facts.

...

Edi Weitz wrote:
> 
> ...
> 
> BTW, I'm just sheepishly repeating what I've heard about the CL-HTTP
> license, I didn't bother to read it myself. But I've heard it quite
> often. Maybe someone who knows more wants to comment? Rainer?
> 
> Edi.

[0] ftp://ftp.ai.mit.edu/pub/users/jcma/cl-http/devo/cl-http-70-177c-devo.tar.gz
(i observe no individual license text file, but the download is not that
large. and then one would have it, and might be positively surprised.)
From: Edi Weitz
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and  Scheme]
Date: 
Message-ID: <873ce0omi7.fsf@bird.agharta.de>
On Fri, 10 Oct 2003 21:58:28 +0200, james anderson <··············@setf.de> wrote:

> it would not hurt to read the cl-http license.[0]

> [0] ftp://ftp.ai.mit.edu/pub/users/jcma/cl-http/devo/cl-http-70-177c-devo.tar.gz
> (i observe no individual license text file, but the download is not that
> large. and then one would have it, and might be positively surprised.)

OK, I just did it. My copy came with a license file right in the main
directory - it's called '-license-.text' (sic!) so maybe some
operating systems don't show it. It can also be found here:

  <http://wilson.ai.mit.edu/cl-http/license.text>

Now that I've read it I think this is a fairly restrictive license and
I can understand that people have called it "dubious." It also looks
like the copyright holder is one single person so it shouldn't be a
problem[1] to change the license to something like the LPGL or a
BSD-style license if the author is interested in wider
distribution.[2]

I wouldn't mind using CL-HTTP for private stuff but I would hesitate
to offer it to a client of mine as long as it has this license. I'd
rather pay for it if such an option were available for commercial
deployment.

> second, the recent experience with linux should make clear the
> limits to the constraints which these clauses could impose.

Yes, probably. I'm not a lawyer and I'm actually not interested in
discussing licenses. I'm happy to use quality free software and I'm
happy to pay for quality commercial software if I the price is OK. I
just want a license that looks reasonably clear to me - not something
like "we reserve all rights and you'll get more details as soon as we
know them."

> third, if one followed the protracted discussions on the cmucl list
> over the summer as they were considering how to unify the licenses
> governing their distribution, the qualification "commerical use is
> allowed, but if you want a commercial license we have to agree" is
> really just a restatement of the facts.

I don't get that one. I thought CMUCL is in the public domain. How
else would SCL be possible?

Cheers,
Edi.

[1] as opposed to something like Plob! where you obviously can't
    license the underlying POSTORE database because there's nobody who
    can make a decision about it

[2] "Subsequent versions of CL-HTTP may have different copyright
     statements and license requirements once it becomes clear
     precisely what arrangements best serve the Lisp community."
From: Marc Spitzer
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and   Scheme]
Date: 
Message-ID: <86vfqvsmm5.fsf@bogomips.optonline.net>
Rainer Joswig <······@lispmachine.de> writes:

> In article <··············@bogomips.optonline.net>,
>  Marc Spitzer <········@optonline.net> wrote:
> 
> > Rainer Joswig <······@lispmachine.de> writes:
> > 
> > > In article <··············@bird.agharta.de>, Edi Weitz <···@agharta.de> 
> > > wrote:
> > > 
> > > > On Fri, 10 Oct 2003 23:28:05 +0200, james anderson <··············@setf.de> wrote:
> > > > 
> > > > > is there any license which is not restrictive?
> > > > 
> > > > Well, there are some that have very simple restrictions that I can
> > > > easily live with like BSD-style licenses.
> > > > 
> > > > > i'm not being rhetorical. i'm asking, what are the undue
> > > > > restrictions?
> > > > 
> > > > c. "The licensee submits any extensions or improvements to CL-HTTP to
> > > >     the developers at ···········@ai.mit.edu;"
> > > > 
> > > > j. "Any modifications by the licensee to the authoritative CL-HTTP
> > > >     must be distributed publicly as separate entities;"
> > > > 
> > > > AFAIK, even the very restrictive GPL doesn't force you to do
> > > > that. With GPL'd software you must license modified code under the GPL
> > > > - but /only/ if you re-distribute it. Also, the GPL doesn't force you
> > > > to send your modifications to a specific address. Someone correct me
> > > > if I'm wrong.
> > > 
> > > We WANT improvements back in return for a significant amount
> > > of effort that has gone into this software.
> > > 
> > > CL-HTTP has been used in some of the most prominent Lisp
> > > software applications ever. Examples were the White House
> > > Publications Server for President Clinton and ELM-ART (which
> > > got the European Academic Software Award in 1998). So developing
> > > it did "something" for the Lisp community. I think it is fair
> > > enough for not letting the CL-HTTP software sleep on some locked
> > > file server to ask for some return.
> > 
> > ask and require are not the same.  
> 
> If you don't have any improvements, you don't have to provide
> them.

And how does this respond to ask and require are not the same?
Also who defines what an improvement is?  Again think of yahoo 
store or ssl or web-dav.

>  
> > > 
> > > > d. "The licensee prominently displays the fact that your application
> > > >     uses CL-HTTP;"
> > > > 
> > > > e. "The licensee prominently indicates that CL-HTTP was developed by
> > > >     and is owned by John C. Mallery;"
> > > > 
> > > > The other webservers I know don't have similar restrictions. Also, I
> > > > cannot imagine a customer who likes to be forced to "prominently
> > > > display" anything on his website.
> > > 
> > > Mentioning CL-HTTP in some "about" page is usually fine.
> > 
> > I do not know, I would think prominently would mean, at the very
> > least, on the home page.  And this is bad if you are trying to use
> > CL as a secret weapon.
> 
> I do know. A remark on an about page is sufficient.

In all honestly that does not seem prominent, right out in front 
and clearly/very visible.  I am not arguing that your above statement 
conveys the authors intent but is that is true it is not reflected in 
the wording of the original license

> 
> > > 
> > > > h. "The licensee informs the CL-HTTP user community of any novel or
> > > >     significant uses in a timely manner by submitting a short
> > > >     description of the server to ······@ai.mit.edu"
> > > > 
> > > > Pardon? What if my application is a top-secret intranet?
> > > 
> > > You can always find more IFs and never get anything done.
> > 
> > well unlike me, I think Edi has done stuff.  And lets say you manage
> > to come up with a novel useful idea for a website and this makes you
> > a lot of money, think yahoo store, under the above listed terms you must
> > give your source code away.  This does not make for happy owners.
> 
> Another one coming up with more IFs. Guess what, you can always ask
> and if you have an application that makes you a lot of money
> there will be a solution.

and 'IF' that solution is give me your code or give me 10% of your business.


> 
> People don't have to give their source code
> for their application away. Just the improvements to CL-HTTP itself
> have to be given back.

What about a web-dav module, would that be considered as an improvement
to cl-httpd or as my code?  There is a good argument to be made for both.
Or a ssl module.

> 
> > 
> > marc
> > 
> > ps I really am not trying to start an licenceing thread here
> > 
> 
> All you have added to the discussion was FUD, uninformed guessing
> and confusion. Thanks.

For all my faults I do admit when I am wrong and I do not engage in
FUD.  All you need to do is come up with facts and logical arguments 
to convince me.  Now accusing me of FUD *without* answering any of my
questions or disproving any of my statements is a personal attack which 
I did nothing to bring on.  So exactly when did you *realize* that your
position was logically flawed and that you needed to resort to personnel
attacks to /win/?

Now the original point of this argument was the license that cl-httpd was
released under was that it was less then friendly to commercial use.  I
think that this has been shown to be so for the following reasons:
1: A vague advertising clause that could be interpreted in one of 
   several ways,ie in the about page(your statement) or on the home
   page or on every page.
2: A requirement that improvements must be submitted back to the project.
   Along with no definition of what an improvement is.  

marc
From: Rainer Joswig
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and   Scheme]
Date: 
Message-ID: <joswig-A79C6B.15564911102003@news.fu-berlin.de>
In article <··············@bogomips.optonline.net>,
 Marc Spitzer <········@optonline.net> wrote:

> > > I do not know, I would think prominently would mean, at the very
> > > least, on the home page.  And this is bad if you are trying to use
> > > CL as a secret weapon.
> > 
> > I do know. A remark on an about page is sufficient.
> 
> In all honestly that does not seem prominent, right out in front 
> and clearly/very visible.

It is. If CL-HTTP is used for a website, mentioning CL-HTTP
from the home page on an "about page" is okay. That
is where one would usually find such information.

If CL-HTTP is being used embedded in some application,
then mentioning it in the About dialog box is fine.
Another nice place is a manual for that software.

If you use CL-HTTP for your research, then mentioning
CL-HTTP in the research paper is fine, too.

>  I am not arguing that your above statement 
> conveys the authors intent but is that is true it is not reflected in 
> the wording of the original license

FUD.

> > People don't have to give their source code
> > for their application away. Just the improvements to CL-HTTP itself
> > have to be given back.
> 
> What about a web-dav module, would that be considered as an improvement
> to cl-httpd or as my code?  There is a good argument to be made for both.
> Or a ssl module.

If you are in that situation, that you would develop
such things, ask and you get an answer. Both modules would
be pretty interesting to CL-HTTP users, so a contribution
would be welcome anyway.

<bullshit deleted>

> Now the original point of this argument was the license that cl-httpd was
> released under was that it was less then friendly to commercial use.  I
> think that this has been shown to be so for the following reasons:
> 1: A vague advertising clause that could be interpreted in one of 
>    several ways,ie in the about page(your statement) or on the home
>    page or on every page.

You seem not to have any idea, that you can ask for clarification
and you already got one.

> 2: A requirement that improvements must be submitted back to the project.
>    Along with no definition of what an improvement is.  

Ask case by case and you get an answer.

Several people have developed extensions and not contributed back,
which is sad.
From: Marc Spitzer
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and   Scheme]
Date: 
Message-ID: <8665ivmje8.fsf@bogomips.optonline.net>
Rainer Joswig <······@lispmachine.de> writes:

> In article <··············@bogomips.optonline.net>,
>  Marc Spitzer <········@optonline.net> wrote:
> 
> > > > I do not know, I would think prominently would mean, at the very
> > > > least, on the home page.  And this is bad if you are trying to use
> > > > CL as a secret weapon.
> > > 
> > > I do know. A remark on an about page is sufficient.
> > 
> > In all honestly that does not seem prominent, right out in front 
> > and clearly/very visible.
> 
> It is. If CL-HTTP is used for a website, mentioning CL-HTTP
> from the home page on an "about page" is okay. That
> is where one would usually find such information.
> 
> If CL-HTTP is being used embedded in some application,
> then mentioning it in the About dialog box is fine.
> Another nice place is a manual for that software.
> 
> If you use CL-HTTP for your research, then mentioning
> CL-HTTP in the research paper is fine, too.
> 
> >  I am not arguing that your above statement 
> > conveys the authors intent but is that is true it is not reflected in 
> > the wording of the original license
> 
> FUD.

yea well fuckl you too

> 
> > > People don't have to give their source code
> > > for their application away. Just the improvements to CL-HTTP itself
> > > have to be given back.
> > 
> > What about a web-dav module, would that be considered as an improvement
> > to cl-httpd or as my code?  There is a good argument to be made for both.
> > Or a ssl module.
> 
> If you are in that situation, that you would develop
> such things, ask and you get an answer. Both modules would
> be pretty interesting to CL-HTTP users, so a contribution
> would be welcome anyway.

But you still have not clarified wether the contribution would be
compelled under the terms of the licence.  You are completely and
deliberatly ignoring the question asked, is a yes or no answer so hard
to come up with?

> 
> <bullshit deleted>

I am sure it is bull shit when you do not agree with it for emotional reasons.
> 
> > Now the original point of this argument was the license that cl-httpd was
> > released under was that it was less then friendly to commercial use.  I
> > think that this has been shown to be so for the following reasons:
> > 1: A vague advertising clause that could be interpreted in one of 
> >    several ways,ie in the about page(your statement) or on the home
> >    page or on every page.
> 
> You seem not to have any idea, that you can ask for clarification
> and you already got one.
> 
> > 2: A requirement that improvements must be submitted back to the project.
> >    Along with no definition of what an improvement is.  
> 
> Ask case by case and you get an answer.

Why not have a clear licence so there is no case by case issue?
> 
> Several people have developed extensions and not contributed back,
> which is sad.

But are they in violation of the licence, yes or no or perhaps?

marc
From: james anderson
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and    Scheme]
Date: 
Message-ID: <3F88483C.89EC9CA5@setf.de>
Marc Spitzer wrote:
> 
> ...
> Now the original point of this argument was the license that cl-httpd was
> released under was that it was less then friendly to commercial use. 

if one makes it through my earlier post, one may witness the argument that it
is actually friendlier to commerical use than most free software licenses.

>   I
> think that this has been shown to be so for the following reasons:
> 1: A vague advertising clause that could be interpreted in one of
>    several ways,ie in the about page(your statement) or on the home
>    page or on every page.

which, to the limited extent that a one-sided agreement can exist, would mean
that the licensee would get to assert any reasonable interpretation. at the
time i was considering using cl-http, my interpretation was that i would be
able to fulfill it by disclosing it in the license agreement with my clients.
while it is true, that this is even narrower than r.joswig's clarification, i
suggest that it would full the letter of the license.

> 2: A requirement that improvements must be submitted back to the project.
>    Along with no definition of what an improvement is.

let us reiterate that clause. it says:

"The licensee submits any extensions or improvements to CL-HTTP to the
developers at ···········@ai.mit.edu"

as i noted in the earlier message, it does not say one agrees to grant the
developers the copyrights to those changes. it would be unlikely that it could
be interpreted to intend that as the other clauses clearly differentiate the
release proper from derivative works and do so in such a way one could even
say derivative works are being disavowed. it does not _even_ say that the
licensee need grant the original developers the rights to use the corrections,
extensions, whatever. it says nothing about inclusion in future releases or
anything at all about anything happening with the disclosed information. as
such, there is no concern that by agreeing to this document - as this document
reads - one gives up in advance rights to something one develops in the
future. i can think of plenty of things which the license could have said
which could have given rise to such concerns. it does not.

> 
> marc
From: Marc Spitzer
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and    Scheme]
Date: 
Message-ID: <86r81jskk9.fsf@bogomips.optonline.net>
james anderson <··············@setf.de> writes:

> Marc Spitzer wrote:
> > 
> > ...
> > Now the original point of this argument was the license that cl-httpd was
> > released under was that it was less then friendly to commercial use. 
> 
> if one makes it through my earlier post, one may witness the argument that it
> is actually friendlier to commerical use than most free software licenses.

It kind of depends on how you define 'free' and that is a whole nother
thread.  When I see 'free' I think PD, MIT/X, BSD, BSD2.  I do not think
gpl or lgpl or the like.

> 
> >   I
> > think that this has been shown to be so for the following reasons:
> > 1: A vague advertising clause that could be interpreted in one of
> >    several ways,ie in the about page(your statement) or on the home
> >    page or on every page.
> 
> which, to the limited extent that a one-sided agreement can exist,
> would mean that the licensee would get to assert any reasonable
> interpretation. at the time i was considering using cl-http, my
> interpretation was that i would be able to fulfill it by disclosing
> it in the license agreement with my clients.  while it is true, that
> this is even narrower than r.joswig's clarification, i suggest that
> it would full the letter of the license.
> 
> > 2: A requirement that improvements must be submitted back to the project.
> >    Along with no definition of what an improvement is.
> 
> let us reiterate that clause. it says:
> 
> "The licensee submits any extensions or improvements to CL-HTTP to the
> developers at ···········@ai.mit.edu"
> 
> as i noted in the earlier message, it does not say one agrees to
> grant the developers the copyrights to those changes. it would be
> unlikely that it could be interpreted to intend that as the other
> clauses clearly differentiate the release proper from derivative
> works and do so in such a way one could even say derivative works
> are being disavowed. it does not _even_ say that the licensee need
> grant the original developers the rights to use the corrections,
> extensions, whatever. it says nothing about inclusion in future
> releases or anything at all about anything happening with the
> disclosed information. as such, there is no concern that by agreeing
> to this document - as this document reads - one gives up in advance
> rights to something one develops in the future. i can think of
> plenty of things which the license could have said which could have
> given rise to such concerns. it does not.

Thanks for the clarification.  

marc

> 
> > 
> > marc
From: james anderson
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and     Scheme]
Date: 
Message-ID: <3F8850EB.A0DBA9B5@setf.de>
Marc Spitzer wrote:
> 
> james anderson <··············@setf.de> writes:
> 
> > Marc Spitzer wrote:
> > >
> > > ...
> > > Now the original point of this argument was the license that cl-httpd was
> > > released under was that it was less then friendly to commercial use.
> >
> > if one makes it through my earlier post, one may witness the argument that it
> > is actually friendlier to commerical use than most free software licenses.
> 
> It kind of depends on how you define 'free' and that is a whole nother
> thread.  When I see 'free' I think PD, MIT/X, BSD, BSD2.  I do not think
> gpl or lgpl or the like.
> 
again, if one makes it through my earlier post, one will witness the argument
that the cl-http license is actually friendlier to commercial use than a
bsd-style license. even if one can avoid some of the issues apparent in that
particular case, one cannot avoid those of collective works and that unless
there is an exchange there need not be an agreement. whatever the license
purports to permit.

...
From: james anderson
Subject: Re: CL-HTTP commercial deployment
Date: 
Message-ID: <3F8827D6.966072CD@setf.de>
i have heard of these sort of objections to the cl-http license before. i have
never understood them. in the belief that genuine misunderstanding has
engendered purportedly informative statements like, "CL-HTTP is NOT 'free'
software So it does not belong here."[0] this note goes to some length to
explicate the license[4] and to indicate why these sorts of objections are
most likely groundless. it would be unfortunate, if ones perception of
cl-http's suitability for deployment as a component of open source lisp
projects were distorted by a misaprehension of the distinction between "free"
and "open", and without benefit of the realization, that much of "free"
software is but a figment of the observer's imagination.

those, for whom this is just boring stuff which has no pertinence to shared
source development, need not read on. but then i would ask that, if one has no
convincing counter-arguments, they should at least admit so and suggest to the
author of [0] that they should well edit it to improve its relevance.

to begin, one must recognize that, no license means anything outside of the
context of an agreement. that one party takes something from the other does
not create an agreement. there is no contract until there has been an
exchange. the grants which a given license may describe do not have effect
unless there is an agreement. not only that, in some cases, some of the rights
which some licenses purport to grant are simple not transferrable.

for example, cl-gd[1] describes the terms of its license as a "BSD-style
license", i suspect this was intended to mean that the use and source/binary
redistribution of the respective version (0.1.0) is permitted so long as the
licensee permits further distribution. aside from the complications, that as
of 20030925, the distribution, did not appear to actually contain a readily
recognizable license a "bsd-style license" does not specify the terms which
will apply to source in the event of a binary redistribution and it introduces
the concept of "derived" software only in the clause governing
non-endorsement. which, for those who like to believe "what the license says",
is worse than if it had left the concept out.


beyond this issue of the license document itself, there is the small problem
that the software is distributed from a ".de" domain, at the discretion of the
ip holder, who, judging from the mail address, developed the package within
the purview of german intellectual property law. this aside from the issue
that if the developer is a german national, the actual locus of development is
not material.

which means that, in additional to that which may appear to be intuitively
obvious to the casual observer upon an initial reading of the license, any
court which is called upon to adjudicate a dispute about which actions the
purported contract might eventually compell, will likely interpret it in the
context of german intellectual property law. which law expressly excludes one
of the grants which this license might have been understood as having been
intended to make.[3] namely the right to benefit economically from the
application of the intellectual property. that is, despite the best of intent,
and even ignoring the rather glaring ambiguity in the terms of the contract
itself, the license has no effect beyond an expression of goodwill.

it is true that one can distinguish the grant of a "right to use" from a
"right to economic benefit", but that does not change the uncertainty for the licensee.

it is also true, that the situation is mitigated by the fact that the author
is a single person, and that the software distributed is their own work, but
it is not clear how that would change the outcome of some future dispute.

in cases like cl-http or cmucl, on the other hand, even this does not apply.
they are the aggregate of the contributions of several developers, the
respective rights to which the respective single developer only can grant. one
might think that it is possible to esablish a collective body to assume those
rights and then transfer them, but it just isn't. unless there is a clear
exchange between that entity and the developer, eg, the work is done for hire,
any claims of transfer are without effect.

so, in the context, if you look at the cl-http license[4], you see the following

- the author reserves any rights which he does not explicitly
  grant. this is normal.
- the author does not make any grant of the rights of the other
  contributors. he cannot. if this were not there the license would
  be completely meaningless.
- the author disclaims warranty. that is normal.
- the author asserts that if one uses or retains the distribution,
  one can be held to its terms:
-- that copyright notices are preserved. that is normal
-- that code developed by the licensee by kept separate.
   this is beneficial.
   a later clause makes it obvious that this covers both application
   and derivative code.
-- extensions and improvements go back to the cl-http developers.
   note that this does not say, "grant copyright to".
   note that this does not even say, "grant use rights to".
   it just says "disclose".
   if anything, this clause should be welcome by a potential
   commercial developer
   as it is one of the few in open source contracts which actually
   establishes terms of exchange.
-- deployments must disclose that the software is used. that
   never struck me as any different than the startup banner of
   every lisp i've used. the presence of which has never deterred me
   from clarifying if and how they are to be disabled. the
   further communication from as r.joswig reiterates that no
   reasonable interpretation of this clause can be cause for concern.
-- deployments must disclose the copyright. i suppose one might be
   concerned about the issues which eventually led to elimination of
   in-band copyright notices on bsd, but such events would surprise
   me.
-- the provenance information must include the location for the
   definitive source. it might be objected that this is an undue
   burden, but, on the other hand, this clause, contrary to most
   other open software licenses, binds the licensor as much, if not
   more, than the licensee.
-- significant deployments must be disclosed to the author. one might
   object, that this is an undue constraint, but similar to the
   "definitive source" clause, once the author has been informed,
   there is no more uncertainty as to whether an agreement exists.
-- if there is a redistribution it must be as verbatim source. i
   suppose this does not adequately define the terms for binary
   installations. i suspect a one-line email resolve uncertainty.
-- the same terms apply to distributing modifications as to
   distributing derivative works and applications. this is innocuous
   and is not counter to dsfg.4.[5]
-- that the field of endeavour is subject to approval. this is
   counter to dsfg.6, but causes no uncertainty. in particluar, given
   the disclosure clause, any uncertainty should be eliminated from 
   the outset.
-- the http headers must be authentic.
-- academic publications include accurate references.

so, what we have here is a license which, much to the benefit of the
prospective licensee, actually goes to extraordinary length - for an open
source license - to establish that an exchange actually is intended to occur.
given which, unless one adheres to the political view, that "free" software is
simply better than "open" software, there is nothing in these terms which, in
itself, could serve to eliminate this software on business or engineering
grounds. 

not even that the license says nothing about the author's future actions
beyond those specifics noted above. that is to be expected, as there is no
contract. there has been no exchange. nothing has been transferred back to
them and as such it is not possible for them to agree to anything or to expect
them to perform in the future.

one may object, and refer to exemplary documents, such as the open software
code, adherence to which is one of the things which distinguishes "free" from
"non-free" software. it contains an exposition of "free software guidelines",
and exhibits them in the context of a "social contract" with the free software
community. upon reflection however, it appears obvious to this casual
observer, that, as well-meaning as the declaration may be, it, in itself, has
no value as the basis for either engineering or business decisions. should, in
this instance, debian decide to change its business plan tomorrow, neither any
debian contributor, nor any debain subscriber would have any recourse. please
note i have not said that the guidelines are unclear, just that they, in
themselves, mean nothing. despite what the casual reader may believe upon an
initial examination.

...

n++k wrote:
> 
> Rainer Joswig <······@lispmachine.de> wrote in message news:<····························@news.fu-berlin.de>...
> > In article <············@comcast.net>, ·············@comcast.net wrote:
> >
> > Anyway, if people have applications in mind and they have
> > a problem with a certain part of the license, they can
> > always ASK. MAYBE they even get a positive answer. Who
> > knows.
> 
> Maybe because they believe that what the license says is more
> important and "correct" that what its author thinks/says it means?

[0] http://www.cliki.net/CL-HTTP
[1] http://www.weitz.de/cl-gd/
[2] http://www.opensource.org/licenses/bsd-license.php 
[3] http://www.gema.de/urheberrecht/urhg/urheberrechtsgesetz_teil1.shtml is
all i could put my finger on now. there is a protected discussion in the cmucl
mailing list with various english translations.
[4] http://wilson.ai.mit.edu/cl-http/license.text
[5] http://www.debian.org/social_contract#guidelines
From: Edi Weitz
Subject: Re: CL-HTTP commercial deployment
Date: 
Message-ID: <877k3b36f7.fsf@bird.agharta.de>
On Sat, 11 Oct 2003 17:56:49 +0200, james anderson <··············@setf.de> wrote:

> for example, cl-gd[1] describes the terms of its license as a
> "BSD-style license", i suspect this was intended to mean that the
> use and source/binary redistribution of the respective version
> (0.1.0) is permitted so long as the licensee permits further
> distribution. aside from the complications, that as of 20030925, the
> distribution, did not appear to actually contain a readily
> recognizable license

The distribution (0.1.0 as well as the current 0.1.4) contains a
readily recognizable license in each and every code file. Open one of
the *.lisp or *.c files and you'll see it.

Here it is, for your convenience:

;;; Copyright (c) 2003, Dr. Edmund Weitz.  All rights reserved.

;;; Redistribution and use in source and binary forms, with or without
;;; modification, are permitted provided that the following conditions
;;; are met:

;;;   * Redistributions of source code must retain the above copyright
;;;     notice, this list of conditions and the following disclaimer.

;;;   * Redistributions in binary form must reproduce the above
;;;     copyright notice, this list of conditions and the following
;;;     disclaimer in the documentation and/or other materials
;;;     provided with the distribution.

;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;;; ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

> a "bsd-style license" does not specify the terms which will apply to
> source in the event of a binary redistribution

Huh?

> and it introduces the concept of "derived" software only in the
> clause governing non-endorsement. which, for those who like to
> believe "what the license says", is worse than if it had left the
> concept out.

Sorry, I can't really see what's so unclear about the license (not to
mention that the word "derived" doesn't even appear in that text).

As to your other points: Some of them are very interesting. I'm just
wondering about their authoritative status. Is this something you
believe or is it something you've read somewhere? Are you are lawyer?
I mean, could I just download, say, CL-XML, break the license and then
tell the judge: "You think you know the truth, buddy, but you haven't
read Usenet posting <·················@setf.de> which clearly says
that 'no license means anything outside of the context of an
agreement. that one party takes something from the other does not
create an agreement. there is no contract until there has been an
exchange.' There has never been any exchange nor an agreement between
me and the CL-XML developers, I've just downloaded a tar archive from
their server. It doesn't matter whether this archive contains the LPGL
or not."

:)

Concerning CL-HTTP: It is not my intent to vilify CL-HTTP. I think we
both agree that there has been some confusion about their license
(exemplified by the fact that somebody removed it from CLiki because
he thought it was "not free"). If anything, this thread has hopefully
provided some clarification, specifically through Rainer Joswig's
comments.

Edi.
From: Rainer Joswig
Subject: Re: CL-HTTP commercial deployment
Date: 
Message-ID: <joswig-B15EFF.16065411102003@news.fu-berlin.de>
> Concerning CL-HTTP: It is not my intent to vilify CL-HTTP. I think we
> both agree that there has been some confusion about their license
> (exemplified by the fact that somebody removed it from CLiki because
> he thought it was "not free"). If anything, this thread has hopefully
> provided some clarification, specifically through Rainer Joswig's
> comments.

For the CLIKI community it is not "free", so it does not belong
there. Especially I'm tired discussing the same thing for
quite some time. Fortunately there are alternatives, so
one does not have to use CL-HTTP.

Though there are people understanding it. For the 70.180
prerelease we got patches and feedback from US, GB, Spain and Germany
for following ports: LispWorks, (Open) Genera, CMUCL, ACL and MCL.
More stuff needs to be done.
From: james anderson
Subject: Re: CL-HTTP commercial deployment
Date: 
Message-ID: <3F8869C8.E71FC537@setf.de>
Edi Weitz wrote:
> 
> ...
> 
> The distribution (0.1.0 as well as the current 0.1.4) contains a
> readily recognizable license in each and every code file. Open one of
> the *.lisp or *.c files and you'll see it.
> 
> Here it is, for your convenience:
> 
thank you.

> [cl-gd license]
> 
> > a "bsd-style license" does not specify the terms which will apply to
> > source in the event of a binary redistribution
> 
> Huh?

what is the status of source, both the original and any derived or application
source when there is a binary-only distribution?

> 
> > and it introduces the concept of "derived" software only in the
> > clause governing non-endorsement. which, for those who like to
> > believe "what the license says", is worse than if it had left the
> > concept out.
> 
> Sorry, I can't really see what's so unclear about the license (not to
> mention that the word "derived" doesn't even appear in that text).

i was treating bsd-style generically, as an exemplar of a freer license, and
examining it with respect to its clarity. the word appears in thr prototype
which the cl-gd license adapted.

> 
> As to your other points: Some of them are very interesting. I'm just
> wondering about their authoritative status. Is this something you
> believe or is it something you've read somewhere?

i believe it all. i have read some of it elsewhere. on the occasion of the
cmucl discussions i read through the pertinent german laws and through those
documents on the wipo site which pertain to internation ip law.

>   Are you are lawyer?

no i am not. i just try to read and understand the licenses i deal with. in
one of the cmucl exchanges the question was posed to me whether i thought the
cl-xml license was adequate. (it is an lgpl license). my intuition was, "no",
but i felt i should find out. so i did. the eventual answer was, "if a
commercial developer wants to use it, actually, no, it is not." i suspect the
next release will have a different license. 

remember, we're talking about uncertainty here.

> I mean, could I just download, say, CL-XML, break the license and then
> tell the judge: "You think you know the truth, buddy, but you haven't
> read Usenet posting <·················@setf.de> which clearly says
> that 'no license means anything outside of the context of an
> agreement. that one party takes something from the other does not
> create an agreement. there is no contract until there has been an
> exchange.'

i suggest that the argument would fail.

>    There has never been any exchange nor an agreement between
> me and the CL-XML developers, I've just downloaded a tar archive from
> their server. It doesn't matter whether this archive contains the LPGL
> or not."
> 

it appears that you do not appreciate the asymmetry. when one takes a
distribution, one has taken something. as such one will be accountable to the
strict terms which allowed one to take it. the strict terms. where one has not
transferred anything in return, one cannot claim any rights. the restrictions
run in one direction only. the taker can neither expect to get anything in the
future, nor - and this is the particularly perverse point - be absolutely
guarenteed that the licensor does not at some point ask to have the thing back.

remember, we're talking about certainty here.

the original questions which were raised about the cl-http license were
directed to certainty as to its terms and its consequent suitability as a
license for commercial derivative or application development. i have attempted
to make clear that uncertainty is inherent in open source licenses, that the
cl-http license has a number of features to recommend it, and that, in fact,
the more open the license is, the more uncertainty _the licensee_ must suffer.

> 
> Concerning CL-HTTP: It is not my intent to vilify CL-HTTP. I think we
> both agree that there has been some confusion about their license
> (exemplified by the fact that somebody removed it from CLiki because
> he thought it was "not free"). If anything, this thread has hopefully
> provided some clarification, specifically through Rainer Joswig's
> comments.

that is good.

...
From: Rob Warnock
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and  Scheme]
Date: 
Message-ID: <OeWcnR5w158LhBWiXTWc-w@speakeasy.net>
james anderson  <··············@setf.de> wrote:
+---------------
| it would not hurt to read the cl-http license.[0] ...
| [0] ftp://ftp.ai.mit.edu/pub/users/jcma/cl-http/devo/cl-http-70-177c-devo.tar.gz
+---------------

That one doesn't seem to exist any more, but this one does [dated 2003-10-10]:

<ftp://ftp.ai.mit.edu/pub/users/jcma/cl-http/devo/cl-http-70-180-pre.tar.gz>


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Edi Weitz
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and Scheme]
Date: 
Message-ID: <87d6d33j59.fsf@bird.agharta.de>
On Sat, 11 Oct 2003 11:34:47 +0200, Paolo Amoroso <·······@mclink.it> wrote:

> From the slide "ITA UI design for air travel" in Rodney Daughtrey's
> ILC 2002 talk "ITA Software and Orbitz: Lisp in the Online Travel
> World" (ILC 2002 Proceedings, page 621):
> 
>   * Generation of search results on ITA's website search engine
>     (www.itasoftware.com) written in Common Lisp using CL-HTTP

Ah, good point. So it /is/ actually used in commercial products.

Edi.
From: Rainer Joswig
Subject: Re: CL-HTTP commercial deployment [was: Re: Python syntax in Lisp and Scheme]
Date: 
Message-ID: <joswig-A0AD8E.15444711102003@news.fu-berlin.de>
In article <··············@bird.agharta.de>, Edi Weitz <···@agharta.de> 
wrote:

> On Sat, 11 Oct 2003 11:34:47 +0200, Paolo Amoroso <·······@mclink.it> wrote:
> 
> > From the slide "ITA UI design for air travel" in Rodney Daughtrey's
> > ILC 2002 talk "ITA Software and Orbitz: Lisp in the Online Travel
> > World" (ILC 2002 Proceedings, page 621):
> > 
> >   * Generation of search results on ITA's website search engine
> >     (www.itasoftware.com) written in Common Lisp using CL-HTTP
> 
> Ah, good point. So it /is/ actually used in commercial products.
> 
> Edi.

Sure.
From: james anderson
Subject: unicode / osx / atsui
Date: 
Message-ID: <3F8670BF.B278C0FA@setf.de>
hello;

i'm trying to understand how best to approach unicode representations.
i am told the pep-0261 is the standard for python.
it was not clear what mechanism it entails for access to os-level text
management facilities on the order of osx's "apple type services for unicode
imaging"[0]. i looked through the mac extensions, but did not discern anything
relevant. can anyone point me to code in wide and narrow builds which uses
such os-level facilities. i was given a reference which appeared to concern
windows' file names, but that, as is the case with direct stream codecs, is
primarly a static situation.

i would also be interested to hear if there have been any data collected on
preponderance of wide builds, and on the consequences in those installations
for storage and algorithm efficiency.

...


[0] http://developer.apple.com/intl/atsui.html
From: Neil Hodgson
Subject: Re: unicode / osx / atsui
Date: 
Message-ID: <CYvhb.144866$bo1.93246@news-server.bigpond.net.au>
james anderson:

> i'm trying to understand how best to approach unicode representations.
> i am told the pep-0261 is the standard for python.

   PEP 261 is the standard for the 4 byte wide implementation. It was
implemented after 2 byte Unicode which was documented after-the-fact in PEP
100.

> it was not clear what mechanism it entails for access to os-level text
> management facilities on the order of osx's "apple type services for
unicode
> imaging"[0].

   ATSUI is a text rendering library. Core Python doesn't include
text-rendering, leaving this up to GUI toolkits. Python does ship with Tk,
which has Unicode text support.

> i looked through the mac extensions, but did not discern anything
> relevant. can anyone point me to code in wide and narrow builds which uses
> such os-level facilities. i was given a reference which appeared to
concern
> windows' file names, but that, as is the case with direct stream codecs,
is
> primarly a static situation.

   Static as opposed to what? A fixed API that is explicitly wrapped versus
a dynamically wrapped system call convention as is done on Windows by
PythonCOM or ctypes?

> i would also be interested to hear if there have been any data collected
on
> preponderance of wide builds, and on the consequences in those
installations
> for storage and algorithm efficiency.

   Red Hat Linux 9.0 ships with a 4 byte wide build of Python and that is
quite widely distributed. On Windows, I would expect 4 byte to be very rare
as 2 byte matches the system conventions and the binary downloads available
from python.org are 2 byte builds.

   Neil
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87n0cay7kt.fsf@bird.agharta.de>
On Thu, 09 Oct 2003 07:43:40 GMT, "Andrew Dalke" <······@mindspring.com> wrote:

> What's unicode support like in general for Lisp? [...] But do
> regexps work on unicode strings?

Unicode support isn't part of the CL standard but the standard is
flexible enough to make it easy for implementations to integrate
Unicode characters and strings seamlessly. You've mentioned a couple
of integrations which do that.

As for regex support - that's not a part of the standard either, but
there a couple of libraries available - see

  <http://www.cliki.net/Regular%20Expression>

If the library is written in Lisp (as opposed to being an FFI wrapper
around a C library) you can be fairly sure that it works with Unicode:

  [19]> (code-char 1000)
  #\COPTIC_CAPITAL_LETTER_HORI
  [20]> (defparameter *target* (make-string 2 :initial-element *))
  *TARGET*
  [21]> (cl-ppcre::scan "^(.){2}$" *target*)
  0 ;
  2 ;
  #(1) ;
  #(2)
  [22]> (cl-ppcre::scan `(:greedy-repetition 2 2 ,(code-char 1000)) *target*)
  0 ;
  2 ;
  #() ;
  #()

(This is CL-PPCRE with CLISP.)

Edi.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8765iy2wt3.fsf@thalassa.informatimago.com>
"Andrew Dalke" <······@mindspring.com> writes:
> Or is there a requirement that it be constrained to display
> systems which can only show ASCII?  (Just like a good
> Lisp editor almost requires the ability to reposition a
> cursor to blink on matching open parens.  Granted, that
> technology is a few decades old now while Unicode isn't,
> but why restrict a new language to the display systems
> of the past instead of the present?)

Because  the  present  is  composed  of  the past.   You  have  to  be
compatible,  otherwise  you could  not  debug  a  Deep Space  1  probe
160 million km away, (and this one was only two or three years old).




> Indeed.  It looks easier to understand to my untrained eye.
> I disagree that "+" shouldn't work on strings because that
> operation isn't commutative -- commutativity isn't a feature
> of + it's a feature of + on a certain type of set.

Mathematicians  indeed  overload operators  with  taking into  account
their   precise   properties.    But  mathematicians   are   naturally
intelligent.  Computers and  our programs are not.  So  it's easier if
you classify operators per properties; if you map the semantics to the
syntax, this allow you to apply transformations on your programs based
on the syntax without having to recover the meaning.
 

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <a6ihb.4361$dn6.3517@newsread4.news.pas.earthlink.net>
Pascal Bourguignon:
> Because  the  present  is  composed  of  the past.   You  have  to  be
> compatible,  otherwise  you could  not  debug  a  Deep Space  1  probe
> 160 million km away, (and this one was only two or three years old).

Huh?  I'm talking purely in the interface.  Use ASCII '[' and ']' in the
Lisp code and display it locally as something with more "directionality".
I'm not suggesting the unicode character be used in the Lisp code.
Take advantages of advances in font display to overcome limitations
in ASCII.

> Mathematicians  indeed  overload operators  with  taking into  account
> their   precise   properties.    But  mathematicians   are   naturally
> intelligent.  Computers and  our programs are not.  So  it's easier if
> you classify operators per properties; if you map the semantics to the
> syntax, this allow you to apply transformations on your programs based
> on the syntax without having to recover the meaning.

Ahhh, so make the language easier for computers to understand and
harder for intelligent users to use?  ;)

                    Andrew
                    ·····@dalkescientific.com
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3k77e5f91.fsf@rigel.goldenthreadtech.com>
"Andrew Dalke" <······@mindspring.com> writes:


> Ahhh, so make the language easier for computers to understand and
> harder for intelligent users to use?  ;)

Spoken like a true Python supporter...

/Jon
From: Brian Downing
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8jkhb.714553$YN5.609794@sccrnsc01>
In article <···················@newsread4.news.pas.earthlink.net>,
Andrew Dalke <······@mindspring.com> wrote:
> Huh?  I'm talking purely in the interface.  Use ASCII '[' and ']' in the
> Lisp code and display it locally as something with more "directionality".
> I'm not suggesting the unicode character be used in the Lisp code.
> Take advantages of advances in font display to overcome limitations
> in ASCII.

How is this amount of complexity possibly better then just making the 
[ ] keys output ( ) in the editor - something that works TODAY?

-bcd
--
*** Brian Downing <bdowning at lavos dot net> 
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm38rr$uik$1@f1node01.rhrz.uni-bonn.de>
Andrew Dalke wrote:
> Pascal Costanza:
> 
>>He provides more information at http://www.paulgraham.com/icad.html
> 

> I have run across his pages before, and have a hard time
> symphathizing with his view of things.  For example, the start of
> the icad essay mentions that Lisp is already "kind of unusual"
> compared to C because it includes a full interpreter.  But
> effectively all Python programs shipped include a full interpreter
> as well, and many give access to that interpreter, so I don't
> see what's unusual about it.  Ditto for Tcl apps.  Even some of
> my command-line perl apps included a way to pass in perl
> code on the command line, as for a search filter.

I guess this reflects his experiences when he has learned Lisp in the 
beginning of the 80's (AFAIK).

Yes, scripting languages have caught up in this regard. (However, note 
that Common Lisp also includes a full compiler at runtime.)

> The phrase "they had hard-headed engineering reasons for
> making the syntax look so strange." reminds me of the statement
> "better first rate salespeople and second rate engineers than
> second rate salespeople and first rate engineers" (and better
> first rate both).  That's saying *nothing* about the languages;
> it's saying that his viewpoint seems to exclude the idea that
> there are hard-headed non-engineering reasons for doing things."

No, that's not a logical conclusion.

> Consider one of those "hard-headed engineering reasons", at
> http://www.paulgraham.com/popular.html
> 
>    It has sometimes been said that Lisp should use first and
>    rest instead of car and cdr, because it would make programs
>    easier to read. Maybe for the first couple hours. But a hacker
>    can learn quickly enough that car means the first element
>    of a list and cdr means the rest. Using first and rest means
>    50% more typing. And they are also different lengths, meaning
>    that the arguments won't line up when they're called,
> 
> That to me is a solid case of post hoc ergo proper.  The
> words "1st" and "rst" are equally as short and easier to
> memorize.  And if terseness were very important, then
> what about using "." for car and ">" for cdr?  No, the reason
> is that that's the way it started and it will stay that way
> because of network effects -- is that a solid engineering
> reason?  Well, it depends, but my guess is that he wouldn't
> weight strongly the impact of social behaviours as part of
> good engineering.  I do.

As you have already noted in another note, car and cdr can be composed.
cadr is the second element, caddr is the third, cadddr is the fourth, 
and so on. cddr is the rest after the second element, cdddr is the rest 
after the third element, and so on. Other abbreviations I have used 
relatively often are caar, cdar, cadar.

These abbreviations seem strange to a Lisp outsider, but they are very 
convenient, and they are easy to read once you have gotten used to them. 
You don't actually "count" the elements in your head every time you see 
these operators, but they rather become patterns that you recognize in 
one go.

I don't know how this could be done with 1st, rst or hd, tl respectively.

Of course, Common Lisp also provides first, second, third, and so on, up 
to ninth, and rest. It also provides nth with (nth 0 l) = (car l), (nth 
1 l) = (cadr l), and so on and (nthcdr 0 l) = l, (nthcdr 1 l) = (cdr l), 
(nthcdr 2 l) = (cddr l) and so on.

Pick your choice. "There is not only one way to do it." (tm)

The learning curve is steeper, but in the long run you become much more 
productive.

Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3zngams83.fsf@javamonkey.com>
Pascal Costanza <········@web.de> writes:

> As you have already noted in another note, car and cdr can be
> composed. cadr is the second element, caddr is the third, cadddr is
> the fourth, and so on. cddr is the rest after the second element,
> cdddr is the rest after the third element, and so on. Other
> abbreviations I have used relatively often are caar, cdar, cadar.
> 
> These abbreviations seem strange to a Lisp outsider, but they are
> very convenient, and they are easy to read once you have gotten used
> to them. You don't actually "count" the elements in your head every
> time you see these operators, but they rather become patterns that
> you recognize in one go.

As a follow-on to Pascal's point: It might seem, if one just thinks
about function calls that the benefit of the composed C[AD]*R
operations is fairly small, and perhaps not worth the "cost" of being
more cryptic: i.e. Is the savings of a few characters in (cddr foo) vs
(rest (rest foo)) that big a benefit? But since Lisp supports higher
order functions, having single name for those composite functions
saves the clutter of having to create a lambda expression. For
instance, compare:

  (loop for (x y) on list by #'cddr do (foo x y))

vs 

  (loop for (x y) on list by #'(lambda (l) (rest (rest l))) do (foo xy))


I figured this out by deciding--as a matter of style--that I was just
going to use FIRST/REST all the time and then noticing that in
situations like this, CDDR is much more convenient. The point being,
it's hard to forsee all the subtle ways different features interact.
So it can be simultaneously true that CAR and CDR were originally
choosen as names for pretty much arbitrary historical reasons *and*
that they have persisted for a lot of "hard-headed" but subtle
engineering reasons. (Or maybe soft-headed, aesthetic reasons, if you
care to draw the distinction when talking about programming language
design which I don't.)

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <%hihb.4368$dn6.2921@newsread4.news.pas.earthlink.net>
Pascal Costanza:
> I guess this reflects his experiences when he has learned Lisp in the
> beginning of the 80's (AFAIK).

But the talk wasn't given in the early 80s.  It was given in the early 00s.
And it implies that Lisp is still strange that way.  OTOH, you aren't him
so it's not fair of me to ask you all to defend his statements.

> Yes, scripting languages have caught up in this regard. (However, note
> that Common Lisp also includes a full compiler at runtime.)

However, that's an implementation difference -- the only thing
users should see is that the code runs faster.  It doesn't otherwise
provide new functionality.

> > The phrase "they had hard-headed engineering reasons for
> > making the syntax look so strange." reminds me of the statement
> > "better first rate salespeople and second rate engineers than
> > second rate salespeople and first rate engineers" (and better
> > first rate both).  That's saying *nothing* about the languages;
> > it's saying that his viewpoint seems to exclude the idea that
> > there are hard-headed non-engineering reasons for doing things."
>
> No, that's not a logical conclusion.

I used those wishy-washy words "reminds me" and "seems".  ;)

> These abbreviations seem strange to a Lisp outsider, but they are very
> convenient, and they are easy to read once you have gotten used to them.
> You don't actually "count" the elements in your head every time you see
> these operators, but they rather become patterns that you recognize in
> one go.

I did know about cddr, etc. from Hofstadter's essays in Scientific
America some 15 years ago.

> I don't know how this could be done with 1st, rst or hd, tl respectively.

Okay, I gave alternatives of "." and ">" instead of "car" and "cdr"
"." for "here" and ">" for "the rest; over there".  These are equally
composable.

. == car
> == cdr
cadr  == >.
caddr == >>.
cddr == >>

> Pick your choice. "There is not only one way to do it." (tm)

Perl beat you to it -- "TMTOWTDO" (There's more than one way to
do it.).   ;)

Python's reply "There should be one-- and preferably only one --
obvious way to do it."

> The learning curve is steeper, but in the long run you become much more
> productive.

Which brings us back to the start of this thread.  :)

                    Andrew
                    ·····@dalkescientific.com
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3fzi25ent.fsf@rigel.goldenthreadtech.com>
"Andrew Dalke" <······@mindspring.com> writes:

> > I don't know how this could be done with 1st, rst or hd, tl respectively.
> 
> Okay, I gave alternatives of "." and ">" instead of "car" and "cdr"
> "." for "here" and ">" for "the rest; over there".  These are equally
> composable.
> 
> . == car
> > == cdr
> cadr  == >.
> caddr == >>.
> cddr == >>

These "look" worse than the version you're railing against and are
bombs waiting to go off since they have long standing prior meanins
not in any way associated with this type of operation.  OTOH, if you
really wanted them, you could define them.


> Python's reply "There should be one-- and preferably only one --
> obvious way to do it."

This then is probably the best reason to _not_ use Python for anything
other than the trivial.  It has long been known in problem solving
(not just computation) that multiple ways of attacking a problem, and
shifting among those ways, tends to yield the the better solutions.


> > The learning curve is steeper, but in the long run you become much more
> > productive.
> 
> Which brings us back to the start of this thread.  :)

If your problems are trivial, I suppose the presumed lower startup
costs of Python may mark it as a good solution medium.

/Jon
From: Bruce Lewis
Subject: startup time (was: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <nm9fzi15ii4.fsf_-_@magic-pi-ball.mit.edu>
·········@rcn.com (Jon S. Anthony) writes:

> If your problems are trivial, I suppose the presumed lower startup
> costs of Python may mark it as a good solution medium.

I find no significant difference in startup time between python and
mzscheme.
From: Jon S. Anthony
Subject: Re: startup time (was: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <m33ce15753.fsf@rigel.goldenthreadtech.com>
Bruce Lewis <·······@yahoo.com> writes:

> ·········@rcn.com (Jon S. Anthony) writes:
> 
> > If your problems are trivial, I suppose the presumed lower startup
> > costs of Python may mark it as a good solution medium.
> 
> I find no significant difference in startup time between python and
> mzscheme.

Category error.  The context (I would have thought) clearly indicated
that "startup costs" concerned the effort needed to use the language!

/Jon
From: Björn Lindberg
Subject: Re: startup time (was: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <hcsfzi1p48l.fsf@tjatte.nada.kth.se>
Bruce Lewis <·······@yahoo.com> writes:

> ·········@rcn.com (Jon S. Anthony) writes:
> 
> > If your problems are trivial, I suppose the presumed lower startup
> > costs of Python may mark it as a good solution medium.
> 
> I find no significant difference in startup time between python and
> mzscheme.

My preliminary results in this very important benchmark indicates that
python performs equally well to the two benchmarked Common Lisps:

200 ·····@nex:~> time for ((i=0; i<100; i++)); do lisp -noinit -eval '(quit)'; done

real    0m2,24s
user    0m1,36s
sys     0m0,83s
201 ·····@nex:~> time for ((i=0; i<100; i++)); do lisp -noinit -eval '(quit)'; done

real    0m2,24s
user    0m1,39s
sys     0m0,82s
202 ·····@nex:~> time for ((i=0; i<100; i++)); do clisp -q -x '(quit)'; done  

real    0m2,83s
user    0m1,74s
sys     0m1,03s
203 ·····@nex:~> time for ((i=0; i<100; i++)); do clisp -q -x '(quit)'; done

real    0m2,79s
user    0m1,67s
sys     0m1,09s
204 ·····@nex:~> time for ((i=0; i<100; i++)); do python -c exit; done        

real    0m2,41s
user    0m1,85s
sys     0m0,52s
205 ·····@nex:~> time for ((i=0; i<100; i++)); do python -c exit; done

real    0m2,41s
user    0m1,89s
sys     0m0,52s

</sarcasm>


Bj�rn
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <gGWhb.200390$hE5.6777507@news1.tin.it>
Jon S. Anthony wrote:
   ...
> bombs waiting to go off since they have long standing prior meanins
> not in any way associated with this type of operation.  OTOH, if you
> really wanted them, you could define them.

Is it a good thing that you can define "bombs waiting to go off"?


>> Python's reply "There should be one-- and preferably only one --
>> obvious way to do it."
> 
> This then is probably the best reason to _not_ use Python for anything
> other than the trivial.  It has long been known in problem solving
> (not just computation) that multiple ways of attacking a problem, and
> shifting among those ways, tends to yield the the better solutions.

One, and preferably only one, of those ways should be the obvious one,
i.e., the best solution.  There will always be others -- hopefully they'll 
be clearly enough inferior to the best one, that you won't have to waste
too much time considering and rejecting them.  But the obvious one
"may not be obvious at first unless you're Dutch".

The worst case for productivity is probably when two _perfectly
equivalent_ ways exist.  Buridan's ass notoriously starved to death in
just such a worst-case situation; groups of programmers may not go
quite as far, but are sure to waste lots of time & energy deciding.


Alex
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm9g9m$28n$1@newsreader2.netcologne.de>
Alex Martelli wrote:
> Jon S. Anthony wrote:
>    ...
> 
>>bombs waiting to go off since they have long standing prior meanins
>>not in any way associated with this type of operation.  OTOH, if you
>>really wanted them, you could define them.
> 
> 
> Is it a good thing that you can define "bombs waiting to go off"?

Yes.

>>>Python's reply "There should be one-- and preferably only one --
>>>obvious way to do it."
>>
>>This then is probably the best reason to _not_ use Python for anything
>>other than the trivial.  It has long been known in problem solving
>>(not just computation) that multiple ways of attacking a problem, and
>>shifting among those ways, tends to yield the the better solutions.
> 
> 
> One, and preferably only one, of those ways should be the obvious one,
> i.e., the best solution.  There will always be others -- hopefully they'll 
> be clearly enough inferior to the best one, that you won't have to waste
> too much time considering and rejecting them.  But the obvious one
> "may not be obvious at first unless you're Dutch".

Python probably really offers a good selection of features suited for 
particular problems. But it is very unlikely that it provides the right 
set of features for all conceivable problems. To put it in a provocative 
way, Python is a domain-specific language for vaguely defined domains - 
those that GvR (subconsciously?) had in mind when he designed the language.

I am pretty sure that Python is an excellent language for a lot of tasks 
- otherwise it wouldn't be used by that many people even though it 
didn't have a massive budget as Microsoft and Sun can provide for their 
pet languages.

But on the other hand, it is also clear that for unknown domains yet to 
be explored you cannot know the best set of features in advance _by 
definition_.

Here is a conjecture - I am not sure myself whether it is true, but 
anyway: The choice for a particular language is _always_ driven by a 
wish for safety. What the various languages provide are different 
perspectives on safety.

Pythonistas are probably driven by the assumption that the language 
designers have found the best language feature for any task that might 
arise. And even if they are not optimal in some cases, they at least 
help to better understand the code of each other. This makes them feel 
safe. (And these assumptions might even be true for 90% of the tasks 
that arise in the domains in which Python is actually used.)

Lispniks are driven by the assumption that there is always the 
unexpected. No matter what happens, it's a safe bet that you can make 
Lisp behave the way you want it to behave, even in the unlikely event 
that something happens that no language designer has ever thought of 
before. And even if you cannot find a perfect solution in some cases, 
you will at least be able to find a good approximation for hard 
problems. This makes them feel safe. (And the large libraries provided 
with Common Lisp and some Scheme systems still cover 90% of the standard 
tasks.)

> The worst case for productivity is probably when two _perfectly
> equivalent_ ways exist.  Buridan's ass notoriously starved to death in
> just such a worst-case situation; groups of programmers may not go
> quite as far, but are sure to waste lots of time & energy deciding.

No, the worst case for productivity is when no way exists.

Yes, it is good thing that a language enables you to "define bombs 
waiting to go off", because this means that you can also define 
solutions for your unexpected problems.


Pascal
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <W5Zhb.7603$dn6.620@newsread4.news.pas.earthlink.net>
Pascal Costanza:
> To put it in a provocative
> way, Python is a domain-specific language for vaguely defined domains -
> those that GvR (subconsciously?) had in mind when he designed the
language.

But by the same vein, is not Lisp is a domain-specific language for
vaguely defined domains?  You say that's because Lisp can be used
for all domains.  My continued response is that it's not optimal for all
domains.  (Also, in another post I conjectured that a thoeretical
quantum computing 'Lisp' may have features for manipulating ensembles
of structures, in ways inappropriate to current Lisps.)

 > But on the other hand, it is also clear that for unknown domains yet to
> be explored you cannot know the best set of features in advance _by
> definition_.

I'll agree with that.  So why should Lisp, designed in the 1950s,
provide the best set of features (and I include more than semantic
abilities) for situations unenvisioned half a centry later (eg, the concept
of a "non-professional programmer")?

> Pythonistas are probably driven by the assumption that the language
> designers have found the best language feature for any task that might
> arise.

Not at all.  When I need language features best found in C (using
shared memory, or memory mapped I/O), I use C; perhaps called
from Python.

Were I to need logic programming, I would use at least consider
Prolog, with bindings like AmziPy or PyProlog, or cousins like
the Python/CLIPS interface.

(Most of the time though, I need libraries.  Eg, calling out to a
Fortran binary, using 'web services', CORBA, or even, when
I need browser applet features best found in Java,  I use Python
in its Jython incarnation.)

The phrase I'm trying to push is "multiple language paradigm;
not multiple paradigm language."

> Lispniks are driven by the assumption that there is always the
> unexpected. No matter what happens, it's a safe bet that you can make
> Lisp behave the way you want it to behave, even in the unlikely event
> that something happens that no language designer has ever thought of
> before.

Ahh, but that assumes that behaviour is the only important thing
in a language.  I disagree with that assumption, and that difference
in belief is one of the core reasons this thread has gone on so long.

> And even if you cannot find a perfect solution in some cases,
> you will at least be able to find a good approximation for hard
> problems.

So, umm, how does Lisp handle shared memory?  Can I, as
with C++, say that certain objects/data structures are to be
allocated from a block of shared memory rather than the standard
memory arena?  What's the way to do I/O through a
memory-mapped port as on an old DOS machine?

Python cannot do the first, excepted in limited cases using
extensions written in C/C++, which is also how to handle
the second case.

I'm not saying that Lisp doesn't handle support for allocation
from multiple arenas; my searches showed many examples
of using Lisp on shared memory parallel machines.  However,
given my understanding of the language, it isn't obvious how
that's done.  By comparison, C++ has syntax support for
letting an class define the allocator for an instance and its
standard templates also take an optional memory allocator.

(Background on when I used C++'s per-class allocators.  I
was writing software for the CAVE, an immersive virtual
reality system.  Each wall of the CAVE is driven by a
different CPU.  The main software driving the visualization
runs on yet another CPU, and uses high-speed shared
memory to update the model viewed by the display CPUs.
It was easy to support; I made a new subclass for the
model data structures, with an allocator which used the
shared memory arena.  I then made a new container (this
was pre STL) for storing those objects.  A few library
calls and it was working.)

 > This makes them feel safe. (And the large libraries provided
> with Common Lisp and some Scheme systems still cover 90% of the standard
> tasks.)

Except for my standard tasks in bioinformatics and chemical
informatics.  ;)

> > The worst case for productivity is probably when two _perfectly
> > equivalent_ ways exist.  Buridan's ass notoriously starved to death in
> > just such a worst-case situation; groups of programmers may not go
> > quite as far, but are sure to waste lots of time & energy deciding.
>
> No, the worst case for productivity is when no way exists.

When there are two perfectly equivalent ways to do something,
people may be stuck in "analysis lock" trying to figure out which
one to take.  When there's no way to do something the answer is
to make a way -- which may be to use Lisp.

Here's a page on Buridan's ass
http://www.postmodernvillage.com/eastwest/issue5/ftf05.html
] The theory often referred to as "Buridan's ass" states that, when
] given the option of two equally wonderful piles of hay, the ass
] will starve to death because it cannot choose. This concept was
] first discussed in writing by Aristotle, but has been in existence
] long before it was documented in writing

Stretching the analogy, if there was no solution (no hay), the ass
would keep on looking for food.

> Yes, it is good thing that a language enables you to "define bombs
> waiting to go off", because this means that you can also define
> solutions for your unexpected problems.

Ahh, more analogies.  Most people don't work in munitions
factories.  While some are able to make their own bombs,
most are happy to relegate the task to professionals, and
depend on still others (the military) to deploy those bombs.

                    Andrew
                    ·····@dalkescientific.com
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <PpZhb.71286$lZ6.11212371@twister.nyc.rr.com>
Andrew Dalke wrote:
> I'll agree with that.  So why should Lisp, designed in the 1950s,
> provide the best set of features (and I include more than semantic
> abilities) for situations unenvisioned half a centry later (eg, the concept
> of a "non-professional programmer")?

Macros. :)

In On Lisp (the reason I am breaking my vow of silence on this thread) 
Paul Graham shows how things like objects and prolog can be built out of 
standard ANSI Lisp (without using the built-in CLOS, of course):

    http://www.paulgraham.com/onlisp.html

And the synatx looks nice (important feature, right?) because of macros.

I am kicking myself for not simply referring everyone to Mr. Graham when 
this thread (and its prior incarnation on clp alone) started. Graham 
says it all, and says it better than I ever could.

That link includes a download of the whole book. Chapter 8 is called 
"When to Use Macros".

Chapter 1 answers your quoted question above; it is called "The 
Extensible Language". It includes discussion of why that is a Good 
Thing, and not to be dreaded because of the concerns Alex (and other 
Pythonistas have) over extending a language.


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Dave Benjamin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbogqqu.kr4.ramen@lackingtalent.com>
In article <··················@newsread4.news.pas.earthlink.net>, Andrew Dalke wrote:
>
> Here's a page on Buridan's ass
> http://www.postmodernvillage.com/eastwest/issue5/ftf05.html
> ] The theory often referred to as "Buridan's ass" states that, when
> ] given the option of two equally wonderful piles of hay, the ass
> ] will starve to death because it cannot choose. This concept was
> ] first discussed in writing by Aristotle, but has been in existence
> ] long before it was documented in writing
> 
> Stretching the analogy, if there was no solution (no hay), the ass
> would keep on looking for food.

Maybe that's why, when confronted with two perfectly good languages, instead
of just picking one of them and writing some code, we instead must make
asses of ourself on long crossposted threads about the relative merits and
demerits of each other's hay.

hay-is-for-horses-ly y'rs - dave
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bma0a5$odt$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> Pascal Costanza:
> 
>>To put it in a provocative
>>way, Python is a domain-specific language for vaguely defined domains -
>>those that GvR (subconsciously?) had in mind when he designed the
> language.
> 
> But by the same vein, is not Lisp is a domain-specific language for
> vaguely defined domains?  You say that's because Lisp can be used
> for all domains.  My continued response is that it's not optimal for all
> domains.

Yes, we disagree in this regard.

> (Also, in another post I conjectured that a thoeretical
> quantum computing 'Lisp' may have features for manipulating ensembles
> of structures, in ways inappropriate to current Lisps.)

I am no expert in quantum computing, so I can't comment on that. 
However, you have mentioned that someone has implemented an quantum 
extension for Perl - and if that's possible then you can safely bet that 
it's also possible in pure Lisp.

>  > But on the other hand, it is also clear that for unknown domains yet to
> 
>>be explored you cannot know the best set of features in advance _by
>>definition_.
> 
> 
> I'll agree with that.  So why should Lisp, designed in the 1950s,
> provide the best set of features (and I include more than semantic
> abilities) for situations unenvisioned half a centry later (eg, the concept
> of a "non-professional programmer")?

I believe that non-professional are more capable than most of us seems 
to think. Furthermore, it has been suggested more than once that a valid 
working model is that a good Lisp programmer can provide a 
domain-specific language for the non-professional programmer. It's very 
likely that a DSL matches better the needs of the user than some 
restricted general-purpose language.

>>Pythonistas are probably driven by the assumption that the language
>>designers have found the best language feature for any task that might
>>arise.
> 
> 
> Not at all.  When I need language features best found in C (using
> shared memory, or memory mapped I/O), I use C; perhaps called
> from Python.
> 
> Were I to need logic programming, I would use at least consider
> Prolog, with bindings like AmziPy or PyProlog, or cousins like
> the Python/CLIPS interface.
> 
> (Most of the time though, I need libraries.  Eg, calling out to a
> Fortran binary, using 'web services', CORBA, or even, when
> I need browser applet features best found in Java,  I use Python
> in its Jython incarnation.)
> 
> The phrase I'm trying to push is "multiple language paradigm;
> not multiple paradigm language."

Ah, but then you need to constantly change the syntax and need to 
remember the idiosyncrasies of several languages.

I am not so sure whether this is a good idea. Personally, I prefer not 
to think about syntax anymore. It's boring. But that's maybe just me.

>>Lispniks are driven by the assumption that there is always the
>>unexpected. No matter what happens, it's a safe bet that you can make
>>Lisp behave the way you want it to behave, even in the unlikely event
>>that something happens that no language designer has ever thought of
>>before.
> 
> 
> Ahh, but that assumes that behaviour is the only important thing
> in a language.

No.

> I disagree with that assumption, and that difference
> in belief is one of the core reasons this thread has gone on so long.
> 
> 
>>And even if you cannot find a perfect solution in some cases,
>>you will at least be able to find a good approximation for hard
>>problems.
> 
> 
> So, umm, how does Lisp handle shared memory?  Can I, as
> with C++, say that certain objects/data structures are to be
> allocated from a block of shared memory rather than the standard
> memory arena?  What's the way to do I/O through a
> memory-mapped port as on an old DOS machine?
> 
> Python cannot do the first, excepted in limited cases using
> extensions written in C/C++, which is also how to handle
> the second case.

I don't know. I have to ask my vendor. ;-)

> I'm not saying that Lisp doesn't handle support for allocation
> from multiple arenas; my searches showed many examples
> of using Lisp on shared memory parallel machines.  However,
> given my understanding of the language, it isn't obvious how
> that's done.  By comparison, C++ has syntax support for
> letting an class define the allocator for an instance and its
> standard templates also take an optional memory allocator.

If it's only a syntactical issue, then it's a safe bet that you can add 
that to the language. Syntax is boring.

> (Background on when I used C++'s per-class allocators.  I
> was writing software for the CAVE, an immersive virtual
> reality system.  Each wall of the CAVE is driven by a
> different CPU.  The main software driving the visualization
> runs on yet another CPU, and uses high-speed shared
> memory to update the model viewed by the display CPUs.
> It was easy to support; I made a new subclass for the
> model data structures, with an allocator which used the
> shared memory arena.  I then made a new container (this
> was pre STL) for storing those objects.  A few library
> calls and it was working.)

Sounds like a possible application for the CLOS MOP.

>  > This makes them feel safe. (And the large libraries provided
> 
>>with Common Lisp and some Scheme systems still cover 90% of the standard
>>tasks.)
> 
> 
> Except for my standard tasks in bioinformatics and chemical
> informatics.  ;)

Again, I don't know. You don't really expect me to know everything about 
any conceivable field of computer science, do you? ;)

>>Yes, it is good thing that a language enables you to "define bombs
>>waiting to go off", because this means that you can also define
>>solutions for your unexpected problems.
> 
> 
> Ahh, more analogies.  Most people don't work in munitions
> factories.  While some are able to make their own bombs,
> most are happy to relegate the task to professionals, and
> depend on still others (the military) to deploy those bombs.

You have forgotten the stupid politicians who go to war because it makes 
them look better on television. No, I don't feel comfortable to depend 
on them.

Seriously, I haven't invented this analogy, I have just tried to answer 
a rhetorical question by Alex in a non-obvious way. Basically, I think 
the analogy is flawed.


Pascal
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <llrr1itw.fsf@comcast.net>
Pascal Costanza <········@web.de> writes:

> Andrew Dalke wrote:
>
>> Pascal Costanza:
>>
>>>To put it in a provocative
>>>way, Python is a domain-specific language for vaguely defined domains -
>>>those that GvR (subconsciously?) had in mind when he designed the
>> language.
>> But by the same vein, is not Lisp is a domain-specific language for
>> vaguely defined domains?  You say that's because Lisp can be used
>> for all domains.  My continued response is that it's not optimal for all
>> domains.
>
> Yes, we disagree in this regard.
>
>> (Also, in another post I conjectured that a thoeretical
>> quantum computing 'Lisp' may have features for manipulating ensembles
>> of structures, in ways inappropriate to current Lisps.)
>
> I am no expert in quantum computing, so I can't comment on
> that. However, you have mentioned that someone has implemented an
> quantum extension for Perl

That doesn't sound too hard.  Perl is *already* fairly non-deterministic.

> Personally, I prefer not to think about syntax anymore.  It's
> boring.  But that's maybe just me.

Agreed.  It's a solved problem.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <rr0ib.7732$dn6.1011@newsread4.news.pas.earthlink.net>
Me:
> > My continued response is that [Lisp is] not optimal for all
> > domains.

Pascal Costanza:
> Yes, we disagree in this regard.

*Shrug*  The existence of awk/perl (great for 1-liners on the
unix command-line) or PHP (for simple web programming) or
Mathematica (for symbolic math) is strong enough evidence for
me to continue to disagree.

Pascal Costanza:
> However, you have mentioned that someone has implemented an quantum
> extension for Perl - and if that's possible then you can safely bet that
> it's also possible in pure Lisp.

The fact that all computing can be programmed in Turing Machine
Language doesn't mean TML is the optimal programming language.

The fact that there is perl code for emulating *some* quantum
programming means that Lisp can handle that subset.  It doesn't mean
that people have fully explored even in Lisp what it means to do all
of quantum computing.

> Furthermore, it has been suggested more than once that a valid
> working model is that a good Lisp programmer can provide a
> domain-specific language for the non-professional programmer. It's very
> likely that a DSL matches better the needs of the user than some
> restricted general-purpose language.

Another *shrug*  And a good C programmer can provide a
domain-specific language for the non-professional programmer.

Any good Python programmer could make an implementation
of a Lisp (slow, and not all of GC Lisp, but a Lisp) in Python, like

import lisp
def spam(distance):
    """(time_to_fall 9.8 distance)"""
spam = lisp.convert(spam)

def time_to_fall(g, distance):
  print "The spam takes", (2.0*distance/g)**(0.5), "seconds to fall"

print spam(10)

> Ah, but then you need to constantly change the syntax and need to
> remember the idiosyncrasies of several languages.

Yup.  Just like remembering what macros do for different domains.
I firmly believe people can in general easily handle much more
complicated syntax than Lisp has.  There's plenty of room to
spare in people's heads for this subject.

> I am not so sure whether this is a good idea. Personally, I prefer not
> to think about syntax anymore. It's boring. But that's maybe just me.

wave equation vs. matrix approach
Newtownian mechanics or Lagrangian
measure theory or non-standard analysis
recursive algorithms vs. iterative ones
travelling salesman vs. maximum clique detection

Each is a pair of different but equivalent ways of viewing the same
problem.  Is the difference just syntax?

> > Ahh, but that assumes that behaviour is the only important thing
> > in a language.
>
> No.

Thank you for your elaboration.  You say the driving force is the
ability to handle unexpected events.  I assumed that means you need
new styles of behaviour.

> If it's only a syntactical issue, then it's a safe bet that you can add
> that to the language. Syntax is boring.

Umm... Sure.  C++ can be expressed as a parse tree, and that
parse tree converted to an s-exp, which can be claimed to be
a Lisp; perhaps with the right set of macros.

Still doesn't answer my question on how nicely Lisp handles
the 'unexpected' need of allocating objects from different
memory arenas.

> Sounds like a possible application for the CLOS MOP.

Or any other language's MOP.

> Seriously, I haven't invented this analogy, I have just tried to answer
> a rhetorical question by Alex in a non-obvious way. Basically, I think
> the analogy is flawed.

Then the right solution is to claim the analogy is wrong, not
go along with it as you did.  ;)

                    Andrew
                    ·····@dalkescientific.com
From: Daniel P. M. Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bma7ie$a0r$1@camelot.ccs.neu.edu>
Andrew Dalke wrote:
>> Furthermore, it has been suggested more than once that a valid
>> working model is that a good Lisp programmer can provide a
>> domain-specific language for the non-professional programmer. It's very
>> likely that a DSL matches better the needs of the user than some
>> restricted general-purpose language.
> 
> Another *shrug*  And a good C programmer can provide a
> domain-specific language for the non-professional programmer.
> 

The last thing we need in this world is more non-professional programmers 
writing C programs to make software even more unstable.  The ATM near where
I work crashes enough as it is.

You can restrict a DSL in lisp/scheme to the point of not allowing it to
call eval, for example.  Can you restrict a C programmer's ability to
dereference NULL?  Can you hide 'exec' from the Python newbie?

> Any good Python programmer could make an implementation
> of a Lisp (slow, and not all of GC Lisp, but a Lisp) in Python, like
> 
> import lisp
> def spam(distance):
>     """(time_to_fall 9.8 distance)"""
> spam = lisp.convert(spam)
> 
> def time_to_fall(g, distance):
>   print "The spam takes", (2.0*distance/g)**(0.5), "seconds to fall"
> 
> print spam(10)
>

Please let me know if you hear of anyone implementing lisp/scheme in
Python :)
 
>> If it's only a syntactical issue, then it's a safe bet that you can add
>> that to the language. Syntax is boring.
> 
> Umm... Sure.  C++ can be expressed as a parse tree, and that
> parse tree converted to an s-exp, which can be claimed to be
> a Lisp; perhaps with the right set of macros.
> 
> Still doesn't answer my question on how nicely Lisp handles
> the 'unexpected' need of allocating objects from different
> memory arenas.

Just like Python does: native modules.

- DS
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmaghv$gce$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> Me:
> 
>>>My continued response is that [Lisp is] not optimal for all
>>>domains.
> 
> 
> Pascal Costanza:
> 
>>Yes, we disagree in this regard.
> 
> 
> *Shrug*  The existence of awk/perl (great for 1-liners on the
> unix command-line) or PHP (for simple web programming) or
> Mathematica (for symbolic math) is strong enough evidence for
> me to continue to disagree.

Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."

> Pascal Costanza:
> 
>>However, you have mentioned that someone has implemented an quantum
>>extension for Perl - and if that's possible then you can safely bet that
>>it's also possible in pure Lisp.
> 
> 
> The fact that all computing can be programmed in Turing Machine
> Language doesn't mean TML is the optimal programming language.

Right.

> The fact that there is perl code for emulating *some* quantum
> programming means that Lisp can handle that subset.  It doesn't mean
> that people have fully explored even in Lisp what it means to do all
> of quantum computing.

...and you expect me to have fully explored it? If this topic is so 
interesting to you, why don't you just grab a Common Lisp environment 
and start working on it? ;)

I am pretty sure you can get very far.

>>Furthermore, it has been suggested more than once that a valid
>>working model is that a good Lisp programmer can provide a
>>domain-specific language for the non-professional programmer. It's very
>>likely that a DSL matches better the needs of the user than some
>>restricted general-purpose language.
> 
> Another *shrug*  And a good C programmer can provide a
> domain-specific language for the non-professional programmer.

Sure, but it's much more work.

> Any good Python programmer could make an implementation
> of a Lisp (slow, and not all of GC Lisp, but a Lisp) in Python, like
> 
> import lisp
> def spam(distance):
>     """(time_to_fall 9.8 distance)"""
> spam = lisp.convert(spam)
> 
> def time_to_fall(g, distance):
>   print "The spam takes", (2.0*distance/g)**(0.5), "seconds to fall"
> 
> print spam(10)

Sure, but inconvenient.

>>Ah, but then you need to constantly change the syntax and need to
>>remember the idiosyncrasies of several languages.
> 
> 
> Yup.  Just like remembering what macros do for different domains.

Sure, there is no way around that. But you can reduce the tediousness in 
the long run.

I believe it is an accepted fact that uniformity in GUI design is a good 
thing because users don't need to learn arbitrarily different ways of 
using different programs. You only need different ways of interaction 
when a program actually requires it for its specific domain.

That's pretty much the same when you program in Lisp. It takes some time 
to get used to s-expressions, but afterwards you forget about syntax and 
focus on the real problems.

> I firmly believe people can in general easily handle much more
> complicated syntax than Lisp has.  There's plenty of room to
> spare in people's heads for this subject.

Sure, but is it worth it?

>>I am not so sure whether this is a good idea. Personally, I prefer not
>>to think about syntax anymore. It's boring. But that's maybe just me.
> 
> 
> wave equation vs. matrix approach
> Newtownian mechanics or Lagrangian
> measure theory or non-standard analysis
> recursive algorithms vs. iterative ones
> travelling salesman vs. maximum clique detection
> 
> Each is a pair of different but equivalent ways of viewing the same
> problem.  Is the difference just syntax?

Probably not. This question is too general though for my taste.

>>>Ahh, but that assumes that behaviour is the only important thing
>>>in a language.
>>
>>No.
> 
> 
> Thank you for your elaboration.  You say the driving force is the
> ability to handle unexpected events.  I assumed that means you need
> new styles of behaviour.

Convenience is what matters. If you are able to conveniently express 
solutions for hard problems, then you win. In the long run, it doesn't 
matter much how things behave in the background, only at first.

Or do you really still care about how sorting algorithms work? No, you 
look for an API that has some useful sorting functions, and then you 
just use them.

Macros are just another tool to create new abstractions that allow you 
to conveniently express solutions for hard problems.

It seems to me that in Python, just as in most other languages, you 
always have to be aware that you are dealing with classes and objects. 
Why should one care? Why does the language force me to see that when it 
really doesn't contribute to the solution?

That's why lambda expressions are sometimes also not quite right. When I 
want to execute some code in some context, why should I care about it 
being wrapped in a lambda expression to make it work? How does that 
contribute to the problem I am trying to tackle?

I want to think in terms of the problem I need to solve. Lisp is one of 
the very rare languages that doesn't force me to think in terms of its 
native language constructs.

>>If it's only a syntactical issue, then it's a safe bet that you can add
>>that to the language. Syntax is boring.
> 
> Umm... Sure.  C++ can be expressed as a parse tree, and that
> parse tree converted to an s-exp, which can be claimed to be
> a Lisp; perhaps with the right set of macros.

That's computational equivalence, and that's not interesting.

> Still doesn't answer my question on how nicely Lisp handles
> the 'unexpected' need of allocating objects from different
> memory arenas.

If it's a good Lisp library I would expect it to work like this:

(with-allocation-from :shared-memory
   ...)

;)

Any more questions?

>>Sounds like a possible application for the CLOS MOP.
> 
> 
> Or any other language's MOP.

Sure.

>>Seriously, I haven't invented this analogy, I have just tried to answer
>>a rhetorical question by Alex in a non-obvious way. Basically, I think
>>the analogy is flawed.
> 
> 
> Then the right solution is to claim the analogy is wrong, not
> go along with it as you did.  ;)

Thanks for your kind words. ;)


Pascal
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <OU4ib.8027$dn6.1845@newsread4.news.pas.earthlink.net>
Pascal Costanza:
> [quantum programming]

While an interesting topic, it's something I'm not going to worry about.
And if I did, it would be in Python ;)

I bring it up as a counter-example to the idea that all modes of
programming have been and can be explored in a current Lisp.
I conjectured one interesting possibility -- that of handling ensembles
of possible solutions to a given problem.

In retrospect I should have given a more obvious possibility.
As some point I hope to have computer systems I can program
by voice in English, as in "House?  Could you wake me up
at 7?"  That is definitely a type of programming, but Lisp is
a language designed for text, not speed.

Pascal Costanza:
> I believe it is an accepted fact that uniformity in GUI design is a good
> thing because users don't need to learn arbitrarily different ways of
> using different programs. You only need different ways of interaction
> when a program actually requires it for its specific domain.

My spreadsheet program looks different from my word processor
looks different from my chemical structure editor looks different from
my biosequence display program looks different from my image
editor looks different from my MP3 player looks different from my
email reader looks different from Return to Castle Wolfinstein ....

There are a few bits of commonality; they can all open files.  But
not much more.  Toss out the MP3 player and RtCW and there
is more in common.  Still, the phrase "practicality beats purity" is
seems appropriate here.

> > I firmly believe people can in general easily handle much more
> > complicated syntax than Lisp has.  There's plenty of room to
> > spare in people's heads for this subject.
>
> Sure, but is it worth it?

Do you have any doubt to my answer?  :)

> Convenience is what matters. If you are able to conveniently express
> solutions for hard problems, then you win. In the long run, it doesn't
> matter much how things behave in the background, only at first.

Personally, I would love to write equations on a screen like I
would on paper, with integral signs, radicals, powers, etc. and
not have to change my notation to meet the limitations of computer
input systems.

For Lisp is a language tuned to keyboard input and not the full
range of human expression.  (As with speech.)

(I know, there are people who can write equations in TeX as
fast as they can on paper.  But I'm talking about lazy ol' me
who wants the covenience.)

Or, will there ever be a computer/robot combination I can
teach to dance?  Will I do so in Lisp?

> It seems to me that in Python, just as in most other languages, you
> always have to be aware that you are dealing with classes and objects.
> Why should one care? Why does the language force me to see that when it
> really doesn't contribute to the solution?

Hmmm..  Is the number '1' an object?  Is a function an object?
What about a module?  A list?  A class?

>>> print sum(range(100))
4950
>>>

Where in that example are you aware that you are dealing with classes
and objects?

> >>If it's only a syntactical issue, then it's a safe bet that you can add
> >>that to the language. Syntax is boring.
> >
> > Umm... Sure.  C++ can be expressed as a parse tree, and that
> > parse tree converted to an s-exp, which can be claimed to be
> > a Lisp; perhaps with the right set of macros.
>
> That's computational equivalence, and that's not interesting.

Which is why I didn't see the point of original statement.  My
conjecture is that additional syntax can make some things easier.
That a problem can be solved without new syntax does not
contradict my conjecture.

> If it's a good Lisp library I would expect it to work like this:
>
> (with-allocation-from :shared-memory
>    ...)
>
> ;)
>
> Any more questions?

Yes.  Got a URL for documentation on a Lisp providing access
to shared memory?  My guess is that the Lisp runtime needs
to be told about the arenas and that the multiple instances of
Lisp sharing the arena must use some extra IPC to handle
the distributed gc.

It gets worse if program X forks copies Y and Z, with shared
memory XY between X and Y (but not Z) and XZ between
X and Z (but not Y).  X needs to be very careful on which
data is copied, and it isn't immediately obvious what happens
when some object from XZ is inserted into a list accessible
to Y via XY.

Consider also a "persistent memory" server running in C
(or hardware access to some sort of non-volatile memory.)
You can use standard IPC to get an initially zeroed memory
block and are free to use that memory without restrictions.
It's persistent after program exit so when the program restarts
it can reconnect to shared memory and get the data as it
was at exit.

This service is straight-forward to support in C/C++.  It
sounds like for Lisp you are dependent on the implementation,
in that if the implementation doesn't support access to its
memory allocator/gc subsystem then it's very hard to
write code for this hardware on your own.  It may be
possible to use an extension (written in C? ;) to read/write
to that persistent memory using some sort of serialization,
but that's the best you can do -- you don't have live objects
running from nonvolatile store -- which is worse than C++.


                    Andrew
                    ·····@dalkescientific.com
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <MSfib.205196$hE5.6903319@news1.tin.it>
Andrew Dalke wrote:

> Pascal Costanza:
>> [quantum programming]
> 
> While an interesting topic, it's something I'm not going to worry about.

Me neither, for now.

> And if I did, it would be in Python ;)

I suspect no existing language would be anywhere near adequate.
But if any current programming concept could stretch there, it might
be that of "unrealized until looked-into set of things", as in, Haskell's
"lazy" (nonstrict) lists.  Now lists are sequential and thus quantumly
inappropriate, but perhaps it's a start.

> I bring it up as a counter-example to the idea that all modes of
> programming have been and can be explored in a current Lisp.
> I conjectured one interesting possibility -- that of handling ensembles
> of possible solutions to a given problem.

I suspect we may have to map the 'ensembles' down to sets of
items, just as we generally map concurrency down to sets of
sequential actions, in order to be able to reason about them (though
I have no proof of that conjecture).  IF you have to map more
complicated intrinsics down to sequential, deterministic, univocal
"things", I'm sure you could do worse than Lisp.  As to whether
that makes more sense than dreaming up completely different
languages having (e.g.) nondeterminism or multivocity as more
intrinsic concepts, I pass: it depends mostly on what human beings
will find they need to use in order to reason most effectively in
this new realm -- and quite likely different humans will find they
have different needs in this matter.


> In retrospect I should have given a more obvious possibility.
> As some point I hope to have computer systems I can program
> by voice in English, as in "House?  Could you wake me up
> at 7?"  That is definitely a type of programming, but Lisp is

Yeah, well, I fear the answer will be yes (it could), but it won't
do so since you haven't _asked_ it to wake you up, only if it
could.  ME, I definitely don't want to use natural language with
all of its ambiguity for anything exept communicating with
other human beings, thankyouverymuch.

> a language designed for text, not speed.

*blink* what does THAT doubtful assertion have to do with anything
else we were discussing just now...?  I think lisp was designed for
lists (as opposed to, say, snobol, which WAS "designed for text") and
that they're a general enough data structure (and supplemented in
today's lisps with other good data structures) that they'll be quite good
for all kinds of 'normal' (deterministic &c) programming.  As for speed,
I'm sure it's easier to get it out of lisp than out of python right now.
So what's your point, and its relation to the above...?


> Pascal Costanza:
>> I believe it is an accepted fact that uniformity in GUI design is a good
>> thing because users don't need to learn arbitrarily different ways of
>> using different programs. You only need different ways of interaction
>> when a program actually requires it for its specific domain.

Yes, I agree this IS generally accepted (with, of course, some dissenters,
but in a minority).

> My spreadsheet program looks different from my word processor

Sure, so do mine, but their menus are quite similar -- in as much as
it makes sense for them to have similar operations -- and ditto ditto
for their toolbars, keyboard shortcuts, etc etc.  I.e. the differences
only come "when needed for a specific domain" just as Pascal just
said.  So I don't know what you're intending with this answer.

> is more in common.  Still, the phrase "practicality beats purity" is
> seems appropriate here.

Uniformity is more practical than diversity: e.g. ctrl-c as the Copy 
operation everywhere means my fingers, even more than my brain, get
used to it.  If you assign ctrl-c to some totally different operation in
your gui app "because you think it's more practical" you're gonna
drive me crazy, assuming I have to use your app.  (That already
happens to me with the -- gnome based i think -- programs using
ctrl-z for minimize instead of undo -- I'm starting to have frayed
nerves about that even for GVIM, one of the programs I use most
often...:-).

>> > I firmly believe people can in general easily handle much more
>> > complicated syntax than Lisp has.  There's plenty of room to
>> > spare in people's heads for this subject.
>>
>> Sure, but is it worth it?
> 
> Do you have any doubt to my answer?  :)

Given the difficulty I'm having understanding your stance[s] in
this post, I do.  My own answer would be that syntax sugar is
in people's head anyway because of different contexts -- infix
arithmetic taught since primary school, indentation in outlines
and pseudocode, etc etc -- so, following that already-ingrained
set of conventions takes no "room to spare in people's heads" --
indeed, the contrary -- it saves them effort.  If people's head
started as "tabula rasa" it might be different, but they don't, so
that's a moot issue.

That much being said, I _do_ like prefix syntax.  In some cases
I need to sum a+b+c+d and repeating that silly plus rather than
writing (+ a b c d) grates.  Or I need to check a<b<c<d and
again I wish I could more summarily write (< a b c d).  When I
designed my own language for bridge-hands evaluation, BBL, I 
used prefix notation, though in the form operator ( operands )
[which I thought would have been easier for other bridge players 
to use], e.g.:

& (                      # weak NT opener requires AND of two things:
    s ( 1 g 4  3  3  3   # shape 4333 (any), or
        2 g 4  4  3  2   #       4432 (any), or
        3   3- 3- 3- 5   #       5332 with 5 clubs, or
        4   3- 3- 5  3-  #       5332 with 5 diamonds
      )
    < ( 12                    # as well as, 13-15 range for
        \+ SHDC c( 4 3 2 1 0) # normal Milton-Work pointcount
        16
      )
  )

Maybe readers are starting to understand why I don't WANT to
use a language I design myself;-).  Anyway, the language was
NOT enthusiastically taken up, until I wrote code generators with
a GUI accepting conditions in more "ordinary looking" notations
and building this, ahem, intrinsically "better" one;-) -- then, but only 
then, did other players start using this to customize hand generators
and the like.  (Yes, I did have macros, but puny enough that they
still required operator(operands) syntax -- they basically served only
to reduce duplication, or provide some little abstraction, not to
drastically change the language syntax at all).  Ah well -- maybe I
should just put the BBL (Turbo Pascal) implementation and (Italian-
language) reference manual online -- it still moves nostalgia in me!-)


>> Convenience is what matters. If you are able to conveniently express
>> solutions for hard problems, then you win. In the long run, it doesn't

My APL experience tells me this is false: conveniently expressing
solutions is HALF the problem -- you (and others!) have to be
able to read them back and maintain and alter them later too.

>> matter much how things behave in the background, only at first.
> 
> Personally, I would love to write equations on a screen like I
> would on paper, with integral signs, radicals, powers, etc. and
> not have to change my notation to meet the limitations of computer
> input systems.

So jot your equations on a tablet-screen and look for a good
enriched text recognition system.  What's programming gotta
do with it?

> For Lisp is a language tuned to keyboard input and not the full
> range of human expression.  (As with speech.)

Python even more so on the output side -- try getting a screen-reader to 
do a halfway decent job with it.  But what does this matter here?


> (I know, there are people who can write equations in TeX as
> fast as they can on paper.  But I'm talking about lazy ol' me
> who wants the covenience.)
> 
> Or, will there ever be a computer/robot combination I can
> teach to dance?  Will I do so in Lisp?

You may want to teach by showing and having the computer
infer more general rules from example.  Whether the inference
engine will be best built in lisp, prolog, ocaml, mozart, whatever,
I dunno.  I don't think it will be optimally done in Python, though.
"Horses for courses" is my philosophy in programming.


>> It seems to me that in Python, just as in most other languages, you
>> always have to be aware that you are dealing with classes and objects.

Given the "everything is an object" (classes included) and every object
belongs to a class, you could indeed say that -- in much the same sense
as you may be said to always be aware that you're breathing air in
everyday life.  Such awareness is typically very subconscious, of course.

>> Why should one care? Why does the language force me to see that when it
>> really doesn't contribute to the solution?

I'm not sure in what sense "python forces you to see" that, e.g.,
the number 2 is an object -- or how can that fail to "contribute to
the solution".  Care to exemplify?

> Hmmm..  Is the number '1' an object?  Is a function an object?
> What about a module?  A list?  A class?

Yes to all of the above, in Python.  I don't get your point.

>>>> print sum(range(100))
> 4950
> 
> Where in that example are you aware that you are dealing with classes
> and objects?

Me?  At every step -- I know 'sum' names a builtin object that is a
function (belonging to the class of builtin functions) taking one argument
which is a sequence, 'range' names another builtin object returning
a list object, etc.  I'm not directly dealing with any of their classes --
I know they belong to classes, like any object does, but I have no need
to think about them in this specific statement (in fact, I hardly ever do;
signature-based polymorphism is what I usually care about, not class
membership, far more often than not).

But I don't get your points -- neither Andrew's nor Pascal's.  How does
this differ from the awareness I might have in some macro-enhanced
lisp where I would type (print (sum (range 100))) or the like?

> conjecture is that additional syntax can make some things easier.
> That a problem can be solved without new syntax does not
> contradict my conjecture.

But even if we provisionally concede your conjecture we are still
left wondering: is the degree of easing so high that it overcomes
the inevitable increase in complication, needed for a language to
have N+1 syntax forms where previously it only had N?  I.e., it's
in general a difficult engineering tradeoff, like many in language
design -- which is why I'd rather delegate the decisions on these
tradeoffs to individuals, groups and processes with a proven track
record for making a lot of them with complexive results that I find
delightful, rather than disperse them to myself & many others
(creating lots of not-quite-congruent language dialects).


Alex
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3cdypdpu.fsf@comcast.net>
"Andrew Dalke" <······@mindspring.com> writes:

> Pascal Costanza:
>> [quantum programming]
>
> While an interesting topic, it's something I'm not going to worry about.
> And if I did, it would be in Python ;)
>
> I bring it up as a counter-example to the idea that all modes of
> programming have been and can be explored in a current Lisp.
> I conjectured one interesting possibility -- that of handling ensembles
> of possible solutions to a given problem.

Oops, try again.  

  http://hampshire.edu/lspector/qgame.html
  http://www.het.brown.edu/people/andre/qlambda/
  http://mitpress.mit.edu/sicp/full-text/sicp/book/node88.html


> In retrospect I should have given a more obvious possibility.
> As some point I hope to have computer systems I can program
> by voice in English, as in "House?  Could you wake me up
> at 7?"  That is definitely a type of programming, but Lisp is
> a language designed for text, not speed.

Oops, try again.

  http://www.hpl.hp.com/techreports/94/HPL-94-30.html
  http://dynamo.ecn.purdue.edu/~qobi/software.html
  http://citeseer.nj.nec.com/siskind93screamer.html

If you were to select a language that has been used for *more* different
kinds of programming paradigms, you'd be hard pressed to find something
better than lisp.

> Personally, I would love to write equations on a screen like I
> would on paper, with integral signs, radicals, powers, etc. and
> not have to change my notation to meet the limitations of computer
> input systems.
>
> For Lisp is a language tuned to keyboard input and not the full
> range of human expression.  (As with speech.)

Oops, it turns out that Lisp is used for handwriting recognition
in the banking industry.  I've heard rumors of Lisp being used
for voice recognition.

> Or, will there ever be a computer/robot combination I can
> teach to dance?  Will I do so in Lisp?

You want to teach a robot to dance?  I would prefer a cute woman,
myself.  Suit yourself, but you can use Lisp:

    http://citeseer.nj.nec.com/lee95programming.html


> Yes.  Got a URL for documentation on a Lisp providing access
> to shared memory?  My guess is that the Lisp runtime needs
> to be told about the arenas and that the multiple instances of
> Lisp sharing the arena must use some extra IPC to handle
> the distributed gc.

  http://www.double.co.nz/creatures/developer/sharedmemory.htm

> It gets worse if program X forks copies Y and Z, with shared
> memory XY between X and Y (but not Z) and XZ between
> X and Z (but not Y).  X needs to be very careful on which
> data is copied, and it isn't immediately obvious what happens
> when some object from XZ is inserted into a list accessible
> to Y via XY.

Actually, it is obvious with a little thought.  Objects sharable
between X and Y must reside in the XY address space.  Objects
sharable between X and Z must reside in the XZ address space.

Since neither Y nor Z share their entire address space with X, there
exist outgoing edges in the heap of Y that do not refer to objects
within Y.  Presumably the author of the system thought of that.
(If not, he's in trouble before Z even exists.)  An object common
with X and Z is as opaque to Y as any other object in X. 

> Consider also a "persistent memory" server running in C
> (or hardware access to some sort of non-volatile memory.)
> You can use standard IPC to get an initially zeroed memory
> block and are free to use that memory without restrictions.
> It's persistent after program exit so when the program restarts
> it can reconnect to shared memory and get the data as it
> was at exit.
>
> This service is straight-forward to support in C/C++.  It
> sounds like for Lisp you are dependent on the implementation,
> in that if the implementation doesn't support access to its
> memory allocator/gc subsystem then it's very hard to
> write code for this hardware on your own.  

Why do you think this?  The api would be straighforward.  a
shared persistent memory would at least have these calls:

  allocate, which takes an allocation amount and returns
   some name for the object allocated,

  retrieve, which takes some name for an object and recovers
   the object itself (for use upon restarting)

  dereference, which takes an object and a field and returns
   or assigns the field.

An obvious way to integrate this into lisp is to make a
displaced array.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmbsrj$ivn$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> In retrospect I should have given a more obvious possibility.
> As some point I hope to have computer systems I can program
> by voice in English, as in "House?  Could you wake me up
> at 7?"  That is definitely a type of programming, but Lisp is
> a language designed for text, not speed.

I don't understand that last sentence. Could you clarify this a bit? You 
don't want to say that there is an inherent dichotomy between text and 
speed, do you?!?

> Pascal Costanza:
> 
>>I believe it is an accepted fact that uniformity in GUI design is a good
>>thing because users don't need to learn arbitrarily different ways of
>>using different programs. You only need different ways of interaction
>>when a program actually requires it for its specific domain.
> 
> 
> My spreadsheet program looks different from my word processor
> looks different from my chemical structure editor looks different from
> my biosequence display program looks different from my image
> editor looks different from my MP3 player looks different from my
> email reader looks different from Return to Castle Wolfinstein ....
> 
> There are a few bits of commonality; they can all open files.  But
> not much more.

...but you probably know from the start where to find the menus, what 
the shortcuts are for opening and saving files, how to find the online 
help, and so forth.

Lisp also has this to a certain degree: It's always clear what 
constitutes the meaning of an s-expression, namely its car, no matter 
what language "paradigm" you are currently using.

> Toss out the MP3 player and RtCW and there
> is more in common.  Still, the phrase "practicality beats purity" is
> seems appropriate here.
> 
> 
>>>I firmly believe people can in general easily handle much more
>>>complicated syntax than Lisp has.  There's plenty of room to
>>>spare in people's heads for this subject.
>>
>>Sure, but is it worth it?
> 
> 
> Do you have any doubt to my answer?  :)

No, not really. :)

>>Convenience is what matters. If you are able to conveniently express
>>solutions for hard problems, then you win. In the long run, it doesn't
>>matter much how things behave in the background, only at first.
> 
> 
> Personally, I would love to write equations on a screen like I
> would on paper, with integral signs, radicals, powers, etc. and
> not have to change my notation to meet the limitations of computer
> input systems.

I know people who have even started to use s-expression for mathematical 
notation (on paper), because they find it more convenient.

> For Lisp is a language tuned to keyboard input and not the full
> range of human expression.  (As with speech.)

There is some research going on to extend Lisp even in this regard 
(incorporating more ways of expression).

> (I know, there are people who can write equations in TeX as
> fast as they can on paper.  But I'm talking about lazy ol' me
> who wants the covenience.)
> 
> Or, will there ever be a computer/robot combination I can
> teach to dance?  Will I do so in Lisp?

?!?

>>It seems to me that in Python, just as in most other languages, you
>>always have to be aware that you are dealing with classes and objects.
>>Why should one care? Why does the language force me to see that when it
>>really doesn't contribute to the solution?
> 
> 
> Hmmm..  Is the number '1' an object?  Is a function an object?
> What about a module?  A list?  A class?
> 
> 
>>>>print sum(range(100))
> 
> 4950
> 
> 
> Where in that example are you aware that you are dealing with classes
> and objects?

Well, maybe I am wrong. However, in a recent example, a unit test 
expressed in Python apparently needed to say something like 
"self.assertEqual ...". Who is this "self", and what does it have to do 
with testing? ;)

>>>>If it's only a syntactical issue, then it's a safe bet that you can add
>>>>that to the language. Syntax is boring.
>>>
>>>Umm... Sure.  C++ can be expressed as a parse tree, and that
>>>parse tree converted to an s-exp, which can be claimed to be
>>>a Lisp; perhaps with the right set of macros.
>>
>>That's computational equivalence, and that's not interesting.
> 
> 
> Which is why I didn't see the point of original statement.  My
> conjecture is that additional syntax can make some things easier.
> That a problem can be solved without new syntax does not
> contradict my conjecture.

If additional syntax makes specific things easier, then in god's name 
just add it! The loop macro in Common Lisp is an example of how you can 
add syntax to make certain things easier. This is not rocket science.

The point here is that for most languages, if you want to add some 
syntax, you have to change the definition of the language, extend the 
grammar, write a parser, extended a compiler and/or interpreter, maybe 
even the internal bytecode representation, have wars with other users of 
the language whether it's a good idea to change the language that way, 
and so forth. In Lisp, you just write a bunch of macros and you're done. 
No problems with syntax except if you want them, most of the time no 
problems with changes to the language (far less than in other 
languages), no messing around with grammars and related tools, no need 
to know about compiler/interpreter internals and internal 
representation, no wars with other language users, and so forth.

Syntax is boring. ;)

>>If it's a good Lisp library I would expect it to work like this:
>>
>>(with-allocation-from :shared-memory
>>   ...)
>>
>>;)
>>
>>Any more questions?
> 
> 
> Yes.  Got a URL for documentation on a Lisp providing access
> to shared memory?

OK, I am sorry that I have lost focus here. You have given this example 
as one that shows what probably cannot not be done in Lisp out of the 
box. However, most Lisp implementations provide a way to access native 
code and in that way deal with specific features of the operating 
system. And there is a de-facto standard for so-called foreign function 
calls called UFFI that you can use if you are interested in a 
considerable degree of portability.

I don't know a lot about the specifics of shared memory, so I can't 
comment on your specific questions.

> This service is straight-forward to support in C/C++.  It
> sounds like for Lisp you are dependent on the implementation,
> in that if the implementation doesn't support access to its
> memory allocator/gc subsystem then it's very hard to
> write code for this hardware on your own.  It may be
> possible to use an extension (written in C? ;) to read/write
> to that persistent memory using some sort of serialization,
> but that's the best you can do -- you don't have live objects
> running from nonvolatile store -- which is worse than C++.

This should be possible as a combination of a FFI/UFFI and the CLOS MOP. 
AFAIK, you can define the memory layout and the allocation of memory for 
specific metaclasses. However, I really don't know the details.

The paper at 
http://www-db.stanford.edu/~paepcke/shared-documents/mopintro.ps might 
be interesting. For UFFI, see http://uffi.b9.com/

As Paul Graham put it, yes, there is some advantage when you use the 
language the operating system is developed in, or it ++.

Pascal
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1Fiib.206002$hE5.6929845@news1.tin.it>
Pascal Costanza wrote:
   ...
>> Where in that example are you aware that you are dealing with classes
>> and objects?
> 
> Well, maybe I am wrong. However, in a recent example, a unit test
> expressed in Python apparently needed to say something like
> "self.assertEqual ...". Who is this "self", and what does it have to do
> with testing? ;)

Here self is 'the current test case' (instance of a class specializing
TestCase), and what it has to do with the organization of unit-testing
as depicted in Kent Beck's framework (originally for Smalltalk, adapted
into a lot of different languages as it, and test-driven design, became
deservedly popular) is "just about everything".  I think you might like
reading Kent's book on TDD -- and to entice you, you'll even find him
criticizing the fact that 'self' is explicit in Python (it's kept implicit 
in Smalltalk).  If you don't like O-O architecture, you doubtlessly won't
like Ken's framework -- he IS a Smalltalk-thinking OO-centered guy.


Alex
From: Coby Beck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmaibn$17uv$1@otis.netspace.net.au>
"Andrew Dalke" <······@mindspring.com> wrote in message
························@newsread4.news.pas.earthlink.net...
> > Furthermore, it has been suggested more than once that a valid
> > working model is that a good Lisp programmer can provide a
> > domain-specific language for the non-professional programmer. It's very
> > likely that a DSL matches better the needs of the user than some
> > restricted general-purpose language.
>
> Another *shrug*  And a good C programmer can provide a
> domain-specific language for the non-professional programmer.

Now you're obviously just trying to be difficult!  Reminds me of a thread a
while back where someone argued that C could so dynamically compile code and
posted an example that wrote a hello-world in a string, wrote it to a file,
called gcc on it and then system-called the .so file!

Or is there something else you mean besides design the language, implement a
parser, write a compiler?  Yes you can do that in C.

> Any good Python programmer could make an implementation
> of a Lisp (slow, and not all of GC Lisp, but a Lisp) in Python, like
>
> import lisp
> def spam(distance):
>     """(time_to_fall 9.8 distance)"""
> spam = lisp.convert(spam)
>
> def time_to_fall(g, distance):
>   print "The spam takes", (2.0*distance/g)**(0.5), "seconds to fall"
>
> print spam(10)

I don't get your point at all.  At least not how it possibly applies to a
discussion of using macros to create domain specific languages.

> > Ah, but then you need to constantly change the syntax and need to
> > remember the idiosyncrasies of several languages.
>
> Yup.  Just like remembering what macros do for different domains.

This is just the same memorizing that applies to application specific
functions, classes etc.  Not at all like memorizing @ % $ ; { } & etc.
Really, this argument is based on pure FUD.  It is not the norm to use
macros to do anything at all obfuscating.  One of the most controversial
macros has got to be loop, and it is ridiculed for something close to what
you seem to be arguing: it creates a very different and unlisp-like
sublanguage.

But even that, it is not:
(loop ^x %% foo==bar -> baz)

it is:
(loop for x from foo upto bar finally return baz)

Not hard to memorize what FROM and UPTO mean.

> I firmly believe people can in general easily handle much more
> complicated syntax than Lisp has.  There's plenty of room to
> spare in people's heads for this subject.

My head prefers to be full of more important things, that's all.

>>>Lispniks are driven by the assumption that there is always the
>>>unexpected. No matter what happens, it's a safe bet that you can make
>>>Lisp behave the way you want it to behave, even in the unlikely event
>>>that something happens that no language designer has ever thought of
>>>before.

>>> Ahh, but that assumes that behaviour is the only important thing
>>> in a language.

>> No.
>
> Thank you for your elaboration.  You say the driving force is the
> ability to handle unexpected events.  I assumed that means you need
> new styles of behaviour.

Just have another look.  He did not even say behaviour is the most
important, let alone the only important thing.

But in the global trade of language design (because remember, everything is
a trade-off) behaviour *is* more important than syntax *if* your goals are
primarily technical rather than social.

Nothing wrong with social goals, but you should not be naive when it comes
to considering what you have traded in for personal notions of ease of
learning.

> Still doesn't answer my question on how nicely Lisp handles
> the 'unexpected' need of allocating objects from different
> memory arenas.

I don't think this is a reasonable discussion point.  You are presumably
trying to show us an example of a problem lisp is not flexible enough to
handle, but you have not presented a problem to solve, you have presented a
solution to implement.  These are entirely different things.

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <M_4ib.8042$dn6.5275@newsread4.news.pas.earthlink.net>
Coby Beck:
> Now you're obviously just trying to be difficult!

Hmm, I think you are correct.  This discussion has worn me out
and I'm reacting now more out of crabbishness than thoughtfulness.

I hereby withdraw from this thread.  Or at least from cross-posting
outside of c.l.py ;)

                    Andrew
                    ·····@dalkescientific.com
From: Paolo Amoroso
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <878ynq9ulh.fsf@plato.moon.paoloamoroso.it>
Andrew Dalke writes:

> Still doesn't answer my question on how nicely Lisp handles
> the 'unexpected' need of allocating objects from different
> memory arenas.

If I understand things correctly, ITA Software's Orbitz system does
that. See the slides of Rodney Daughtrey's ILC 2002 talk "ITA Software
and Orbitz: Lisp in the Online Travel World" (International Lisp
Conference 2002 Proceedings, page 606).

A toy example is contained in Paul Graham's book "ANSI Common
Lisp". See section 13.5 "Example: Pools" on page 226.


Paolo
-- 
Paolo Amoroso <·······@mclink.it>
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pth31j6m.fsf@comcast.net>
Pascal Costanza <········@web.de> writes:

> Lispniks are driven by the assumption that there is always the
> unexpected.  No matter what happens, it's a safe bet that you can make
> Lisp behave the way you want it to behave, even in the unlikely event
> that something happens that no language designer has ever thought of
> before.  And even if you cannot find a perfect solution in some cases,
> you will at least be able to find a good approximation for hard
> problems.  This makes them feel safe.  (And the large libraries provided
> with Common Lisp and some Scheme systems still cover 90% of the
> standard tasks.)

The smartest programmers I know all prefer Lisp (in some form or 
another).  Given that they agree on very little else, that's saying
a lot.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <we0ib.7725$dn6.7509@newsread4.news.pas.earthlink.net>
·············@comcast.net:
> The smartest programmers I know all prefer Lisp (in some form or
> another).  Given that they agree on very little else, that's saying
> a lot.

Guess you don't know Knuth.

The smartest programmers I know prefer Python.  Except Guido.
He write a lot of C.

Bias error?  On whose side?

The smartest people I know aren't programmers.  What does
that say?

                    Andrew
                    ·····@dalkescientific.com
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1o2ib.71310$lZ6.11331244@twister.nyc.rr.com>
Andrew Dalke wrote:
> Guess you don't know Knuth.

Eight years to do TeX? How smart can he be? He should have used Lisp.

> The smartest people I know aren't programmers.  What does
> that say?

Aren't you the scientist who praised a study because statistics showed 
the studies statistics had a better than even chance of not being 
completely random? Credibility zero, dude. (if you now complain that it 
was fully a 75% chance of not being completely random, you lose.)


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <GP3ib.7877$dn6.569@newsread4.news.pas.earthlink.net>
Kenny Tilton:
> Aren't you the scientist who praised a study because statistics showed
> the studies statistics had a better than even chance of not being
> completely random? Credibility zero, dude. (if you now complain that it
> was fully a 75% chance of not being completely random, you lose.)

Wow!  You continue to be wrong in your summaries:

  - I am not a scientist and haven't claimed to be one in about 8 years

  - I didn't 'praise' the study, I pointed out that it exists and that it
offers
       some interesting points to consider.  At the very least it makes a
       testable prediction.

  - After someone asserted that that study had been "debunked" I asked for
       more information on the debunking, and pointed out the results of
       one experiment suggest that the language mapping was not complete
       bunkum. (Note that since 100% correlation is also a 'better than even
       chance' your statement above is meaningless.  What is your
threshold?)

       I would be *delighted* to see more studies on this topic,
       even ones which state that COBOL is easier to use than Python.

  - When I make statements of belief, I present where possible the
       sources and the analyses used to justify the belief and, in an
       attempt at rigour, the weaknesses of those arguments.  As such,
       I find it dubious that my credibility can be lower than someone
       making claims based solely on gut feelings and illogical thought.
       I take that back; a -1.0 credibility makes a wonderful oracle.

Given how imprecise you are in your use of language (where your
thoughtless turns of phrase gracelessly demean those who don't believe
that programming is the be-all and end-all of ambitions), your inability
to summarize matters correctly, and your insistance on ad hominum attacks
(dude!) over logical counter-argument and rational discourse, I'm surprised
you can make a living as a programmer or in any other field which
requires mental aptitude and the ability to communicate.

                    Andrew
                    ·····@dalkescientific.com
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <o75ib.72052$lZ6.11414620@twister.nyc.rr.com>
Andrew Dalke wrote:

> Given how imprecise you are in your use of language 

Ah, but there was a 75% chance that my remarks were not /completely/ 
random, so my unfairness towards you can't be complete bunkum.

:)


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Coby Beck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmaiei$17vg$1@otis.netspace.net.au>
"Andrew Dalke" <······@mindspring.com> wrote in message
························@newsread4.news.pas.earthlink.net...
> The smartest people I know aren't programmers.  What does
> that say?

Nothing surprising! ;)

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7k3apgg8.fsf@comcast.net>
"Andrew Dalke" <······@mindspring.com> writes:

> ·············@comcast.net:
>> The smartest programmers I know all prefer Lisp (in some form or
>> another).  Given that they agree on very little else, that's saying
>> a lot.
>
> Guess you don't know Knuth.

Never met him.

> The smartest people I know aren't programmers.  What does
> that say?

You hang out with dumb programmers?
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfswuba9xn3.fsf@black132.ex.ac.uk>
"Andrew Dalke" <······@mindspring.com> writes:
> The smartest people I know aren't programmers.  What does
> that say?

I think this is vital point. CL's inaccessibility is painted as a feature of
CL by many c.l.l denizens (keeps the unwashed masses out), but IMO the CL
community stunts and starves itself intellectually big time because CL is (I
strongly suspect) an *extremely* unattractive language for smart people
(unless they happen to be computer geeks).

Apart from the fact that this yields a positive feedback loop, I'd think that
even the smart computer geeks are likely to suffer from this incestuousness in
the midrun.

'as
From: Jock Cooper
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3wub96p09.fsf@jcooper02.sagepub.com>
Alexander Schmolck <··········@gmx.net> writes:

> "Andrew Dalke" <······@mindspring.com> writes:
> > The smartest people I know aren't programmers.  What does
> > that say?
> 
> I think this is vital point. CL's inaccessibility is painted as a feature of
> CL by many c.l.l denizens (keeps the unwashed masses out), 

I have never seen this in c.l.l. - most seem to feel the inaccessibility 
("ew the parens") are a necessary evil..

> but IMO the CL
> community stunts and starves itself intellectually big time because CL is (I
> strongly suspect) an *extremely* unattractive language for smart people
> (unless they happen to be computer geeks).

Well Hofstadter seems pretty smart to me, I don't think he's a computer geek, and
he's pretty fascinated by Lisp.  See G.E.B. and Metamagical Themas.
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <aeb7ff58.0310121142.6df26363@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<············@newsreader2.netcologne.de>...

> Lispniks are driven by the assumption that there is always the 
> unexpected. No matter what happens, it's a safe bet that you can make 
> Lisp behave the way you want it to behave, even in the unlikely event 
> that something happens that no language designer has ever thought of 
> before. And even if you cannot find a perfect solution in some cases, 
> you will at least be able to find a good approximation for hard 
> problems.

This I believe is the very crux of the matter. The problem domain to
which lisp has historically been applied, artificial intelligence,
more or less guaranteed that lisp hackers would run up against the
sorts of problems that no one had ever seen before. The language
therefore evolved into a "programmable programming language," to quote
John Foderaro (or whoever first said or wrote this now famous line).

Lisp gives the programmer who knows he will be working in a domain
that is not completely cut and dried, the assurance that his language
will not prevent him for doing something that has never been done
before. Python gives me the distinct impression that I might very well
run up against the limitations of the language when dealing with very
complex problems.

For 90% of tasks, even large projects, Python will certainly have
enough in its ever expanding bag of tricks to provide a clean,
maintainable solution. But that other 10% keeps lisp hackers from
using Python for exploratory programming - seeking solutions in
problem domains that have not been solved before.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmcdsd$fp8$1@newsreader2.netcologne.de>
Raffael Cavallaro wrote:

> For 90% of tasks, even large projects, Python will certainly have
> enough in its ever expanding bag of tricks to provide a clean,
> maintainable solution. But that other 10% keeps lisp hackers from
> using Python for exploratory programming - seeking solutions in
> problem domains that have not been solved before.

I would like to add to that by pointing out that it is even a good idea 
to use Lisp for problem domains that others have solved before but that 
_I_ (or "you") don't understand completely yet.

To me, programming languages are tools that help me to explore domains 
by writing models for them and interactively testing how they react to 
commands. In a certain sense, they are an extension of my brain that 
help me to manage the tedious and repetitive tasks, and let me focus on 
the essential problems.

Many programming languages require you to build a model upfront, on 
paper or at least in your head, and then write it down as source code. 
This is especially one of the downsides of OOP - you need to build a 
class hierarchy very early on without actually knowing if it is going to 
work in the long run.

What you actually do when you build a model of something is that you 
start _somewhere_, see how far you can get, take some other route, and 
so on, until you have a promising conceptualization. The cool thing 
about Lisp is that I can immediately sketch my thoughts as little 
functions and (potential) macros from the very beginning, and see how 
far I can get, exactly like I would when I would be restricted to work 
on paper. Except that in such an exploratory programming mode, I can get 
immediate feedback by trying to run the functions and expanding the 
macros and see what they do.

I know that OOP languages have caught up in this regard by providing 
refactoring tools and other IDE features. And I definitely wouldn't want 
to get rid of OOP in my toolbox because of its clear advantages in 
certain scenarios.

But I haven't yet seen a programming language that supports exploratory 
thinking as well as Lisp. It's like that exactly because of the 
s-expressions, or more specifically because of the fact that programs 
and data are the same in Lisp.

Computers are there to make my tasks easier. Not using them from the 
very beginning to help me solve programming tasks is a waste of 
computing resources.

In one particular case, I have used the CLOS MOP to implement some 
special case of a method combination. At a certain stage, I have 
realized that I have made a conceptual mistake - I have tried to resolve 
the particular method combination at the wrong stage. Instead of doing 
it inside of the method combination it had to be done at the call site. 
It was literally just a matter of placing a quote character at the right 
place - in front of the code to be executed - that allowed me to it pass 
to the right place as data, and then expand it at the call site. I can't 
describe in words what an enlightening experience this was. In any other 
language I have known until then, this change would have required a 
complete restructuring of the source code, of the phases in which to 
execute different parts of the code, of the representation for that 
code, and so on. In Lisp, it was just one keystroke!

It's because of such experiences that Lispniks don't want to switch to 
lesser languages anymore. ;-)


(More seriously, there are probably very different ways to think about 
problems. So Lisp might not be the right language for everyone, because 
other people might find completely different things helpful when they 
try to tackle a problem. It would be interesting to do some research on 
this topic. As much as I don't think that there is a single programming 
paradigm that is best suited for all possible problems I also don't 
think that there is a single programming style that is best suited for 
all programmers.)


Pascal
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <raffaelcavallaro-35EC05.21271412102003@netnews.comcast.net>
In article <············@newsreader2.netcologne.de>,
 Pascal Costanza <········@web.de> wrote:

> Many programming languages require you to build a model upfront, on 
> paper or at least in your head, and then write it down as source code. 
> This is especially one of the downsides of OOP - you need to build a 
> class hierarchy very early on without actually knowing if it is going to 
> work in the long run.

This parallels Paul Graham's critique of the whole idea of program 
"specifications." To paraphrase Graham,for any non-trivial software, 
there is no such thing as a specification. For a specification to be 
precise enough that programmers can convert it directly into code, it 
must already be a working program! What specifications are in reality is 
a direction in which programmers must explore, finding in the process 
what doesn't work and what does, and how, precisely, to implement that.

Once you've realized that there is really no such thing as the waterfall 
method, it follows inevitably that you'll prefer bottom up program 
development by exploratory methods. Once you realize that programs are 
discovered, not constructed from a blueprint, you'll inevitably prefer a 
language that gives you freedom of movement in all directions, a 
language that makes it difficult to paint yourself into a corner.
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pmoib.73408$lZ6.11874907@twister.nyc.rr.com>
Pascal Costanza wrote:

> Many programming languages require you to build a model upfront, on 
> paper or at least in your head, and then write it down as source code. 
> This is especially one of the downsides of OOP - you need to build a 
> class hierarchy very early on without actually knowing if it is going to 
> work in the long run.

Whoa! The MOP and CLOS went to a lot of trouble to create an OOP for 
Lisp that lived up to the Lisp heritage of figuring things out as we go. 
I am forever refactoring class hierarchies, dragging slots from here to 
there, adding some, erasing others, changing initforms and inheritance. 
Best of all I can do all this for a couple of hours after landing in a 
backtrace and then simply pick an appropriate stack frame from which to 
restart and all the existing instances adjust themselves on the fly.

kenny

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Greg Ewing (using news.cis.dfn.de)
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmfuj4$mbq8g$1@ID-169208.news.uni-berlin.de>
Pascal Costanza wrote:
> Many programming languages require you to build a model upfront, on 
> paper or at least in your head, and then write it down as source code. 
> This is especially one of the downsides of OOP - you need to build a 
> class hierarchy very early on without actually knowing if it is going to 
> work in the long run.

I don't think that's a downside of OOP itself, but of statically
typed OO languages that make it awkward and tedious to rearrange
your class hierarchy once you've started on it.

Python's dynamic typing and generally low-syntactic-overhead
OO makes it quite amenable to exploratory OO programming, in my
experience.

-- 
Greg Ewing, Computer Science Dept,
University of Canterbury,	
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <aeb7ff58.0310121154.79924dc4@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<············@newsreader2.netcologne.de>...

> Lispniks are driven by the assumption that there is always the 
> unexpected. No matter what happens, it's a safe bet that you can make 
> Lisp behave the way you want it to behave, even in the unlikely event 
> that something happens that no language designer has ever thought of 
> before. And even if you cannot find a perfect solution in some cases, 
> you will at least be able to find a good approximation for hard 
> problems.

This I believe is the very crux of the matter. The problem domain to
which lisp has historically been applied, artificial intelligence,
more or less guaranteed that lisp hackers would run up against the
sorts of problems that no one had ever seen before. The language
therefore evolved into a "programmable programming language," to quote
John Foderaro (or whoever first said or wrote this now famous line).

Lisp gives the programmer who knows he will be working in a domain
that is not completely cut and dried, the assurance that his language
will not prevent him for doing something that has never been done
before. Python gives me the distinct impression that I might very well
run up against the limitations of the language when dealing with very
complex problems.

For 90% of tasks, even large projects, Python will certainly have
enough in its ever expanding bag of tricks to provide a clean,
maintainable solution. But that other 10% keeps lisp hackers from
using Python for exploratory programming - seeking solutions in
problem domains that have not been solved before.
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3y8vp3y6i.fsf@rigel.goldenthreadtech.com>
Alex Martelli <·······@yahoo.com> writes:

<typical unthinking stuff>


You're unrelenting tenacity to remain ignorant far exceeds any
inclination on my part to educate.

/Jon
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm4v12$7ff$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> Pascal Costanza:
> 
>>Yes, scripting languages have caught up in this regard. (However, note
>>that Common Lisp also includes a full compiler at runtime.)
> 
> 
> However, that's an implementation difference -- the only thing
> users should see is that the code runs faster.  It doesn't otherwise
> provide new functionality.

No, not quite. You can actually control whether you want a piece of 
dynamically generated code interpreted or compiled. If such generated 
code isn't run too often (for example only once) then the overhead of 
compiling it most probably doesn't pay off but rather can be higher than 
when the code is just interpreted.

Furthermore note that this is not an implementation difference. The ANSI 
standard defines the function COMPILE.

>>Pick your choice. "There is not only one way to do it." (tm)
> 
> 
> Perl beat you to it -- "TMTOWTDO" (There's more than one way to
> do it.).   ;)
> 
> Python's reply "There should be one-- and preferably only one --
> obvious way to do it."

I simply don't believe that this will work out in the long run. Not in a 
truly general-purpose language.


Pascal
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <lzphb.4794$dn6.3306@newsread4.news.pas.earthlink.net>
Pascal Costanza:
> Furthermore note that this is not an implementation difference. The ANSI
> standard defines the function COMPILE.

Is the implementation free to *not* compile the code when the
COMPILE function is called?  That is, to leave it as is?  How
would a user tell the difference without running a timing test?

> I simply don't believe that this will work out in the long run. Not in a
> truly general-purpose language.

Indeed.  That viewpoint (agree or disagree) really is one of
underlying cultural differences which have helped .... um....
invigorate this discussion.

                    Andrew
                    ·····@dalkescientific.com
From: Paul F. Dietz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <WPWdnfWZYr2bBBuiU-KYvA@dls.net>
Andrew Dalke wrote:
> Pascal Costanza:
> 
>>Furthermore note that this is not an implementation difference. The ANSI
>>standard defines the function COMPILE.
> 
> 
> Is the implementation free to *not* compile the code when the
> COMPILE function is called?  That is, to leave it as is?  How
> would a user tell the difference without running a timing test?

In CL, COMPILE (and COMPILE-FILE) are not required by the CL spec
to convert lisp code to machine language.  Many implementations do,
however, and it tends to be one of the major defining characteristics
of a CL implementation.

A conforming implementation must perform certain minimal steps
at compilation time.  See section 3.2.2.2 of the CL spec.  It states:

    Minimal compilation is defined as follows:

     * All compiler macro calls appearing in the source code being
       compiled are expanded, if at all, at compile time; they will
       not be expanded at run time.

     * All macro and symbol macro calls appearing in the source code
       being compiled are expanded at compile time in such a way that
       they will not be expanded again at run time. macrolet and
       symbol-macrolet are effectively replaced by forms corresponding
       to their bodies in which calls to macros are replaced by their expansions.

     * The first argument in a load-time-value form in source code
       processed by compile is evaluated at compile time; in source code
       processed by compile-file, the compiler arranges for it to be
       evaluated at load time. In either case, the result of the evaluation
       is remembered and used later as the value of the load-time-value
       form at execution time.

Other than this,a conforming implementation is allowed to leave the
source code alone, compile it to byte codes, compile it to machine
language, or any other correctness-preserving transformation.

It would be conforming to do the minimal compilation, produce byte codes, then
dynamically convert the byte codes to machine language at run time as in Psyco.

	Paul
From: Christophe Rhodes
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <sqekxlpl9d.fsf@lambda.jcn.srcf.net>
"Andrew Dalke" <······@mindspring.com> writes:

> Pascal Costanza:
>> Furthermore note that this is not an implementation difference. The ANSI
>> standard defines the function COMPILE.
>
> Is the implementation free to *not* compile the code when the
> COMPILE function is called?  That is, to leave it as is?  How
> would a user tell the difference without running a timing test?

Somewhat ironically given the context, within the standard a user can
only tell whether code has been compiled by whether redefinitions of
macros affect the execution or not.  (If they do, it hasn't been
compiled; if they don't, it has).

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: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm64ii$pi2$1@f1node01.rhrz.uni-bonn.de>
Andrew Dalke wrote:
> Pascal Costanza:
> 
>>Furthermore note that this is not an implementation difference. The ANSI
>>standard defines the function COMPILE.
> 
> 
> Is the implementation free to *not* compile the code when the
> COMPILE function is called?  That is, to leave it as is?  How
> would a user tell the difference without running a timing test?

...by looking at the documentation. ;)


Seriously, ANSI CL defines "minimal compilation". See 
http://www.lispworks.com/reference/HyperSpec/Body/03_bbb.htm

Most CL implementations do more than that.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Sampo Smolander
Subject: car, cdr; 1sr, rst
Date: 
Message-ID: <bnfg7j$c9o$1@oravannahka.helsinki.fi>
In comp.lang.scheme Andrew Dalke <······@mindspring.com> wrote:
> Pascal Costanza:
>> I don't know how this could be done with 1st, rst or hd, tl respectively.

> Okay, I gave alternatives of "." and ">" instead of "car" and "cdr"
> "." for "here" and ">" for "the rest; over there".  These are equally
> composable.

>  . == car
>  > == cdr
>  cadr  == >.
>  caddr == >>.
>  cddr == >>

One can also go like:

1st == car
rst == cdr
1rst == cadr
1rrst == caddr
rrst == cddr

The benefit being, it's less messy to quote these in Usenet :-)
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ad8a2xoc.fsf@thalassa.informatimago.com>
"Andrew Dalke" <······@mindspring.com> writes:
> That to me is a solid case of post hoc ergo proper.  The
> words "1st" and "rst" are equally as short and easier to
> memorize.  And if terseness were very important, then
> what about using "." for car and ">" for cdr?  No, the reason
> is that that's the way it started and it will stay that way
> because of network effects -- is that a solid engineering
> reason?  Well, it depends, but my guess is that he wouldn't
> weight strongly the impact of social behaviours as part of
> good engineering.  I do.

Right, network effect.  And attachment  to historic heritage.  C has B
and "Hello World!". COBOL has real  bugs pined in log books.  Lisp has
704' CAR  and CDR. 


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Greg Ewing (using news.cis.dfn.de)
Subject: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmd2js$l3vkg$1@ID-169208.news.uni-berlin.de>
Andrew Dalke wrote:
>    It has sometimes been said that Lisp should use first and
>    rest instead of car and cdr

I used to think something like that would be more logical, too.
Until one day it occurred to me that building lists is only
one possible, albeit common, use for cons cells. A cons cell
is actually a completely general-purpose two-element data
structure, and as such its accessors should have names that
don't come with any preconceived semantic connotations.

 From that point of view, "car" and "cdr" are as good
as anything!

-- 
Greg Ewing, Computer Science Dept,
University of Canterbury,	
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg
From: Rayiner Hashem
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <a3995c0d.0310130023.584ec93f@posting.google.com>
>  From that point of view, "car" and "cdr" are as good
> as anything!
Well, if you're going to call the thing a 'cons' you might as well go
all the way and use 'car' and 'cdr' as operators. A little flavor is
nice, although I think that "4th" would be easier to read than
"cadddr"...
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmdqrc$n40$1@f1node01.rhrz.uni-bonn.de>
Rayiner Hashem wrote:
>> From that point of view, "car" and "cdr" are as good
>>as anything!
> 
> Well, if you're going to call the thing a 'cons' you might as well go
> all the way and use 'car' and 'cdr' as operators. A little flavor is
> nice, although I think that "4th" would be easier to read than
> "cadddr"...

...but cadddr might not be "fourth". It might be some leaf in a tree. Or 
something completely different. "fourth" doesn't always make sense.

(And just for the sake of completeness, Common Lisp does have FOURTH and 
also (NTH 3 ...).)

Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Kenny Tilton
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <_juib.73433$lZ6.11992981@twister.nyc.rr.com>
Pascal Costanza wrote:

> Rayiner Hashem wrote:
> 
>>> From that point of view, "car" and "cdr" are as good
>>> as anything!
>>
>>
>> Well, if you're going to call the thing a 'cons' you might as well go
>> all the way and use 'car' and 'cdr' as operators. A little flavor is
>> nice, although I think that "4th" would be easier to read than
>> "cadddr"...
> 
> 
> ...but cadddr might not be "fourth". It might be some leaf in a tree. Or 
> something completely different. "fourth" doesn't always make sense.
> 
> (And just for the sake of completeness, Common Lisp does have FOURTH and 
> also (NTH 3 ...).)
> 

And it maxes out at ten:

    http://www.lispworks.com/reference/HyperSpec/Body/f_firstc.htm#tenth

Doesn't seem right for a language that goes to eleven.*

:)

kenny

* That's one more, isn't it?

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bme4jk$sgc$1@f1node01.rhrz.uni-bonn.de>
Stephen Horne wrote:
> On Mon, 13 Oct 2003 15:28:57 +1300, "Greg Ewing (using
> news.cis.dfn.de)" <··········@sneakemail.com> wrote:
> 
> 
>>Andrew Dalke wrote:
>>
>>>   It has sometimes been said that Lisp should use first and
>>>   rest instead of car and cdr
>>
>>I used to think something like that would be more logical, too.
>>Until one day it occurred to me that building lists is only
>>one possible, albeit common, use for cons cells. A cons cell
>>is actually a completely general-purpose two-element data
>>structure, and as such its accessors should have names that
>>don't come with any preconceived semantic connotations.
>>
>>From that point of view, "car" and "cdr" are as good
>>as anything!
> 
> 
> "left" and "right" - referring to 'subtrees'?

Sure, why not?

(defun left (tree)
   (car tree))

(defun right (tree)
   (cdr tree))


;-)

Note: Why break anyone else's code just because you prefer a different 
vocabulary?

(Yes, this is different from the Python mindset. What I have learnt from 
this thread is that the languages might seem similar on the technical 
level, but the "social" goals of the languages are vastly different.)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Pascal Bourguignon
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <87he2di529.fsf@thalassa.informatimago.com>
Pascal Costanza <········@web.de> writes:
> Stephen Horne wrote:
> > On Mon, 13 Oct 2003 15:28:57 +1300, "Greg Ewing (using
> > news.cis.dfn.de)" <··········@sneakemail.com> wrote:
> > 
> >>Andrew Dalke wrote:
> >>From that point of view, "car" and "cdr" are as good
> >>as anything!
> > "left" and "right" - referring to 'subtrees'?
> 
> Sure, why not?
> 
> (defun left (tree)
>    (car tree))
> 
> (defun right (tree)
>    (cdr tree))
>
> ;-)
 
Wrong:

    (defun left  (tree)  (car (car tree)))
    (defun right (tree)  (cdr (car tree)))
    (defun label (tree)  (cdr tree))
 
 
> Note: Why break anyone else's code just because you prefer a different
> vocabulary?
> 
> (Yes, this is different from the Python mindset. What I have learnt
> from this thread is that the languages might seem similar on the
> technical level, but the "social" goals of the languages are vastly
> different.)

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmed8i$sha$1@f1node01.rhrz.uni-bonn.de>
Pascal Bourguignon wrote:
> Pascal Costanza <········@web.de> writes:
> 
>>Stephen Horne wrote:
>>
>>>On Mon, 13 Oct 2003 15:28:57 +1300, "Greg Ewing (using
>>>news.cis.dfn.de)" <··········@sneakemail.com> wrote:
>>>
>>>
>>>>Andrew Dalke wrote:
>>>
>>>>From that point of view, "car" and "cdr" are as good
>>>
>>>>as anything!
>>>
>>>"left" and "right" - referring to 'subtrees'?
>>
>>Sure, why not?
>>
>>(defun left (tree)
>>   (car tree))
>>
>>(defun right (tree)
>>   (cdr tree))
>>
>>;-)
> 
>  
> Wrong:
> 
>     (defun left  (tree)  (car (car tree)))
>     (defun right (tree)  (cdr (car tree)))
>     (defun label (tree)  (cdr tree))

I see your point, but "wrong" is a bit strong here:

(defvar *tree-labels* (make-hash-table))

(defun label (tree) (gethash tree *tree-labels*))


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Pascal Bourguignon
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <87brslhz1x.fsf@thalassa.informatimago.com>
Pascal Costanza <········@web.de> writes:
> >>>"left" and "right" - referring to 'subtrees'?
> >>
> >>Sure, why not?
> >>
> >>(defun left (tree)
> >>   (car tree))
> >>
> >>(defun right (tree)
> >>   (cdr tree))
> >>
> >>;-)
> >  Wrong:
> >     (defun left  (tree)  (car (car tree)))
> >     (defun right (tree)  (cdr (car tree)))
> >     (defun label (tree)  (cdr tree))
> 
> I see your point, but "wrong" is a bit strong here:

This was a rhetorical "wrong" :-)
 
> (defvar *tree-labels* (make-hash-table))
> 
> (defun label (tree) (gethash tree *tree-labels*))

While this kind  of technique may be helpful (or  even save our "life"
sometimes), I don't like it because of the loose coupling and possible
inconsistency between  the various data structures...  I  think it can
only be justified by low-level optimization reasons.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmfdah$afm$1@newsreader2.netcologne.de>
Pascal Bourguignon wrote:

> Pascal Costanza <········@web.de> writes:
> 
>>>>>"left" and "right" - referring to 'subtrees'?
>>>>
>>>>Sure, why not?
>>>>
>>>>(defun left (tree)
>>>>  (car tree))
>>>>
>>>>(defun right (tree)
>>>>  (cdr tree))
>>>>
>>>>;-)
>>>
>>> Wrong:
>>>    (defun left  (tree)  (car (car tree)))
>>>    (defun right (tree)  (cdr (car tree)))
>>>    (defun label (tree)  (cdr tree))
>>
>>I see your point, but "wrong" is a bit strong here:
> 
> 
> This was a rhetorical "wrong" :-)

:-)

>>(defvar *tree-labels* (make-hash-table))
>>
>>(defun label (tree) (gethash tree *tree-labels*))
> 
> 
> While this kind  of technique may be helpful (or  even save our "life"
> sometimes), I don't like it because of the loose coupling and possible
> inconsistency between  the various data structures...  I  think it can
> only be justified by low-level optimization reasons.

Hey, this was only a toy example. Let's just forget about it... ;)


Pascal
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmgh32$1a32$1@f1node01.rhrz.uni-bonn.de>
Stephen Horne wrote:

> This would make some sense. After all, 'head' and 'tail' actually
> imply some things that are not always true. Those 'cons' thingies may
> be trees rather than lists, and even if they are lists they could be
> backwards (most of the items under the 'car' side with only one item
> on the 'cdr' side) which is certainly not what I'd expect from 'head'
> and 'tail'.

I think that's the essential point here. The advantage of the names car 
and cdr is that they _don't_ mean anything specific. I wouldn't mind if 
they were called jrl and jol, or rgk and rsk, etc. pp.

This is similar to how array elements are accessed. In expressions like 
a[5], the number 5 doesn't mean anything specific either.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Hartmann Schaffer
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <3f8c2182@news.sentex.net>
In article <·············@f1node01.rhrz.uni-bonn.de>,
	Pascal Costanza <········@web.de> writes:
> ...
> I think that's the essential point here. The advantage of the names car 
> and cdr is that they _don't_ mean anything specific.

gdee, you should read early lisp history ;-).  car and cdr ha[d|ve] a
very specific meaning

hs

-- 

ceterum censeo SCO esse delendam
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmhpqi$jf0$1@newsreader2.netcologne.de>
Hartmann Schaffer wrote:

> In article <·············@f1node01.rhrz.uni-bonn.de>,
> 	Pascal Costanza <········@web.de> writes:
> 
>>...
>>I think that's the essential point here. The advantage of the names car 
>>and cdr is that they _don't_ mean anything specific.
> 
> 
> gdee, you should read early lisp history ;-).  car and cdr ha[d|ve] a
> very specific meaning

Yes, but noone (noone at all) refers to that meaning anymore. It's a 
historical accident that doesn't really matter anymore when developing code.


Pascal
From: Pascal Bourguignon
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <87smlripkq.fsf@thalassa.informatimago.com>
Pascal Costanza <········@web.de> writes:

> Hartmann Schaffer wrote:
> 
> > In article <·············@f1node01.rhrz.uni-bonn.de>,
> > 	Pascal Costanza <········@web.de> writes:
> > 
> >>...
> >> I think that's the essential point here. The advantage of the names
> >> car and cdr is that they _don't_ mean anything specific.
> > gdee, you should read early lisp history ;-).  car and cdr ha[d|ve] a
> > very specific meaning
> 
> Yes, but noone (noone at all) refers to that meaning anymore. It's a
> historical accident that doesn't really matter anymore when developing
> code.

For that matter,  even the very first LISP  _programmer_ did not refer
to that meaning either.

Only the _implementer_ of the first LISP did.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
Lying for having sex or lying for making war?  Trust US presidents :-(
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmka9k$2a8$2@newsreader2.netcologne.de>
Hartmann Schaffer wrote:

 > In article <·············@f1node01.rhrz.uni-bonn.de>,
 >     Pascal Costanza <········@web.de> writes:
 >
 >> ...
 >> I think that's the essential point here. The advantage of the names 
car and cdr is that they _don't_ mean anything specific.
 >
 >
 >
 > gdee, you should read early lisp history ;-).  car and cdr ha[d|ve] a
 > very specific meaning


Yes, but noone (noone at all) refers to that meaning anymore. It's a 
historical accident that doesn't really matter anymore when developing code.


Pascal
From: Pascal Bourguignon
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <87k775jlki.fsf@thalassa.informatimago.com>
Pascal Costanza <········@web.de> writes:

> Hartmann Schaffer wrote:
> 
>  > In article <·············@f1node01.rhrz.uni-bonn.de>,
>  >     Pascal Costanza <········@web.de> writes:
>  >
>  >> ...
>  >> I think that's the essential point here. The advantage of the
>     names car and cdr is that they _don't_ mean anything specific.
>  >
>  >
>  >
>  > gdee, you should read early lisp history ;-).  car and cdr ha[d|ve] a
>  > very specific meaning
> 
> 
> Yes, but noone (noone at all) refers to that meaning anymore. It's a
> historical accident that doesn't really matter anymore when developing
> code.

Indeed.  Had the first lisp been  programmed on a 680x0, we would have
d0 and d1 instead of car and  cdr, or worse, had it been done on 8086,
we would have ax and bx...

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Pascal Costanza
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmmdtj$ght$1@newsreader2.netcologne.de>
Pascal Bourguignon wrote:

> Indeed.  Had the first lisp been  programmed on a 680x0, we would have
> d0 and d1 instead of car and  cdr, or worse, had it been done on 8086,
> we would have ax and bx...

...and both would have the same advantage of composability of names.

cadr <=> d01 <=> abx
caddr <=> d011 <=> abbx
cdar <=> d10 <=> bax
cadar <=> d010 <=> abax
caar <=> d00 <=> aax

Not too bad, although I'd definitely prefer varying letters over 0s and 1s.

It seems to be natural for any two such operators that at least one 
letter is always fixed.

However, I still also like the fact that to me, "d" resonates somewhat 
with "rest". I mean, I can only count to three. So, a is 1st, b is 2nd, 
c is 3rd, and d is, well, somewhere in the rest of the alphabet. ;-)


Pascal
From: John M. Gamble
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <bmnrfd$de$4@e250.ripco.com>
In article <··············@thalassa.informatimago.com>,
Pascal Bourguignon  <····@thalassa.informatimago.com> wrote:
>Pascal Costanza <········@web.de> writes:
>
>> Hartmann Schaffer wrote:
>> 
>>  > In article <·············@f1node01.rhrz.uni-bonn.de>,
>>  >     Pascal Costanza <········@web.de> writes:
>>  >
>>  >> ...
>>  >> I think that's the essential point here. The advantage of the
>>     names car and cdr is that they _don't_ mean anything specific.
>>  >
>>  >
>>  >
>>  > gdee, you should read early lisp history ;-).  car and cdr ha[d|ve] a
>>  > very specific meaning
>> 
>> 
>> Yes, but noone (noone at all) refers to that meaning anymore. It's a
>> historical accident that doesn't really matter anymore when developing
>> code.
>
>Indeed.  Had the first lisp been  programmed on a 680x0, we would have
>d0 and d1 instead of car and  cdr, or worse, had it been done on 8086,
>we would have ax and bx...
>

I think you mean "cd0 and cd1" and "cax and cbx".  The Cs in car
and cdr mean "contents".  For that matter, the Rs mean register,
so i suppose it would go "cd0r", "cd1r", etc.

-- 
	-john

February 28 1997: Last day libraries could order catalogue cards
from the Library of Congress.
From: Christos "TZOTZIOY" Georgiou
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <8bf2pvobvhja58691has9rflhge994vd1a@4ax.com>
On 16 Oct 2003 16:37:01 +0200, rumours say that Pascal Bourguignon
<····@thalassa.informatimago.com> might have written:

>> Yes, but noone (noone at all) refers to that meaning anymore. It's a
>> historical accident that doesn't really matter anymore when developing
>> code.
>
>Indeed.  Had the first lisp been  programmed on a 680x0, we would have
>d0 and d1 instead of car and  cdr, or worse, had it been done on 8086,
>we would have ax and bx...

Perhaps on 680x0 they would be ca0 and cd0, or ca0r and cd0r.  AFAIK car
stands for contents of address register and cdr for contents of contents
of data register.  So, picking register 0 out of 8 (7 if you exclude a7
/ sp) address registers and register 0 out of 8 data registers is just a
choice on this hypothetical subject.

However, I have a suspicion that the "correct" names would be ca0r and
c(a0)r ...
-- 
TZOTZIOY, I speak England very best,
Ils sont fous ces Redmontains! --Harddix
From: Rob Warnock
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <btCdnXAhTbAKSgmiXTWc-w@speakeasy.net>
Christos "TZOTZIOY" Georgiou  <····@sil-tec.gr> wrote:
+---------------
| AFAIK car stands for contents of address register and
| cdr for contents of contents of data register.
+---------------

From the IBM 704 CPU instruction format:
CAR == "Contents of Address [part of] Register".
CDR == "Contents of Decrement [part of] Register".
See <URL:http://www.catb.org/~esr/jargon/html/C/cdr.html>.

Note that the PDP-10 AOBJP/AOBJN/BLKI/BLKO/PUSH/PUSHJ/POP/POPJ
instructions used a similar format, but with the "decrement" part
being a negative count in the upper half of the word (which was
*incremented* in parallel with the address in the lower half
[or in the case of POP & POPJ only, decremented in parallel with
the address]).


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Roy Smith
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <roy-4C9771.07485621102003@reader1.panix.com>
····@rpw3.org (Rob Warnock) wrote:
> Note that the PDP-10 AOBJP/AOBJN/BLKI/BLKO/PUSH/PUSHJ/POP/POPJ
> instructions used a similar format.

I havn't thought about that stuff for many years.  Now you've made my 
brain hurt again.
From: Christos "TZOTZIOY" Georgiou
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <g12bpvcs85pkc5ajte9djci8va1etbkis2@4ax.com>
On Tue, 21 Oct 2003 01:52:07 -0500, rumours say that ····@rpw3.org (Rob
Warnock) might have written:

>+---------------
>| AFAIK car stands for contents of address register and
>| cdr for contents of contents of data register.
>+---------------
>
>From the IBM 704 CPU instruction format:
>CAR == "Contents of Address [part of] Register".
>CDR == "Contents of Decrement [part of] Register".
>See <URL:http://www.catb.org/~esr/jargon/html/C/cdr.html>.

Thanks for correcting me :)
-- 
TZOTZIOY, I speak England very best,
Ils sont fous ces Redmontains! --Harddix
From: Avi Blackmore
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <7c1401ca.0310170243.2c0863d@posting.google.com>
"Greg Ewing (using news.cis.dfn.de)" <··········@sneakemail.com> wrote in message news:<··············@ID-169208.news.uni-berlin.de>...

[snip]
> 
>  From that point of view, "car" and "cdr" are as good
> as anything!

    Better in one sense, I think.  With "first" and "rest", you can't
have fun making bumper stickers that say "My other car is a cdr."

Avi Blackmore
From: Terry Reedy
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <7O6dnTI-M4_-YRKiRVn-tA@comcast.com>
"Avi Blackmore" <········@cableone.net> wrote in message
································@posting.google.com...
> "Greg Ewing (using news.cis.dfn.de)" <··········@sneakemail.com>
wrote in message news:<··············@ID-169208.news.uni-berlin.de>...
>
> [snip]
> >
> >  From that point of view, "car" and "cdr" are as good
> > as anything!
>
>     Better in one sense, I think.  With "first" and "rest", you
can't
> have fun making bumper stickers that say "My other car is a cdr."
>
> Avi Blackmore

Crossposting this insider-joke car and cdr thread on c.l.python, where
it is wildly off-topic, only makes Lisp look silly.
From: Shriram Krishnamurthi
Subject: Re: Car and cdr (Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <w7d7k33zhvc.fsf@cs.brown.edu>
········@cableone.net (Avi Blackmore) writes:

> "Greg Ewing (using news.cis.dfn.de)" <··········@sneakemail.com> wrote in message news:<··············@ID-169208.news.uni-berlin.de>...
> 
> [snip]
> > 
> >  From that point of view, "car" and "cdr" are as good
> > as anything!
> 
>     Better in one sense, I think.  With "first" and "rest", you can't
> have fun making bumper stickers that say "My other car is a cdr."

Or my wife's car, which she backed into a dumpster, damaging the
fender.  We took to calling it the car without a cdr.

Shriram
From: Alain Picard
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <873cdxj8jg.fsf@memetrics.com>
"Andrew Dalke" <······@mindspring.com> quotes Paul Graham:

> Consider one of those "hard-headed engineering reasons", at
> http://www.paulgraham.com/popular.html
>
>    It has sometimes been said that Lisp should use first and
>    rest instead of car and cdr, because it would make programs

I (and I'm pretty sure I'm not alone) actually like to
use _both CAR/CDR and FIRST/REST; using each to imply
a certain kind of semantic distinction; use CAR when you're
dealing with a raw CONS cell; i.e. you only care about 
"the left part" and "the right part", but FIRST when you're
dealing with a proper list.

The name basically become reminders (syntactic sugar?) of the
intention of the programmer at the time of writing.
From: Björn Lindberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <hcs4qyid9ed.fsf@tjatte.nada.kth.se>
"Andrew Dalke" <······@mindspring.com> writes:

> > If you want some real world numbers on program length check here:
> > http://www.bagley.org/~doug/shootout/
> 
> If I want some real world numbers on program length, I do it myself:
>   http://pleac.sourceforge.net/
> I wrote most of the Python code there
> 
> Still, since you insist, I went to the scorecard page and changed
> the weights to give LOC a multipler of 1 and the others a multiplier
> of 0.  This is your definition of succinctness, yes?  This table
> is sorted (I think) by least LOC to most.

<snip>

> So:
>   - Why aren't you using Ocaml?
>   - Why is Scheme at the top *and* bottom of the list?
>   - Python is right up there with the Lisp/Scheme languages
>   -  ... and with Perl.
> 
> Isn't that conclusion in contradiction to your statements
> that 1) "Perl is *far* more compact than Python is" and 2)
> the implicit one that Lisp is significantly more succinct than
> Python?  (As you say, these are small projects .. but you did
> point out this site so implied it had some relevance.)

Apart from the usual problems with micro benchmarks, there are a few
things to consider regarding the LOC counts on that site:

  * Declarations. Common Lisp gives the programmer the ability to
    optimize a program by adding declarations to it. This is purely
    optional, and something you normally don't do until you discover a
    bottelneck in your code. For instance, it is possible to add type
    declarations so that the compiler can generate more efficient
    code. In a normal program, the declarations (if any) will
    constitute an extremely small part of the program, but since the
    micro benchmarks in the shootout are focused on speed of
    execution, and they are so small, all of them contains a lot of
    declarations, which will increase LOC.

  * In many languages, any program can be written on a single
    line. This goes for Lisp, ut also for C and other languages. This
    means that the LOC count is also affected by formatting. For
    instance, in the Ackermann's function benchmark, the Ackermann
    function is written like this in the C code:

      int Ack(int M, int N) { return(M ? (Ack(M-1,N ? Ack(M,(N-1)) : 1)) : N+1); }
    
    That is, 1 LOC, although most people would probably write it in
    anything between 5-10 lines.

  * I don't think the LOC saving qualities of Lisp is made justice in
    micro benchmarks. The reason Lisp code is so much shorter than the
    equivalent code in other languages is because of the abstractive
    powers of Lisp, which means that the difference will be more
    visible the larger the program is.


Bj�rn
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <WFihb.4375$dn6.3023@newsread4.news.pas.earthlink.net>
Bj�rn Lindberg:
> Apart from the usual problems with micro benchmarks, there are a few
> things to consider regarding the LOC counts on that site:

I wasn't the one who pointed out those micro benchmarks.  Kenny
Tilton pushed the idea that more concise code is better and that Lisp
gives the most concise code, and that Perl is much more compact
than Python.  He suggested I look at some comparisons, so I followed
his suggestion and found that 1) the Lisp code there was not more
succinct than Python and 2) neither was the Perl code.

>   * Declarations. Common Lisp gives the programmer the ability to
>     optimize a program by adding declarations to it.

While OCaml, which has the smallest size, does type inferencing....

>     since the
>     micro benchmarks in the shootout are focused on speed of
>     execution, and they are so small, all of them contains a lot of
>     declarations, which will increase LOC.

Ahh, good point.

>   * In many languages, any program can be written on a single
>     line. This goes for Lisp, ut also for C and other languages.

Absolutely correct.  Both Alex Martellli and I tried to dissuade
Kenny Tilton that LOC was the best measure of succinctness and
appropriateness, and he objected.

>   * I don't think the LOC saving qualities of Lisp is made justice in
>     micro benchmarks. The reason Lisp code is so much shorter than the
>     equivalent code in other languages is because of the abstractive
>     powers of Lisp, which means that the difference will be more
>     visible the larger the program is.

Agreed.  I pointed out elsewhere that there has been no systematic
study to show that Lisp code is indeed "so much shorter than the
equivalent code in other languages" where "other languages" include
Python, Perl, or Ruby.

The closest is
 http://www.ipd.uka.de/~prechelt/Biblio/
where the example program, which was non-trivial in size
took about 100LOC in Tcl/Rexx/python/perl and about 250LOC
in Java/C/C++.

There was a repeat of that test at
  http://www.flownet.com/gat/papers/lisp-java.pdf
which showed that the average Lisp size was 119 LOC and
277 for Java.  I eyeballed the numbers, and I'm not sure if
the counts included comments or not, so call it the same.

In any case, it implies you need to get to some serious sized
programs (1000 LOC? 10000LOC? A million?) before
the advantages of Lisp appear to be significant.

That's not saying that they are more obvious in some subdomain.
For that matter, if I want to do hardware I/O on some
memory mapped ports, it's pretty obvious that C is a good
contender for that domain.

So we're left with depending on gut feelings, guided by
(non-rigorous) observation.  Eg, observations that Python
does scale to large projects, observations that the people
who will use my code (computational scientists, not
programmers) find Python easier than Lisp and Tcl-style
commands easier than Python :(.

                    Andrew
                    ·····@dalkescientific.com
From: Björn Lindberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <hcssmm1pbo6.fsf@tjatte.nada.kth.se>
"Andrew Dalke" <······@mindspring.com> writes:

> Bj�rn Lindberg:
> > Apart from the usual problems with micro benchmarks, there are a few
> > things to consider regarding the LOC counts on that site:
> 
> I wasn't the one who pointed out those micro benchmarks.  Kenny
> Tilton pushed the idea that more concise code is better and that Lisp
> gives the most concise code, and that Perl is much more compact
> than Python.  He suggested I look at some comparisons, so I followed
> his suggestion and found that 1) the Lisp code there was not more
> succinct than Python and 2) neither was the Perl code.
> 
> >   * Declarations. Common Lisp gives the programmer the ability to
> >     optimize a program by adding declarations to it.
> 
> While OCaml, which has the smallest size, does type inferencing....

The good Lisp compilers do type inferencing too AFAIK, but since Lisp
is fully dynamic it is not always possible for the compiler to do full
type inference at compile time. Declarations help the compiler in this
respect.

<snip>

> >   * In many languages, any program can be written on a single
> >     line. This goes for Lisp, ut also for C and other languages.
> 
> Absolutely correct.  Both Alex Martellli and I tried to dissuade
> Kenny Tilton that LOC was the best measure of succinctness and
> appropriateness, and he objected.

I think in general there *is* a correlation between LOC and
succinctness, eg LOC(assembler) > LOC(C) > LOC(awk). It is probably
not a very strong correlation though, and it would probably be more
accurate for larger programs than small code snippets.

> >   * I don't think the LOC saving qualities of Lisp is made justice in
> >     micro benchmarks. The reason Lisp code is so much shorter than the
> >     equivalent code in other languages is because of the abstractive
> >     powers of Lisp, which means that the difference will be more
> >     visible the larger the program is.
> 
> Agreed.  I pointed out elsewhere that there has been no systematic
> study to show that Lisp code is indeed "so much shorter than the
> equivalent code in other languages" where "other languages" include
> Python, Perl, or Ruby.

It would be interesting to see such studies made.

> The closest is
>  http://www.ipd.uka.de/~prechelt/Biblio/
> where the example program, which was non-trivial in size
> took about 100LOC in Tcl/Rexx/python/perl and about 250LOC
> in Java/C/C++.

That is an interesting study, although there are some possible flaws
(eg no controlled selection of participants). The programming problem
in that study is far to small to meaningfully test any abstraction
capabilities in the language on the level of macros, OO or HOF
though.

<snip>

> In any case, it implies you need to get to some serious sized
> programs (1000 LOC? 10000LOC? A million?) before
> the advantages of Lisp appear to be significant.

I think that goes for any advantages due to abstraction capabilities
of macros, OO or HOF. The small program in the study above seems to
capture the scripting languages higher level compared to the
close-to-the-machine languages C & C++. (I have not read all of it
though.) To show advantages of the abstraction facilities we have been
discussing in this thread, I believe much larger programs are needed.


Bj�rn
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Wpyhb.194741$hE5.6583756@news1.tin.it>
Bj�rn Lindberg wrote:
   ...
>> Agreed.  I pointed out elsewhere that there has been no systematic
>> study to show that Lisp code is indeed "so much shorter than the
>> equivalent code in other languages" where "other languages" include
>> Python, Perl, or Ruby.
> 
> It would be interesting to see such studies made.

Absolutely!  But funding such studies would seem hard.  Unless some
company or group of volunteers had their own reasons to take some
existing large app coded in Lisp/Python/Perl/Ruby, and recode it in
one of the other languages with essentially unchanged functionality,
which doesn't seem all that likely.  And if it happened, whatever
group felt disappointed in the results would easily find a zillion
methodological flaws to prove that the results they dislike should
be ignored, nay, reversed.

In practice, such a re-coding would likely involve significant
changes in functionality, making direct comparisons iffy, I fear.

I know (mostly by hearsay) of some C++/Java conversions done
within companies (C++ -> Java for portability, Java -> C++ for
performance) with strong constraints on functionality being "just
the same" between the two versions (and while that's far from
a "scientific result", a curious pattern seems to emerge: going
from C++ to Java seems to produce the same LOC's, apparently a
disappointment for some; going from Java to C++ seems to expand
LOC's by 10%/20%, ditto -- but how's one to say if the C++ code
had properly exploited the full macro-like power of templates,
for example...?).  But I don't even have hearsay about any such
efforts between different higher-level languages (nothing beyond
e.g. a paltry few thousand lines of Perl being recoded to Python
and resulting in basically the same LOC's; or PHP->Python similarly,
if PHP can count as such a language, perhaps in a restricted context).


>> In any case, it implies you need to get to some serious sized
>> programs (1000 LOC? 10000LOC? A million?) before
>> the advantages of Lisp appear to be significant.
> 
> I think that goes for any advantages due to abstraction capabilities
> of macros, OO or HOF. The small program in the study above seems to
> capture the scripting languages higher level compared to the
> close-to-the-machine languages C & C++. (I have not read all of it
> though.) To show advantages of the abstraction facilities we have been
> discussing in this thread, I believe much larger programs are needed.

Yes, and perhaps to show advantages of one such abstraction facility
(say macros) wrt another (say HOFs) would require yet another jump up
in application size, if it could be done at all.  Unless some great
benefactors with a few megabucks to wast^H^H^H^H invest for the general
benefit of humanity really feel like spending them in funding such
studies, I strongly suspect they're never really going to happen:-(.


Alex
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <E6zhb.30845$pv6.30305@twister.nyc.rr.com>
Bj�rn Lindberg wrote:

> "Andrew Dalke" <······@mindspring.com> writes:
> 
> 
>>Bj�rn Lindberg:
>>
>>>Apart from the usual problems with micro benchmarks, there are a few
>>>things to consider regarding the LOC counts on that site:
>>
>>I wasn't the one who pointed out those micro benchmarks.  Kenny
>>Tilton pushed the idea that more concise code is better and that Lisp
>>gives the most concise code, and that Perl is much more compact
>>than Python.  He suggested I look at some comparisons, so I followed
>>his suggestion and found that 1) the Lisp code there was not more
>>succinct than Python and 2) neither was the Perl code.

You might be thinking of someone else. I remember a recent discussion 
focused on this, but IIRC all other things were equal.

All else being equal, shorter is better. But then right away things can 
get longer, since cryptic languages like APL, K, and (I gather) Perl are 
not equal in value to nice long function and data names.

As for that ridiculous study, it includes VB. VB suffers from The 4GL 
Problem. It reduces LOC by making decisions for you. But no general tool 
can successfully get the decision right for all the people all the time. 
And 4GL tools are not meant to be tailored to individual requirements. 
Where hooks even exist, one ends up in the dread situation of Fighting 
the Tool.

So leave me out of this. :)

>>Absolutely correct.  Both Alex Martellli and I tried to dissuade
>>Kenny Tilton that LOC was the best measure of succinctness and
>>appropriateness, and he objected.

All things being equal.


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <k7fhb.5752584$cI2.813489@news.easynews.com>
Andrew Dalke wrote:
> Doug Tolton:
> 
>>Yes and I have repeatedly stated that I disagree with it.  I simply do
>>not by that allowing expressiveness via high level constructs detracts
>>from the effectiveness of the group.  That argument is plainly
>>ridiculous, if it were true then Python would be worse than Java,
>>because Python is *far* more expressive.
> 
> 
> I disagree with your summary.  Compare:
> 
>   The argument is that expressive power for a single developer can, for
>   a group of developers and especially those comprised of people with
>   different skill sets and mixed expertise, reduce the overall effectiveness
>   of the group.
> 
> Notice the "can".   Now your summary is:
> 
>   ...allowing expressiveness via high level constructs detracts
>   from the effectiveness of the group
> 
> That implies that at least I assert that *all* high level constructs
> detract from group effectiveness, when clearly I am not saying
> that.
> 
> 
> 
>>>If this is indeed the crux, then any justification which says "my brain"
>>>and "I" is suspect, because that explicitly ignores the argument.
>>
>>Apparently you can't read very well.  I simply stated that I believe our
>>point of contention to be that issue, I never stated I believe that
>>because it's some vague theory inside my head.
> 
> 
> Nor can you, because I did not say that.  I said that the arguments you
> use to justify your assertions could be stronger if you were to include
> cases in your history and experience which show that you understand
> the impacts of a language feature on both improving and detracting from
> a group effort.  Since you do have that experience, bring it up.  But
> since your arguments are usually along the lines of "taking tools out
> of your hands", they carry less weight for this topic.
> 
> (Ambiguity clarification: "your hands" is meant as 2nd person singular
> possessive and not 2nd person plural. :)
> 
> 
>>No, what I was referring to wasn't estimation.  Rather I was referring
>>to the study that found that programmers on average write the same
>>number of lines of code per year regardless of the language they write
>>in.
> 
> 
> McConnell's book has the same study, with outliers for assembly
> and APL.  Indeed, I mentioned this in my reply:
> 
>>>... and that LOC has a
>>>good correlation to development time, excluding extremes like APL
>>>and assembly.
> 
> 
>> Therefore the only way to increase productivity is to write
>>software in a language that uses less lines to accomplish something
>>productive.  See Paul Grahams site for a discussion.
> 
> 
> I assume you refer to "Succinctness is Power" at
>   http://www.paulgraham.com/power.html
> 
> It does not make as strong a case as you state here.  It argues
> that "succintness == power" but doesn't make any statement
> about how much more succinct Lisp is over Python.  He doesn't
> like Paul Prescod's statement, but there's nothing to say that
> Python can't be both easier to read and more succinct.  (I am
> not making that claim, only pointing out that that essay is pure
> commentary.)
> 
> Note also that it says nothing about group productivity.
> If it takes me 5% longer to write a program in language X
> then language Y, but where I can more easily use code and
> libraries developed by others then it might be a good choice
> for me to use a slightly less succinct language.
> 
> Why don't people use APL/J/K with it's succinctness?
> 
> I also disagree with Graham's statement:
> 
>>the most accurate measure of the relative power of
>>programming languages might be the percentage of
>>people who know the language who will take any job
>>where they get to use that language, regardless of the
>>application domain.
> 
> 
> I develop software for computational life sciences.  I would
> do so in Perl, C++, Java, even Javascript because I find
> the domain to be very interesting.  I would need to be very
> low on money to work in, say, accounting software, even if
> I had the choice of using Python.
> 
> 
> 
>>You are saying that Python and Perl are similarly compact?!?
>>You have got to be kidding right?
>>Perl is *far* more compact than Python is.  That is just ludicrous.
> 
> 
> Yes.  In this I have a large body of expertise by which to compare
> things.  Perl dominates bioinformatics sofware development, and the
> equivalent Python code is quite comparable in side -- I argue that
> Python is easier to understand, but it's still about the same size.
> 
> 
>>It's always nice just to chuck some arbitrary table into the
>>conversation which conveniently backs some poitn you were trying to
>>make, and also conveniently can't be located for anyone to check the
>>methodology.
> 
> 
> "Can't be located"!?!?!  I gave a full reference to the secondary material,
> included the full quote (with no trimming to bias the table more my way),
> gave the context to describe the headings, and gave you a reference
> to the primary source!  And I made every reasonable effort to find both
> sources online.
> 
> Since you can't be suggesting that I tracked down and destroyed
> every copy of McConnell's book and of the primary literature (to make
> it truely unlocatable) then what's your real complaint?  That things exist
> in the world which aren't accessible via the web?  And how is that my
> fault?
> 
> 
>>If you want some real world numbers on program length check here:
>>http://www.bagley.org/~doug/shootout/
> 
> 
> If I want some real world numbers on program length, I do it myself:
>   http://pleac.sourceforge.net/
> I wrote most of the Python code there
> 
> Still, since you insist, I went to the scorecard page and changed
> the weights to give LOC a multipler of 1 and the others a multiplier
> of 0.  This is your definition of succinctness, yes?  This table
> is sorted (I think) by least LOC to most.
> 
>             SCORES
> Language Implementation Score Missing
> Ocaml       ocaml        584     0
> Ocaml       ocamlb       584     0
> Ruby        ruby         582     0
> Scheme      guile        578     0
> Python      python       559     0
> Pike        pike         556     0
> Perl        perl         556     0
> Common Lisp cmucl        514     0
> Scheme      bigloo       506     1
> Lua         lua          492     2
> Tcl         tcl          478     3
> Java        java         468     0
> Awk         mawk         457     6
> Awk         gawk         457     6
> Forth       gforth       449     2
> Icon        icon         437     7
> C++         g++          435     0
> Lisp        rep          427     3
> Haskell     ghc          413     5
> Javascript  njs          396     5
> Erlang      erlang       369     8
> PHP         php          347     9
> Emacs Lisp  xemacs       331     9
> C           gcc          315     0
> SML         mlton        284     0
> Mercury     mercury      273     8
> Bash        bash         264     14
> Forth       bigforth     264     10
> SML         smlnj        256     0
> Eiffel      se           193     4
> Scheme      stalin       131     17
> 
> So:
>   - Why aren't you using Ocaml?
>   - Why is Scheme at the top *and* bottom of the list?
>   - Python is right up there with the Lisp/Scheme languages
>   -  ... and with Perl.
> 
> Isn't that conclusion in contradiction to your statements
> that 1) "Perl is *far* more compact than Python is" and 2)
> the implicit one that Lisp is significantly more succinct than
> Python?  (As you say, these are small projects .. but you did
> point out this site so implied it had some relevance.)
> 
> 
>>I just don't buy these numbers or the chart from Mcconell on faith.  I
>>would have to see his methodolgy, and understand what his motivation in
>>conducting the test was.
> 
> 
> I invite you to dig up the original paper (which wasn't McConnell)
> and enlighten us.  Until then, I am as free to agree with McConnell --
> more so because his book is quite good and comprehensive with
> sound arguments comparing and contrasting the different
> approaches and with no strong hidden agenda that I can detect.
> 
> 
>>It still wasn't relevant to Macros.  However, because neither of you
>>understand Macros, you of course think it is relevant.
> 
> 
> My lack of knowledge not withstanding, the question I pose to
> you is, in three parts:
>   - is it possible for a language feature to make a single programmer
>        more expressive/powerful while hindering group projects?
Yes I believe this to be the case.  However in my own experience even 
working with language such as Visual Basic and Java (which are far less 
expressive than Python), people give me code that is so obfuscated that 
is could compete in the Perl contenst.

In my experience, it hasn't been expressiveness per se that caused the 
most problems.  It has been lack of familiarity with sound software 
engineering concepts, or more specific lack of experience building real 
world applications.

So the short answer, is that *any* operator / feature used incorrectly 
can cause massive confusion.  I've seen this with simple operators such 
as loop (ever seen seven nested loops doing different things at 
different levels?  It's can be ugly)
>   - can you list three examples of situations where that's occured?
Hmm, does everythime I've read someone elses code count? ;)
In seriousness, I have yet to be on any serious project where someone 
doesn't do something that I disagree with.  Personally though, I haven't 
run across a problem where a cleanly implemented abstraction (ie class, 
macro, HOF or metaclass) has caused a loss of productivity.  In my 
experience it has been quite the opposite.

Most of the development teams that I've worked on have gravitated 
towards two groups.  Those who write utilities and substrates for the 
development framework, and those who consume them.  This has happened 
even if not specified by management, simply because those with the 
ability to write reusable abstractions end up doing it a lot.  I have 
personally seen on numerous occaisions development speed up greatly when 
the proper high level constructs were in place.

>   - can you list one example where the increased flexibility was, in
>        general, a bad idea?  That is, was there a language which would
>        have been better without a language feature.
I don't necessarily believe that to be the case.  Certainly I can list 
cases where utilizing a certain feature for a certain problem has been a 
bad idea.  That doesn't general to the language would be better without 
the feature though.  For that to be the case, IMO, there would have to 
be *no* redeaming value to the feature, or it's use would have to be so 
massively problematic that it nearly always causes problems.

I can't think of any feature off hand where I would say "take it out of 
the language, that's just stupid".  Perhaps there are some, and I'm just 
missing them while I'm thinking about it.

One example of mis-use that caused some serious headaches:
Back in 1999 I was lead on a team building a heavy duty enterprise web 
application.  Management decided that our best choice was to use Visual 
Basic and MTS.  The system had to be scalable, it had to be extremely 
fault tolerant and it had to be very flexible.  The architecture 
initially decided upon was to have three web servers, two application 
servers and a fully fault tolerant sql server.

Based on the initial reports from MS we decided to test DCOM from the 
web servers to the application servers (remember when that was the big 
fad?).  We quickly found out that our performance was terrible, and 
couldn't scale to support our minimum required users.  Switching things 
around we re-configured and went with five web servers each running the 
MTS components locally.

Another problem we ran into was that we decided to test out the XML 
hype.  All of our messaging between objects and between systems was sent 
via XML payloads.  This turned out to be extremely slow, and we ended up 
ripping out most of the XML messaging guts in order to spead up the system.

We also encountered serious problems with people not knowing how to 
efficiently utilize a SQL Server.  For instance they would get a 
recordset from each table (rather than joining) and then loop through 
each recordset comparing the values and constructing their resultset. 
Rewriting the queries to properly utilize joins and where clauses 
yielded several orders of magnitude performance increases.
> 
> Note that I did not at all make reference to macros.  Your statements
> to date suggest that your answer to the first is "no."
> 
That's not exactly my position, rather my position is that just about 
anything can and will be abused in some way shape or fashion.  It's a 
simple fact of working in teams.  However I would rather err on the side 
of abstractability and re-usability than on the side of forced restrictions.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <j0jhb.4393$dn6.1352@newsread4.news.pas.earthlink.net>
Me:
> > Note that I did not at all make reference to macros.  Your statements
> > to date suggest that your answer to the first is "no."

Doug Tolton:
> That's not exactly my position, rather my position is that just about
> anything can and will be abused in some way shape or fashion.  It's a
> simple fact of working in teams.  However I would rather err on the side
> of abstractability and re-usability than on the side of forced
restrictions.

You are correct.  I misremembered "Tolton" as "Tilton" and confused
you with someone else.  *blush*

My answer, btw, that the macro preprocessor in C is something
which is useful and too easily prone to misuse.  Eg, my original
C book was "C for native speakers of Pascal" and included in
the first section a set of macros like

#define BEGIN {
#define END }

It's not possible to get rid of cpp for C because the language
is too weak, but it is something which takes hard experience to
learn when not to use.

As for a language feature which should never be used.  Alex Martelli
gave an example of changing the default definition for == between
floats, which broke other packages, and my favorite is "OPTION
BASE 1" in BASIC or its equivalent in Perl and other langauges.
That is, on a per-program (or even per-module) basis, redefine
the 0 point offset for an array.

                    Andrew
                    ·····@dalkescientific.com
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F85C65A.3080202@nospam.com>
Andrew Dalke wrote:

> Me:
> 
>>>Note that I did not at all make reference to macros.  Your statements
>>>to date suggest that your answer to the first is "no."
> 
> 
> Doug Tolton:
> 
>>That's not exactly my position, rather my position is that just about
>>anything can and will be abused in some way shape or fashion.  It's a
>>simple fact of working in teams.  However I would rather err on the side
>>of abstractability and re-usability than on the side of forced
> 
> restrictions.
> 
> You are correct.  I misremembered "Tolton" as "Tilton" and confused
> you with someone else.  *blush*

Heh, yeah I've noticed that a couple of times.  Poor Kenny keeps getting 
blamed for things I've said.  D'oh!
> 
> My answer, btw, that the macro preprocessor in C is something
> which is useful and too easily prone to misuse.  Eg, my original
> C book was "C for native speakers of Pascal" and included in
> the first section a set of macros like
> 
> #define BEGIN {
> #define END }

I agree the C macro system is constantly abused.  Then again, I haven't 
ever been a really big fan of the C macro system, primarily because even 
if it's used correctly it has always struck me as an ugly hack.  I don't 
think that's because it's overly expressive and powerful though, rather 
I think it's because of it's limitations and foreign feeling syntax.
> 
> It's not possible to get rid of cpp for C because the language
> is too weak, but it is something which takes hard experience to
> learn when not to use.
> 
> As for a language feature which should never be used.  Alex Martelli
> gave an example of changing the default definition for == between
> floats, which broke other packages, and my favorite is "OPTION
> BASE 1" in BASIC or its equivalent in Perl and other langauges.
> That is, on a per-program (or even per-module) basis, redefine
> the 0 point offset for an array.

Again, I can see setting corporate wide policies that specify if you 
change the OPTION BASE, we are going to take you out behind the shed and 
beat you silly.  I don't think the existence of OPTION BASE is a 
problem, personally I think it's when someone decides they want to 
change the OPTION BASE to 0 while everyone else is still using 1.  That 
doesn't necessarily imply that OPTION BASE is by itself and evil construct.
-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <rOWhb.266378$R32.8669424@news2.tin.it>
Doug Tolton wrote:
   ...
>> You are correct.  I misremembered "Tolton" as "Tilton" and confused
>> you with someone else.  *blush*
> 
> Heh, yeah I've noticed that a couple of times.  Poor Kenny keeps getting
> blamed for things I've said.  D'oh!

That's clearly you lispers' fault for not having "preferably only one 
obvious [i.e. widely different] way to spell your names".  (Admittedly,
in the Python world we run into similar issues with the name "Tim").


>> As for a language feature which should never be used.  Alex Martelli
>> gave an example of changing the default definition for == between
>> floats, which broke other packages, and my favorite is "OPTION
>> BASE 1" in BASIC or its equivalent in Perl and other langauges.

APL had that too (quad-IO, if I recall correctly) as well as the ability
to tweak comparison tolerance for numbers.  Eeek, to say the least.

>> That is, on a per-program (or even per-module) basis, redefine
>> the 0 point offset for an array.
> 
> Again, I can see setting corporate wide policies that specify if you
> change the OPTION BASE, we are going to take you out behind the shed and
> beat you silly.  I don't think the existence of OPTION BASE is a
> problem, personally I think it's when someone decides they want to
> change the OPTION BASE to 0 while everyone else is still using 1.  That
> doesn't necessarily imply that OPTION BASE is by itself and evil
> construct.

A third-party package is quite likely to assume SOME specific setting
of quad-IO, OPTION BASE, or other such global setting.  By providing
such global settings, therefore, the language is inherently restricting your
abilities to reuse third-party code seamlessly and in full respect of
the 'open-closed principle'.  Complicating a language to ensure that its use 
will split into mutually incompatible dialects seems truly evil to me.  In 
practice, any sufficiently complex language does in practice "get 
subsetted" by different groups using it, but at least, without global 
settings threading on each other's toes, you can still _re-use_ third party 
code (although perhaps not practically _maintain_ it, if it uses a subset
or style too different from what your own development group uses).


Alex
From: Frode Vatvedt Fjeld
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <2hismz4ijz.fsf@vserver.cs.uit.no>
"Andrew Dalke" <······@mindspring.com> writes:

> That point has been made over and over to you.  The argument is that
> expressive power for a single developer can, for a group of
> developers and especially those comprised of people with different
> skill sets and mixed expertise, reduce the overall effectiveness of
> the group.

This is true for all abstractions: Syntactic, linguistic, or
functional. Good abstractions are good, bad abstractions are bad,
regardless.

-- 
Frode Vatvedt Fjeld
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87vfqz4gdu.fsf@thalassa.informatimago.com>
"Andrew Dalke" <······@mindspring.com> writes:
> And here's Table 31-2

Sorted by statement per function point:
 
                           Statements per
Language          Level    Function Point
--------          -----    --------------
spreadsheets      ~50            6
Smalltalk (80 & V) 15           20
AWK                15           25
Perl               15           25
SAS, SPSS, etc.    10           30
Visual Basic 3     10           30
Paradox             9           35
dBase IV            9           35
Focus               8           40
Oracle              8           40
Sybase              8           40
C++                 6.5         50
Quick Basic 3       5.5         60
Lisp                5           65
Ada 83              4.5         70
Modula 2            4           80
Cobol (ANSI 85)     3.5         90
Pascal              3.5         90
GW Basic            3.25       100
Fortran 77          3          110
C                   2.5        125
Macro assembler     1.5        215
Assembler           1          320

>   Source: Adapted from data in 'Programming Languages
>                                     Table' (Jones 1995a)
> 
> 
> I'll use Perl as a proxy for Python; given that that was pre-OO
> Perl I think it's reasonable that that sets a minimum level for
> Python.  Compare the Lisp and Perl numbers
> 
> Lisp                5           65
> Perl               15           25
> 
> and the differences in "statements per function point" (which isn't
> quite "LOC per function point") is striking.  It suggests that
> Python is more than twice as concise as Lisp, so if LOC is
> used as the estimate for implementation time then it's a strong
> recommendation to use Python instead of Lisp because it
> will take less time to get the same thing done.  And I do believe
> Lisp had macros back in the mid-1990s.


Some differences in  this table look suspect to  me.  Perhaps they did
not  take into account  other important  factors, such  as the  use of
libraries.

For  example, when  I write  awk code,  I really  don't feel  like I'm
programming  in a  higher level  languange than  LISP... (and  I won't
mention perl).

Also, the ordering of Fortran  vs. C fell strange (given the libraries
I use in C and the fact that I don't use Fortran).


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Jb0hb.3454$dn6.1357@newsread4.news.pas.earthlink.net>
Pascal Bourguignon:
> Some differences in  this table look suspect to  me.  Perhaps they did
> not  take into account  other important  factors, such  as the  use of
> libraries.

Anyone here know more about the original reference?

> For  example, when  I write  awk code,  I really  don't feel  like I'm
> programming  in a  higher level  languange than  LISP... (and  I won't
> mention perl).

The specific definition of "higher level language" is the number
of assembly instructions replaced.  Eg, spreadsheets are in that
table despite not being a good general purpose programming
language.

I also suspect the numbers were taken from the analysis
of existing programs, and people would have used awk
for cases where it was appropriate.

> Also, the ordering of Fortran  vs. C fell strange (given the libraries
> I use in C and the fact that I don't use Fortran).

Hmm... You don't do scientific programming, do you.  ;)

                    Andrew
                    ·····@dalkescientific.com
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <YS0hb.59342$nU6.10019189@twister.nyc.rr.com>
Pascal Bourguignon wrote:
> "Andrew Dalke" <······@mindspring.com> writes:
> 
>>And here's Table 31-2
> 
> 
> Sorted by statement per function point:
>  
>                            Statements per
> Language          Level    Function Point
> --------          -----    --------------
> spreadsheets      ~50            6

OK, this where Cells would fall, they are spreadsheets for objects.

:)

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm1slu$ndr$1@newsreader2.netcologne.de>
Andrew Dalke wrote:

> Doug Tolton:
> 
>>I believe the crux of our difference is that you don't want to give
>>expressive power because you believe it will be misused.  I on the
>>other hand want to give expressive power because I believe it could be
>>used correctly most of the time.  For the times when it's not, well
>>that's why I have debugging skills.  Sadly not eveyone uses looping
>>the way I would, but using my brain I can figure out what they are
>>doing.
> 
> 
> That point has been made over and over to you.  The argument is
> that expressive power for a single developer can, for a group of
> developers and especially those comprised of people with different
> skill sets and mixed expertise, reduce the overall effectiveness of the
> group.

Do you have some empirical data and/or references that back this claim?


Pascal
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m38ynu77vb.fsf@rigel.goldenthreadtech.com>
"Andrew Dalke" <······@mindspring.com> writes:

> The tricky thing about using McConnell's book is the implications
> of table 31-2 in the section "Using Rapid Development Languages",

This thing has been debunked for years.  No one with a clue takes it
seriously.  Even the author(s) indicate that much of it is based on
subjective guesses.

/Jon
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <j0jhb.4394$dn6.304@newsread4.news.pas.earthlink.net>
Jon S. Anthony:
> This thing has been debunked for years.  No one with a clue takes it
> seriously.  Even the author(s) indicate that much of it is based on
> subjective guesses.

Do you have a reference?  And a pointer to something better?

The only one better I know is
  http://www.ipd.uka.de/~prechelt/Biblio/jccpprtTR.pdf

which on page 23, Fig. 17, has a mapping from median
work time actual to work time w.r.t the language list.

Of the 6 languages there are two major misorderings.
First, C actually ended up easier to use than Java or C++.
(which is strange since you would think C++ would be
at least as good as C), and second, Tcl actually ends up
much better.

2 of 6 is better than random, so Jones' work can't be
complete bunkum.

                    Andrew
                    ·····@dalkescientific.com
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3brsq5ca5.fsf@rigel.goldenthreadtech.com>
"Andrew Dalke" <······@mindspring.com> writes:

> Jon S. Anthony:
> > This thing has been debunked for years.  No one with a clue takes it
> > seriously.  Even the author(s) indicate that much of it is based on
> > subjective guesses.
> 
> Do you have a reference?  And a pointer to something better?

Even nothing is better than misinformation.

> 2 of 6 is better than random, so Jones' work can't be
> complete bunkum.

2 of 6 is worse than flipping a coin.

/Jon
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Frphb.4787$dn6.2402@newsread4.news.pas.earthlink.net>
Me:
> > 2 of 6 is better than random, so Jones' work can't be
> > complete bunkum.

Jon S. Anthony:
> 2 of 6 is worse than flipping a coin.

Since I said "Of the 6 languages there are two major misorderings"
I suspect this discussion has reached the point of weariness.

Nevertheless, the ordering is 1 3 5 6 2 4

Assume a cost metric based on simple transpositions, where
neighbors can be exchanged.  This is the familiar interchange
(or Shell, or bubble, or ..) sort.  The degree of disorder is
the number of exchanges needed to sort the list.  For the
above it is ||{2-6, 2-5, 2-3, 4-6, 4-5}|| = 5

The average number of exchanges needed to sort a randomly
arranged list with the Shell sort is N*(N-1)/4 == 7.5 for
this list of size 6, so it's already better than average.

 From Knuth, Searching and Sorting, 5.1.1, Table 1, the
distribution of the number of permutations with k inversions
of a list of length 6 is
   1 way to be ordered
   5 to have one transpositions to be ordered
 14 to be off by 2 transpositions
 29
 49
 71
 90
101
101
 90
 71
 49
 29
 14
   5
   1 to be completely reversed

Thus there are 720 possible random orderings of a list of
size 6 and only 169 ways to be off by 5 or fewer transpositions.
meaning that there is only a 24% chance of being this good
randomly.

If I understand 5.1.1(13) well enough, the variance is
sqrt(6*(2*6+5)*(6-1)/72) == 2.66 which means we're
right on the 1 sigma threshold, or about a 75% chance
that his table was not randomly generated.

Again, this suggests Jones' work can't be complete
bunkum.

                    Andrew
                    ·····@dalkescientific.com
P.S.
  That's the first time in 5 years I've had to pull out Knuth.  ;)
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <RYqhb.28663$pv6.18893@twister.nyc.rr.com>
Andrew Dalke wrote:
> Me:
> 
>>>2 of 6 is better than random, so Jones' work can't be
>>>complete bunkum.
> 
> 
> Jon S. Anthony:
> 
>>2 of 6 is worse than flipping a coin.
> 
> 
> Since I said "Of the 6 languages there are two major misorderings"
> I suspect this discussion has reached the point of weariness.
> 
> Nevertheless, the ordering is 1 3 5 6 2 4
> 
> Assume a cost metric based on simple transpositions, where
> neighbors can be exchanged.  This is the familiar interchange
> (or Shell, or bubble, or ..) sort.  The degree of disorder is
> the number of exchanges needed to sort the list.  For the
> above it is ||{2-6, 2-5, 2-3, 4-6, 4-5}|| = 5
> 
> The average number of exchanges needed to sort a randomly
> arranged list with the Shell sort is N*(N-1)/4 == 7.5 for
> this list of size 6, so it's already better than average.
> 
>  From Knuth, Searching and Sorting, 5.1.1, Table 1, the
> distribution of the number of permutations with k inversions
> of a list of length 6 is
>    1 way to be ordered
>    5 to have one transpositions to be ordered
>  14 to be off by 2 transpositions
>  29
>  49
>  71
>  90
> 101
> 101
>  90
>  71
>  49
>  29
>  14
>    5
>    1 to be completely reversed
> 
> Thus there are 720 possible random orderings of a list of
> size 6 and only 169 ways to be off by 5 or fewer transpositions.
> meaning that there is only a 24% chance of being this good
> randomly.
> 
> If I understand 5.1.1(13) well enough, the variance is
> sqrt(6*(2*6+5)*(6-1)/72) == 2.66 which means we're
> right on the 1 sigma threshold, or about a 75% chance
> that his table was not randomly generated.
> 
> Again, this suggests Jones' work can't be complete
> bunkum.

I can see why you like studies. They are so much more malleable than 
peoples' reports of their experience. With numbers you can say things 
like "there is only a 25% chance I got this off a ouija (sp?) board" and 
it sounds good! I think the tobacco companies can use you, they're 
losing ground fast. Your research bureau can have the tag line "Our Data 
Guaranteed Not /Completely/ Random!"


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7YXhb.266744$R32.8680675@news2.tin.it>
Andrew Dalke wrote:
   ...
> Of the 6 languages there are two major misorderings.
> First, C actually ended up easier to use than Java or C++.
> (which is strange since you would think C++ would be
> at least as good as C), and second, Tcl actually ends up
> much better.

Personally, I'm not surprised that, for a sufficiently simple
problem, C's simplicity makes its users more productive
than the users of (particularly) C++ in all of its glory.  Sure,
the C solution might have been adopted in C++, but once
having gone to the trouble to learn a 10-times-bigger language,
the temptation is obvious to strive and find ways use SOME of
those extra 9 helpings, no?-)


Alex
From: Frode Vatvedt Fjeld
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <2hy8w188h3.fsf@vserver.cs.uit.no>
Alex Martelli <·····@aleax.it> writes:

> Good summary: if you fancy yourself as a language designer, go for
> Lisp; if you prefer to use a language designed by somebody else,
> without you _or any of the dozens of people working with you on the
> same project_ being able to CHANGE the language, go for Python.

I believe it is very unfortunate to view lisp macros as something that
is used to "change the language". Macros allow syntactic abstraction
the same way functions allow functional abstraction, and is almost as
important a part of the programmer's toolchest. While macros _can_ be
used to change the language in the sense of writing your own
general-purpose iteration construct or conditional operator, I believe
this is an abuse of macros, precisely because of the implications this
has for the readability of the code and for the language's user
community.

-- 
Frode Vatvedt Fjeld
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8yo1gdab.fsf@comcast.net>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> Alex Martelli <·····@aleax.it> writes:
>
>> Good summary: if you fancy yourself as a language designer, go for
>> Lisp; if you prefer to use a language designed by somebody else,
>> without you _or any of the dozens of people working with you on the
>> same project_ being able to CHANGE the language, go for Python.
>
> I believe it is very unfortunate to view lisp macros as something that
> is used to "change the language".  Macros allow syntactic abstraction
> the same way functions allow functional abstraction, and is almost as
> important a part of the programmer's toolchest.  While macros _can_ be
> used to change the language in the sense of writing your own
> general-purpose iteration construct or conditional operator, I believe
> this is an abuse of macros, precisely because of the implications this
> has for the readability of the code and for the language's user
> community.

But syntactic abstractions *are* a change to the language, it just
sounds fancier.  

I agree that injudicious use of macros can destroy the readability of
code, but judicious use can greatly increase the readability.  So
while it is probably a bad idea to write COND1 that assumes
alternating test and consequence forms, it is also a bad idea to
replicate boilerplate code because you are eschewing macros.
 
From: Frode Vatvedt Fjeld
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <2hsmm894e4.fsf@vserver.cs.uit.no>
·············@comcast.net writes:

> But syntactic abstractions *are* a change to the language, it just
> sounds fancier.

Yes, this is obviously true. Functional abstractions also change the
language, even if it's in a slightly different way. Any programming
language is, after all, a set of functional and syntactic
abstractions.

> I agree that injudicious use of macros can destroy the readability
> of code, but judicious use can greatly increase the readability.  So
> while it is probably a bad idea to write COND1 that assumes
> alternating test and consequence forms, it is also a bad idea to
> replicate boilerplate code because you are eschewing macros.

I suppose this is about the same differentiantion I wanted to make by
the terms "syntactic abstraction" (stressing the idea of building a
syntax that matches a particular problem area or programming pattern),
and "changing the language" which is just that, not being part of any
particular abstraction other than the programming language itself.

-- 
Frode Vatvedt Fjeld
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwl9j2y43seq94@news.nscp.aoltw.net>
On Sat, 04 Oct 2003 16:48:00 GMT, <·············@comcast.net> wrote:
> I agree that injudicious use of macros can destroy the readability of
> code, but judicious use can greatly increase the readability.  So
> while it is probably a bad idea to write COND1 that assumes
> alternating test and consequence forms, it is also a bad idea to
> replicate boilerplate code because you are eschewing macros.

But it may also be a mistake to use macros for the boilerplate code when
what you really need is a higher-order function...

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <brsuo3ug.fsf@ccs.neu.edu>
David Rush <·····@aol.net> writes:

> On Sat, 04 Oct 2003 16:48:00 GMT, <·············@comcast.net> wrote:
>> I agree that injudicious use of macros can destroy the readability of
>> code, but judicious use can greatly increase the readability.  So
>> while it is probably a bad idea to write COND1 that assumes
>> alternating test and consequence forms, it is also a bad idea to
>> replicate boilerplate code because you are eschewing macros.
>
> But it may also be a mistake to use macros for the boilerplate code when
> what you really need is a higher-order function...

Certainly.

One should be willing to use the appropriate tools: higher-order
functions, syntactic abstraction, and meta-linguistic abstraction
(embedding a domain-specific `tiny language' within the host
language).  Macros come in handy for the latter two.
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <47Dfb.224825$R32.7231998@news2.tin.it>
Frode Vatvedt Fjeld wrote:

> Alex Martelli <·····@aleax.it> writes:
> 
>> Good summary: if you fancy yourself as a language designer, go for
>> Lisp; if you prefer to use a language designed by somebody else,
>> without you _or any of the dozens of people working with you on the
>> same project_ being able to CHANGE the language, go for Python.
> 
> I believe it is very unfortunate to view lisp macros as something that
> is used to "change the language". Macros allow syntactic abstraction

Maybe "enhance" can sound more positive?  An enhancement, of course,
IS a change -- and if one were to perform any change, he'd surely be
convinced it WAS going to be an enhancement.  (Whether it really
turned out to be one is another issue).

> the same way functions allow functional abstraction, and is almost as
> important a part of the programmer's toolchest. While macros _can_ be
> used to change the language in the sense of writing your own
> general-purpose iteration construct or conditional operator, I believe
> this is an abuse of macros, precisely because of the implications this
> has for the readability of the code and for the language's user
> community.

Sure, but aren't these the examples that are being presented?  Isn't
"with-collector" a general purpose iteration construct, etc?  Maybe
only _special_ purpose ones should be built with macros (if you are
right that _general_ purpose ones should not be), but the subtleness
of the distinction leaves me wondering about the practice.


Alex
From: Frode Vatvedt Fjeld
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <2hoeww930a.fsf@vserver.cs.uit.no>
Alex Martelli <·····@aleax.it> writes:

> Sure, but aren't these the examples that are being presented?  Isn't
> "with-collector" a general purpose iteration construct, etc?  Maybe
> only _special_ purpose ones should be built with macros (if you are
> right that _general_ purpose ones should not be), but the subtleness
> of the distinction leaves me wondering about the practice.

It is a subtle distinction, just like a lot of other issues in
programming are quite subtle. And I think this particular issue
deserves more attention than it has been getting (so far as I know).

As for the current practice, I know that I quite dislike code that
uses things like with-collector, and I especially dislike it when I
have to look at the macro's expansion to see what is going on, and I
know there are perfectly fine alternatives in the standard syntax. On
the other hand, I do like it when I see a macro call that reduces tens
or even hundreds of lines of code to just a few lines that make it
immediately apparent what's happening. And I know I'd never want to
use a language with anything less than lisp's macros.

-- 
Frode Vatvedt Fjeld
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwl9grkx3seq94@news.nscp.aoltw.net>
On Sat, 04 Oct 2003 17:07:12 GMT, Alex Martelli <·····@aleax.it> wrote:
> Frode Vatvedt Fjeld wrote:
>> the same way functions allow functional abstraction, and is almost as
>> important a part of the programmer's toolchest. While macros _can_ be
>> used to change the language in the sense of writing your own
>> general-purpose iteration construct or conditional operator, I believe
>> this is an abuse of macros, precisely because of the implications this
>> has for the readability of the code and for the language's user
>> community.
>
> Sure, but aren't these the examples that are being presented?  Isn't
> "with-collector" a general purpose iteration construct, etc?  Maybe
> only _special_ purpose ones should be built with macros (if you are
> right that _general_ purpose ones should not be), but the subtleness
> of the distinction leaves me wondering about the practice.

Well, this probably points up one of the major language differences between
Scheme and CL: the extent to which macrology is required. In the Scheme
world (due to the first-classness of functions primarily) you use macros
rather less frequently than you do in CL. In fact,it is a common mistake to
over-use macros (one which I have made and continue to unlearn),especially
in cases where a lexically-scoped closure will do just fine.

IMO, this is one of those areas where weakness can be strength. Syntax- 
rules
macros' enforcement of name hygiene makes a certain class of macro rather
difficult to write. I frequently find that this also shows that a closure
based solution works better. Not always mind you. I wouldn't want to do
without sexp macros in my toolkit; I'm just saying that  there are 
frequently
other mechanisms which achieve the same effect, often at a better cost.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvbrsu5pdm.fsf@famine.OCF.Berkeley.EDU>
David Rush <·····@aol.net> writes:

> On Sat, 04 Oct 2003 17:07:12 GMT, Alex Martelli <·····@aleax.it> wrote:
> > Frode Vatvedt Fjeld wrote:
> >> the same way functions allow functional abstraction, and is almost as
> >> important a part of the programmer's toolchest. While macros _can_ be
> >> used to change the language in the sense of writing your own
> >> general-purpose iteration construct or conditional operator, I believe
> >> this is an abuse of macros, precisely because of the implications this
> >> has for the readability of the code and for the language's user
> >> community.
> >
> > Sure, but aren't these the examples that are being presented?  Isn't
> > "with-collector" a general purpose iteration construct, etc?  Maybe
> > only _special_ purpose ones should be built with macros (if you are
> > right that _general_ purpose ones should not be), but the subtleness
> > of the distinction leaves me wondering about the practice.
> 
> Well, this probably points up one of the major language differences between
> Scheme and CL: the extent to which macrology is required. In the Scheme
> world (due to the first-classness of functions primarily) you use macros
> rather less frequently than you do in CL.

That makes no sense!  How are functions any less first-class in CL?  I
agree that we use macros more, and that a CL-level of macro use might
be bad Scheme style, but the reason would be a more subtle one, either
cultural or the interaction of many language design choices.  It's not
a we-have-this-you-don't kind of difference.  Just for illustrative
purposes:

  (let ((line-breaker (make-line-breaker '(#\Newline \#Return) #\Tab)))
    (call-with-open-file "foo.txt"
                         (lambda (stream)
                           (call-with-file-lines
                             line-breaker
                             (lambda (line)
                               (do-something-with line))))
                         (lambda () (print "This is the continuation!"))
                         :if-does-not-exist :create))

The above is a questionable use of some of my text-file utilities.  I
would normally write the above as:

  (progn
    (with-open-file (stream "foo.txt" :if-does-not-exist :create)
      (do-file-lines (line (stream (#\Newline #\Return))
                           :continuation-char #\Tab)
        (do-something-with line)))
    (print "Done!"))

which expands to something very similar to the functional code above.

> In fact,it is a common mistake to
> over-use macros (one which I have made and continue to unlearn),especially
> in cases where a lexically-scoped closure will do just fine.

I guess ... IMNSHO, the macro version above is much nicer.  If you
write your macros as a friendly, domain-specific syntax over the top
of a set of functional utilities, you get the best of both worlds.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <0Eygb.2$KR3.79@typhoon.nyu.edu>
David Rush wrote:
> On Sat, 04 Oct 2003 17:07:12 GMT, Alex Martelli <·····@aleax.it> wrote:
> 
>> Frode Vatvedt Fjeld wrote:
>>
>>> the same way functions allow functional abstraction, and is almost as
>>> important a part of the programmer's toolchest. While macros _can_ be
>>> used to change the language in the sense of writing your own
>>> general-purpose iteration construct or conditional operator, I believe
>>> this is an abuse of macros, precisely because of the implications this
>>> has for the readability of the code and for the language's user
>>> community.
>>
>>
>> Sure, but aren't these the examples that are being presented?  Isn't
>> "with-collector" a general purpose iteration construct, etc?  Maybe
>> only _special_ purpose ones should be built with macros (if you are
>> right that _general_ purpose ones should not be), but the subtleness
>> of the distinction leaves me wondering about the practice.
> 
> 
> Well, this probably points up one of the major language differences between
> Scheme and CL: the extent to which macrology is required. In the Scheme
> world (due to the first-classness of functions primarily)

Am I reading what I am reading? :{

Cheers
--
Marco
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3d6d77edp.fsf@rigel.goldenthreadtech.com>
David Rush <·····@aol.net> writes:

> Well, this probably points up one of the major language differences between
> Scheme and CL: the extent to which macrology is required. In the Scheme
> world (due to the first-classness of functions primarily) you use macros
> rather less frequently than you do in CL.

Your credibility just disappeared...

/Jon
From: ·····@cs.uwa.edu.au
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blr1cq$bb1$1@enyo.uwa.edu.au>
In comp.lang.functional Erann Gat <··························@jpl.nasa.gov> wrote:
:> I can't see why a LISP programmer would even want to write a macro.
: That's because you are approaching this with a fundamentally flawed
: assumption.  Macros are mainly not used to make the syntax prettier
: (though they can be used for that).  They are mainly used to add features
: to the language that cannot be added as functions.

Really? Turing-completeness and all that... I presume you mean "cannot
so easily be added as functions", but even that would surprise me.
(Unless you mean cannot be added _to_Lisp_ as functions, because I don't
know as much as I'd like to about Lisp's capabilities and limitations.)

: For example, imagine you want to be able to traverse a binary tree and do
: an operation on all of its leaves.  In Lisp you can write a macro that
: lets you write:
: (doleaves (leaf tree) ...)
: You can't do that in Python (or any other langauge).

My Lisp isn't good enough to answer this question from your code,
but isn't that equivalent to the Haskell snippet: (I'm sure
someone here is handy in both languages)

doleaves f (Leaf x)     = Leaf (f x)
doleaves f (Branch l r) = Branch (doleaves f l) (doleaves f r)

I'd be surprised if Python couldn't do the above, so maybe doleaves
is doing something more complex than it looks to me to be doing.

: Here's another example of what you can do with macros in Lisp:

: (with-collector collect
:   (do-file-lines (l some-file-name)
:     (if (some-property l) (collect l))))

: This returns a list of all the lines in a file that have some property. 

OK, that's _definitely_ just a filter: filter someproperty somefilename
Perhaps throw in a fold if you are trying to abstract "collect".

: DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
: any other way because they take variable names and code as arguments.

What does it mean to take a variable-name as an argument? How is that
different to taking a pointer? What does it mean to take "code" as an
argument? Is that different to taking a function as an argument?

-Greg
From: Marco Baringer
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <m23ce6g7ac.fsf@bese.it>
·····@cs.uwa.edu.au writes:

> Really? Turing-completeness and all that... I presume you mean "cannot
> so easily be added as functions", but even that would surprise me.

well you can pass around code full of lambdas so most macros (expect
the ones which perform hairy source transformations) can be rewritten
as functions, but that isn't the point. Macros are about saying what
you mean in terms that makes sense for your particular app.

> : Here's another example of what you can do with macros in Lisp:
>
> : (with-collector collect
> :   (do-file-lines (l some-file-name)
> :     (if (some-property l) (collect l))))
>
> : This returns a list of all the lines in a file that have some property. 
>
> OK, that's _definitely_ just a filter: filter someproperty somefilename
> Perhaps throw in a fold if you are trying to abstract "collect".

no it's not, and the proof is that it wasn't written as a filter. For
whatever reason the author of that snippet decided that the code
should be written with WITH-COLLECTOR and not as a filter, some
languages give you this option, some don't, some people think this is
a good thing, some don't.

> : DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
> : any other way because they take variable names and code as arguments.
>
> What does it mean to take a variable-name as an argument? How is that
> different to taking a pointer? What does it mean to take "code" as an
> argument? Is that different to taking a function as an argument?

You are confusing the times at which things happen. A macro is
expanded at compile time, there is no such thing as a pointer as far
as macros are concerned (more or less), macros are passed pieces of
source code in the form of lists and atoms and return _source code_ in
the form of lists and atoms. The source code is then compiled (whith
further macro expansion in need be) and finally, after the macro has
long since finished working, the code is executed.

Another trivial example:

We often see code like this:

(let ((var (foo)))
  (if var
      (do-stuff-with-var)
      (do-other-stuff)))

So write a macro called IF-BIND which allows you to write this instead:

(if-bind var (foo)
  (do-stuff-with-var)
  (do-other-stuff))

The definition for IF-BIND is simply:

(defmacro if-bind (var condition then &optional else)
  `(let ((,var ,condition))
     (if ,then ,else)))

But what if the condition form returns multiple values which we didn't
want to throw away? Well easy enough:

(defmacro if-bind (var condition then &optional else)
  (etypecase var
    (cons `(multiple-value-bind ,var ,condition
             (if ,(car var) ,then ,else)))
    (symbol `(let ((,var ,condition)) 
               (if ,var ,then ,else)))))

Notice how we use lisp to inspect the original code and decide what
code to produce depending on whether VAR is a cons or a symbol.

I could get the same effect (from an execution stand point) of if-bind
without the macro, but the source code is very different. Macros allow
me to say what I _mean_, not what the compiler wants.

If you want more examples look in Paul Graham's OnLisp
(http://www.paulgraham.com/onlisp.html) book for the chapters on
continuations or multitasking.

-- 
-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: ·····@cs.uwa.edu.au
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <blrfk2$nrv$1@enyo.uwa.edu.au>
In comp.lang.functional Marco Baringer <··@bese.it> wrote:
: ·····@cs.uwa.edu.au writes:
:> Really? Turing-completeness and all that... I presume you mean "cannot
:> so easily be added as functions", but even that would surprise me.

: well you can pass around code full of lambdas so most macros (expect
: the ones which perform hairy source transformations) can be rewritten
: as functions, but that isn't the point. Macros are about saying what
: you mean in terms that makes sense for your particular app.

OK, so in some other application, they might allow you to extend the
syntax of the language to encode some problem domain more naturally?

:> OK, that's _definitely_ just a filter:
: no it's not, and the proof is that it wasn't written as a filter.

He was saying that this could not be done in Python, but Python has
a filter function, AFAIK.

: For whatever reason the author of that snippet decided that the code
: should be written with WITH-COLLECTOR and not as a filter, some
: languages give you this option, some don't, some people think this is
: a good thing, some don't.

Naturally. I'm against extra language features unless they increase
the expressive power, but others care more for ease-of-writing and
less for ease-of-reading and -maintaining than I do.

:> : DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
:> : any other way because they take variable names and code as arguments.
:> What does it mean to take a variable-name as an argument? How is that
:> different to taking a pointer? What does it mean to take "code" as an
:> argument? Is that different to taking a function as an argument?
: You are confusing the times at which things happen. A macro is
: expanded at compile time,

OK, yep. It should have occurred to me that that was the difference.
So now the question is "what does that give you that higher-order
functions don't?".

: Another trivial example:
: <IF-BIND>

: Macros allow me to say what I _mean_, not what the compiler wants.

Interesting. It would be interesting to see an example where it allows
you to write the code in a less convoluted way, rather than the three
obfuscating (or would the non-macro Lisp versions be just as obfuscated?
I know Lisp is fine for higher-order functions, but I guess the IF-BIND
stuff might be hard without pattern-matching.) examples I've seen so far.

: If you want more examples look in Paul Graham's OnLisp
: (http://www.paulgraham.com/onlisp.html) book for the chapters on
: continuations or multitasking.

Doubtless I'll find good examples here, given the frequency I see
this site cited.

-Greg
From: Matthew Danish
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <20031006145110.GK1454@mapcar.org>
On Mon, Oct 06, 2003 at 10:19:46AM +0000, ·····@cs.uwa.edu.au wrote:
> In comp.lang.functional Marco Baringer <··@bese.it> wrote:
> : ·····@cs.uwa.edu.au writes:
> :> Really? Turing-completeness and all that... I presume you mean "cannot
> :> so easily be added as functions", but even that would surprise me.
> 
> : well you can pass around code full of lambdas so most macros (expect
> : the ones which perform hairy source transformations) can be rewritten
> : as functions, but that isn't the point. Macros are about saying what
> : you mean in terms that makes sense for your particular app.
> 
> OK, so in some other application, they might allow you to extend the
> syntax of the language to encode some problem domain more naturally?

Right.

> 
> :> OK, that's _definitely_ just a filter:
> : no it's not, and the proof is that it wasn't written as a filter.
> 
> He was saying that this could not be done in Python, but Python has
> a filter function, AFAIK.

He meant the way it was expressed.  Java can ``do'' it too, but it's not
going to look as simple.

> 
> : For whatever reason the author of that snippet decided that the code
> : should be written with WITH-COLLECTOR and not as a filter, some
> : languages give you this option, some don't, some people think this is
> : a good thing, some don't.
> 
> Naturally. I'm against extra language features unless they increase
> the expressive power, but others care more for ease-of-writing and
> less for ease-of-reading and -maintaining than I do.

Then you should like macros, because ease-of-reading and -maintaining is
precisely why I use them.  Like with functions, being able to label
common abstractions is a great maintainability boost.

You don't write ((lambda (x) ...) 1) instead of (let ((x 1)) ...), right?

> :> : DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
> :> : any other way because they take variable names and code as arguments.
> :> What does it mean to take a variable-name as an argument? How is that
> :> different to taking a pointer? What does it mean to take "code" as an
> :> argument? Is that different to taking a function as an argument?
> : You are confusing the times at which things happen. A macro is
> : expanded at compile time,
> 
> OK, yep. It should have occurred to me that that was the difference.
> So now the question is "what does that give you that higher-order
> functions don't?".
> : Another trivial example:
> : <IF-BIND>
> 
> : Macros allow me to say what I _mean_, not what the compiler wants.
> 
> Interesting. It would be interesting to see an example where it allows
> you to write the code in a less convoluted way, rather than the three
> obfuscating (or would the non-macro Lisp versions be just as obfuscated?
> I know Lisp is fine for higher-order functions, but I guess the IF-BIND
> stuff might be hard without pattern-matching.) examples I've seen so far.

Here's an example that I am currently using:

(definstruction move ((s register) (d register))
  :sources (s)
  :destinations (d)
  :template "movl `s0, `d0"
  :class-name move-instruction)

1. This expands into a 
     (defmethod make-instruction-move ((s register) (d register)) ...)
   which itself is called indirectly, but most importantly it allows the
   compiler to compile a multiple-dispatch method statically rather than
   trying to replicate that functionality at runtime (which would require
   parsing a list of parameters supplied by the &rest lambda-list keyword,
   not to mention implementing multiple-dispatch).

2. Sources and destinations can talk about variable names rather than indices
   into a sequence.  (Templates cannot because they need the extra layer of
   indirection--the source and destination lists are subject to change in
   this system currently.  Well, I suppose it could be worked out anyway,
   perhaps if I have time I will try it).

3. Originally I processed the templates at run-time, and upon profiling
   discovered that it was the most time-consuming function by far.  I modified
   the macro to process the template strings statically and produce a
   function which could be compiled with the rest of the code, and the
   overhead completely disappeared.  I can imagine a way to do this with
   functions: collect a list of functions which take the relevant values
   as arguments, then map over them and apply the results to format.
   This is less efficient because
     (a) you need to do some extra steps, which the macro side-steps by
         directly pasting the code into the proper place, and
     (b) FORMATTER is a macro which lets you compile a format string into
         a function, and this cannot be used in the functional version,
         since you cannot say (FORMATTER my-control-string) but must supply
         a string statically, as in (FORMATTER "my control string").
         Could FORMATTER be implemented functionally?  Probably, but either
         you require the use of the Lisp compiler at run-time, which is
         certainly possible though heavyweight usually, or you write a 
         custom compiler for that function.  If you haven't figured it out
         yet, Lispers like to leverage existing resources =)

4. The macro arranges all the relevant information about a machine instruction
   in a simple way that is easy to write even if you don't understand
   the underlying system.  If you know anything about assembly language,
   it is probably pretty easy to figure out what information is being encoded.


Here's another fun macro which I've been using as of yesterday afternoon,
courtesy of Far� Rideau:

(match s
  ...
  ((ir move (as temp (ir temp _)) b)
    (reorder-stm (list b)
                 (mlambda ((list b) ;; match + lambda
                           (make-ir-move temp b)))))
  ...)

MATCH performs ML/Erlang-style pattern matching with a Lispy twist: patterns
are of the form: literal, variable, or (designator ...) where designator is a
symbol specified by some defining construct.

I wrote this to act like the ML `as' [meta-?]pattern:

(define-macro-matcher as
    ;; I think this lambda should be folded into the macro, but whatever
    #'(lambda (var pat)
        (multiple-value-bind (matcher vars)
            (pattern-matcher pat)
          (values `#'(lambda (form)
                       (m%and (funcall ,matcher form)
                              (setf ,var form)))
                  (merge-matcher-variables (list vars (list var)))))))

for example, which at macro-expansion time computes the pattern-matching code
of the pat argument, adds var to the list of variables (used by MATCH), and
creates a function which first checks the pattern and then sets the supplied
(lexical) variable var to the value of the form at this point the form at this
point.  Calling PATTERN-MATCHER yourself is quite enlightening on this:

* (pattern-matcher '(as x 1))
#'(LAMBDA (FORM)
    (M%AND (FUNCALL #'(LAMBDA (#:FORM) (M%WHEN (EQL #:FORM '1))) FORM)
           (SETF X FORM)))
(X)

MATCH (really implemented in terms of IFMATCH) computes this at macro-expansion
and the Lisp statically compiles it afterwards.  Of course, MATCH could be
implemented functionally, but consider the IR matcher that
  (a) looks up the first parameter in a table (created by another macro) to
      see if it is a valid IR type and get the slot names
  (b) which are used to create slot-accessing forms that can be optimized
      by a decent CLOS implementation when the slot-name is a literal value
      (as when constructed by the macro, something a functional version
      could not do).

Not to mention that a functional version would have to look something like:

(match value
       '(pattern involving x, y, and z) #'(lambda (x y z) ...)
       ... ...)

Rather annoying, don't you think?  The variables need to be repeated.
  
The functional version would have to create some kind of structure to hold the
bound variable values and construct a list to apply the consequent function
with.  The macro version can get away with modifying lexical variables.

Also the macro version can be extended to support multiple value forms, which
in Lisp are not first-class (but more efficient than returning lists).


A third quick example:

(ir-sequence
  (make-ir-move ...)
  (make-ir-jump ...)
  ...)

Which transforms a list of values into a list-like data structure.  I wrote
this originally as a macro, because in my mind it was a static transformation.
I realized later that it could be implemented as a function, without changing
any uses, but I didn't because
  (a) I wasn't using it with higher-order functions, or situations demanding
      them.
  (b) It would now have to cons a list every call and do the transformation;
      added overhead and the only gain being that it was now a function which
      I never even used in a functional way.  Rather questionable.
  (c) I can always write a separate functional version if I need it.


Basically, this boils down to:

* Macros can do ``compile-time meta-programming'' or whatever the buzzword
  is these days, and those above are some real-life examples.
  This allows for compiler optimization and static analysis where desired.
* Macros make syntax much more convenient and less cluttered.  I really
  don't understand the people who think that macros make things harder to read.
  It is far better to have clear labelled markers in the source code rather
  than having to sort through boilerplate to figure out the intended meaning
  of code.  Just because I understand lambda calculus doesn't mean I want to 
  sort through nested lambdas just to use some functionality, every time.
  If you are afraid because you are unsure of what the macro does, or its
  complete syntax, MACROEXPAND-1 is your friend.  That, and an editor with
  some hot-keys to find source/docs/expansion/etc.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Raymond Wiker
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <861xtqjs2z.fsf@raw.grenland.fast.no>
        Another example:

        Given a set of files containing database data, I want to create

        - classes that represent (the interesting bits of) each table

        - functions that parse lines from the files, create instances
of a given class, and returns the instance along with the "primary
key" of the instance.

        The interface to this functionality is the macro

(defmacro define-record (name key args &body body)
        ...)
        
which I use like this:
        
(define-record category oid ((oid 0 integer)
			     (name 1 string)
			     (status 4 integer)
			     (deleted 5 integer)
			     (parent 9 integer)
			     active)
	       (unless (zerop deleted)
		 (return t)))

which expands into

(PROGN
 (DEFCLASS CATEGORY-CLASS
           NIL
           ((OID :INITARG :OID) (NAME :INITARG :NAME) (STATUS :INITARG :STATUS)
            (DELETED :INITARG :DELETED) (PARENT :INITARG :PARENT)
            (ACTIVE :INITARG :ACTIVE)))
 (DEFUN HANDLE-CATEGORY (#:LINE-2524)
   (WHEN #:LINE-2524
     (LET ((#:FIELDS-2525
            (SPLIT-LINE-COLLECT #:LINE-2524
                                '((0 . INTEGER) (1 . STRING) (4 . INTEGER)
                                  (5 . INTEGER) (9 . INTEGER)))))
       (WHEN #:FIELDS-2525
         (PROGV
             '(OID NAME STATUS DELETED PARENT)
             #:FIELDS-2525
           (BLOCK NIL
             (LET (ACTIVE)
               (UNLESS (ZEROP DELETED) (RETURN T))
               (VALUES OID
                       (MAKE-INSTANCE 'CATEGORY-CLASS
                                      :OID
                                      OID
                                      :NAME
                                      NAME
                                      :STATUS
                                      STATUS
                                      :DELETED
                                      DELETED
                                      :PARENT
                                      PARENT
                                      :ACTIVE
                                      ACTIVE))))))))))

        The implementation of this macro is probably not perfect (I've
learnt more about Common Lisp since I wrote it). This is OK, since I
can go back and change the innards of the macro whenever I want to :-)
Actually, this is probably something that calls for the use of MOP.

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <m33ce6wdem.fsf@javamonkey.com>
·····@cs.uwa.edu.au writes:

> In comp.lang.functional Marco Baringer <··@bese.it> wrote:

[snip]

> : You are confusing the times at which things happen. A macro is
> : expanded at compile time,
> 
> OK, yep. It should have occurred to me that that was the difference.
> So now the question is "what does that give you that higher-order
> functions don't?".

Clean syntax. That is, clean syntax that allows your code to
express--in terms of the problem at hand--what it is doing, hiding the
actual mechanics under the macro. See my example below.

> : Macros allow me to say what I _mean_, not what the compiler wants.
> 
> Interesting. It would be interesting to see an example where it allows
> you to write the code in a less convoluted way, rather than the three
> obfuscating (or would the non-macro Lisp versions be just as obfuscated?
> I know Lisp is fine for higher-order functions, but I guess the IF-BIND
> stuff might be hard without pattern-matching.) examples I've seen so far.

Okay, here's an example of a couple macros I use all the time. Since I
write a lot of unit tests, I like to have a clean syntax for
expressing the essence of a set of related tests. So I have a macro
DEFTEST which is similar to DEFUN except it defines a "test function"
which has some special characteristics. For one, all test functions
are registered with the test framework so I can run all defined tests.
And each test function binds a dynamic variable to the name of the
test currently being run which is used by the reporting framework when
reporting results. So, to write a new test function, here's what I
write:

  (deftest foo-tests ()
    (check
     (= (foo 1 2 3) 42)
     (= (foo 4 5 6) 99)))

Note that this is all about the problem domain, namely testing. Each
form within the body of the CHECK is evaluated as a separate test
case. If a given form doesn't evaluate to true then a failure is
reported like this which tells me which test function the failure was
in, the literal form of the test case and then the values of any
non-literal values is the function call (i.e. the arguments to = in
this case.)

  Test Failure:

    Test Name: (FOO-TESTS)
    Test Case: (= (FOO 1 2 3) 42)
    Values:    (FOO 1 2 3): 6


  Test Failure:

    Test Name: (FOO-TESTS)
    Test Case: (= (FOO 4 5 6) 99)
    Values:    (FOO 4 5 6): 15


So what is the equivalent non-macro code? Well the equivalent code to
the DEFTEST form (i.e. the macro expansion) is not *that* much more
complex--it just has to do the stuff I mentioned; binding the test
name variable and registering the test function. But it's complex
enough that I sure wouldn't want to have to type it over and over
again each time I write a test:

  (progn
    (defun foo-tests ()
      (let ((test::*test-name*
             (append test::*test-name* (list 'foo-tests))))
        (check
         (= (foo 1 2 3) 42)
         (= (foo 4 5 6) 99))))
    (eval-when (:compile-toplevel :load-toplevel :execute)
      (test::add-test 'foo-tests)))

But the real payoff comes when we realize that innocent looking CHECK
is also a macro. Thus to see what the *real* benefit of macros is we
need to compare the original four-line DEFTEST form to what it expands
into (i.e. what the compiler actually compiles) when all the
subsidiary macros are also expanded. Which is this:

  (progn
    (defun foo-tests ()
      (let ((test::*test-name*
             (append test::*test-name* (list 'foo-tests))))
        (let ((#:end-result356179 t))
          (tagbody
           test::retry
            (multiple-value-bind (#:result356180 #:bindings356181)
                (let ((#:g356240 (foo 1 2 3)) (#:g356241 42))
                  (values (= #:g356240 #:g356241)
                          (list (list '(foo 1 2 3) #:g356240))))
              (if #:result356180
                (signal
                 'test::test-passed
                 :test-name test::*test-name*
                 :test-case '(= (foo 1 2 3) 42)
                 :bound-values #:bindings356181)
                (restart-case 
                    (signal
                     'test::test-failed
                     :test-name test::*test-name*
                     :test-case '(= (foo 1 2 3) 42)
                     :bound-values #:bindings356181)
                  (test::skip-test-case nil)
                  (test::retry-test-case nil (go test::retry))))
              (setq #:end-result356179
                (and #:end-result356179 #:result356180))))
          (tagbody
           test::retry
            (multiple-value-bind (#:result356180 #:bindings356181)
                (let ((#:g356242 (foo 4 5 6)) (#:g356243 99))
                  (values (= #:g356242 #:g356243) 
                          (list (list '(foo 4 5 6) #:g356242))))
              (if #:result356180
                (signal
                 'test::test-passed
                 :test-name test::*test-name*
                 :test-case '(= (foo 4 5 6) 99)
                 :bound-values #:bindings356181)
                (restart-case
                    (signal
                     'test::test-failed
                     :test-name test::*test-name*
                     :test-case '(= (foo 4 5 6) 99)
                     :bound-values #:bindings356181)
                  (test::skip-test-case nil)
                  (test::retry-test-case nil (go test::retry))))
              (setq #:end-result356179
                (and #:end-result356179 #:result356180))))
          #:end-result356179)))
    (eval-when (:compile-toplevel :load-toplevel :execute)
      (test::add-test 'foo-tests)))


Note that it's the ability, at macro expansion time, to treat the code
as data that allows me to generate test failure messages that contain
the literal code of the test case *and* the value that it evaluated
to. I could certainly write a HOF version of CHECK that accepts a list
of test-case-functions:

  (defun check (test-cases)
    (dolist (case test-cases)
      (if (funcall case)
        (report-pass case)
        (report-failure case))))

which might be used like:

  (defun foo-tests ()
    (check
      (list
        #'(lambda () (= (foo 1 2 3) 42))
        #'(lambda () (= (foo 4 5 6) 99)))))


But since each test case would be an opaque function object by the
time CHECK sees it, there'd be no good option for nice reporting from
the test framework. (Of course I'm no functional programming wizard so
maybe there are other ways to do it in other languges (or even Lisp)
but for me, the test, no pun intended, is, is the thing I have to
write to define a new test function much more complex than my original
DEFTEST form?

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Avi Blackmore
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <7c1401ca.0310070116.7caa0797@posting.google.com>
Peter Seibel <·····@javamonkey.com> wrote in message news:<··············@javamonkey.com>...

[snippage]
> 
> Okay, here's an example of a couple macros I use all the time. Since I
> write a lot of unit tests, I like to have a clean syntax for
> expressing the essence of a set of related tests. So I have a macro
> DEFTEST which is similar to DEFUN except it defines a "test function"
> which has some special characteristics. For one, all test functions
> are registered with the test framework so I can run all defined tests.
> And each test function binds a dynamic variable to the name of the
> test currently being run which is used by the reporting framework when
> reporting results. So, to write a new test function, here's what I
> write:
> 
>   (deftest foo-tests ()
>     (check
>      (= (foo 1 2 3) 42)
>      (= (foo 4 5 6) 99)))

    Sweet!  So you use this for dynamic testing of code as a debugging
tool?  What other capabilities does it give you?  Can you query the
active tests, "unregister" a test that you don't want run anymore,
selectively run tests based on conditional code, etc?  It sounds like
it might be a nice framework to release.
 
[snippage]

> But the real payoff comes when we realize that innocent looking CHECK
> is also a macro. Thus to see what the *real* benefit of macros is we
> need to compare the original four-line DEFTEST form to what it expands
> into (i.e. what the compiler actually compiles) when all the
> subsidiary macros are also expanded. Which is this:
> 

[really long PROGN snipped]

> 
> 
> Note that it's the ability, at macro expansion time, to treat the code
> as data that allows me to generate test failure messages that contain
> the literal code of the test case *and* the value that it evaluated to.

    Okay, maybe you already have done so, but if not, might I suggest
that you use this example in your book?  Not only is it a wonderful
elucidation of just what macros can buy you, but it also looks like
something that would be...well, practical.  Since the point of your
book, as I understand it, is showing CL's power through useful
examples that really leverage that power, such a testing framework
would probably make for an excellent tutorial on macrology.  Of
course, I'm also really really curious to know what the DEFMACROs were
on those two examples, so I can swipe them for use in my own code. 
:-)

    I'm still something of a Lisp novice, so I kvell over how nifty
this language really is.  This DEFTEST macro of yours, I guess, is
exhibit...umm...0x80.  :-)

Avi Blackmore
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <m3y8vxrxa8.fsf@javamonkey.com>
········@cableone.net (Avi Blackmore) writes:

[comp.lang.scheme,comp.lang.functional removed]

> Peter Seibel <·····@javamonkey.com> wrote in message news:<··············@javamonkey.com>...
> 
> [snippage]
> > 
> > Okay, here's an example of a couple macros I use all the time. Since I
> > write a lot of unit tests, I like to have a clean syntax for
> > expressing the essence of a set of related tests. So I have a macro
> > DEFTEST which is similar to DEFUN except it defines a "test function"
> > which has some special characteristics. For one, all test functions
> > are registered with the test framework so I can run all defined tests.
> > And each test function binds a dynamic variable to the name of the
> > test currently being run which is used by the reporting framework when
> > reporting results. So, to write a new test function, here's what I
> > write:
> > 
> >   (deftest foo-tests ()
> >     (check
> >      (= (foo 1 2 3) 42)
> >      (= (foo 4 5 6) 99)))
> 
> Sweet! So you use this for dynamic testing of code as a debugging
> tool? What other capabilities does it give you? Can you query the
> active tests, "unregister" a test that you don't want run anymore,
> selectively run tests based on conditional code, etc?

Yup. Well in theory. I haven't gotten around to implementing all that
mostly because I haven't quite figured out the UI I want to have on
top of it. But all the information required is there.

> It sounds like it might be a nice framework to release.

I intend to, once I get this other, er, project off my plate. ;-)

> [snippage]
> 
> > But the real payoff comes when we realize that innocent looking
> > CHECK is also a macro. Thus to see what the *real* benefit of
> > macros is we need to compare the original four-line DEFTEST form
> > to what it expands into (i.e. what the compiler actually compiles)
> > when all the subsidiary macros are also expanded. Which is this:
> > 
> 
> [really long PROGN snipped]
> 
> > 
> > 
> > Note that it's the ability, at macro expansion time, to treat the
> > code as data that allows me to generate test failure messages that
> > contain the literal code of the test case *and* the value that it
> > evaluated to.
> 
> Okay, maybe you already have done so, but if not, might I suggest
> that you use this example in your book?

I'm way aheead of you. ;-) If you want a sneak preview, check out:

 <http://www.gigamonkeys.com/book/mini-practical-building-a-unit-test-framework.html>

I'm sure I'll be doing a lot more work on that chapter, and perhaps
splitting it up so I can introduce a simple test framework early in
the book and then make it more sophisticated as I introduce more
advanced language features.

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: james anderson
Subject: test frameworks [Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <3F82CDC3.510819C7@setf.de>
just as a comment from the peanut gallery: the first thought which will occur
when i see the contents entry subtitled "unit test framework", will be to
check the references to the others - eg the one p.dietz uses which derives
from the utility from the ai lab, the test harness associated with acl,
clunit, xptest, ... to see whether they are footnotes or substantial
expositions of differences - something a bit more substantial than the cliki entry.

among other things,
 - the "UI" issues, to which you alluded in your note; especially naming;
 - logistic matters - where do they live - in the source, or in isolation;
 - why don't any of them support descriptions of serious relations among
tests. for example, while xptest defines isolated groups and clunit defines
categories no tool provides a way to describe either intrinscially or
extrinsically relations - for example interdependancy, versioning,
supersesssion, system dependancy - among the tests.

even for a middling-piddling application, none of this scales well.

...

Peter Seibel wrote:
> 
> ········@cableone.net (Avi Blackmore) writes:
> 
> ...
> >
> > Okay, maybe you already have done so, but if not, might I suggest
> > that you use this example in your book?
> 
> I'm way aheead of you. ;-) If you want a sneak preview, check out:
> 
>  <http://www.gigamonkeys.com/book/mini-practical-building-a-unit-test-framework.html>
> 
> I'm sure I'll be doing a lot more work on that chapter, and perhaps
> splitting it up so I can introduce a simple test framework early in
> the book and then make it more sophisticated as I introduce more
> advanced language features.

...
From: Marco Baringer
Subject: Re: Python syntax in Lisp and Scheme (macro tangent)
Date: 
Message-ID: <m2y8vys40c.fsf@bese.it>
[just to be clear: when i say "lisp" i mean Common Lisp, when I talk
about macros I'm talking about Common Lisp's macros]

·····@cs.uwa.edu.au writes:

> : well you can pass around code full of lambdas so most macros (expect
> : the ones which perform hairy source transformations) can be rewritten
> : as functions, but that isn't the point. Macros are about saying what
> : you mean in terms that makes sense for your particular app.
>
> OK, so in some other application, they might allow you to extend the
> syntax of the language to encode some problem domain more naturally?

exactly. I'd just change the wording to make it a bit stronger:

[macros used properly] in applications allow you to extend the syntax
of the [underlying] language to encode your problem domain naturally.

> :> OK, that's _definitely_ just a filter:
> : no it's not, and the proof is that it wasn't written as a filter.
>
> He was saying that this could not be done in Python, but Python has
> a filter function, AFAIK.

so does common lisp (it's called remove-if-not), that's not the point
I was trying to make though.

What I was trying to say is that the author, having the option to
write his code via a filter or via a block of code with calls to a
collector function chose the later, in python you don't have this
option. In python you can _not_ define new control structures, you are
limited to the one's Mr. van Rossum has decided to include. The fact
that you _can_ write code using only lambda means nothing; I _could_
program in unlambda, but I don't plan on it.

This brings up another point I'd like to make: If you have macros
anyone can try new control structs and see how they work in real
code, only when a lot people use it in a lot of code do you
standardive it. Without macros you have to first allow a small group
of people decide how the structure should work and then you see how
it works "in the wild."

> : For whatever reason the author of that snippet decided that the code
> : should be written with WITH-COLLECTOR and not as a filter, some
> : languages give you this option, some don't, some people think this is
> : a good thing, some don't.
>
> Naturally. I'm against extra language features unless they increase
> the expressive power, but others care more for ease-of-writing and
> less for ease-of-reading and -maintaining than I do.

but it's not that clear cut. You can't simply prefer one over the
other, they go hand in hand. You have to decide how much you're
willing to sacrifice in one for the other. Every language feature
increases experssive power, everything that eases writing increase in
some way the difficulty of reading/maintaining, but how much weight do
you give to each arm of the scale? Do you have a meter for this? (I
don't think one exists)

Let me ask a few questions:

1) Are you willing to gain writability at the cast of having the
   readers to learn a new word? How many pages of documentation would
   you sacrifice in order to save 5 "boiler plate" statements in 20
   places in your code? 1? 0.5?

2) Would you add an "official" language feature to consolidate an
   idiom that has been around for 5 years? if it has been around for
   20 years?

2b) If your main customer has been using an idiom for 10 years would
    you ever consider modifying the language to consolidate that idiom
    in the language? If no, why?

3) Do you think that being able to mold the language to fit your
   problem is a good thing?

3b) Is this so good that it's worth the added effort of learning a new
    language feature?

> OK, yep. It should have occurred to me that that was the difference.
> So now the question is "what does that give you that higher-order
> functions don't?".

introspection.

> Interesting. It would be interesting to see an example where it allows
> you to write the code in a less convoluted way, rather than the three
> obfuscating (or would the non-macro Lisp versions be just as obfuscated?

was the code I posted obfuscated?

> I know Lisp is fine for higher-order functions, but I guess the IF-BIND
> stuff might be hard without pattern-matching.) examples I've seen so far.

(can you write a drop-in replacement for if-bind using pattern matching?)

With no documentation, no idea of what the rest of the framework does,
no idea of what app this is in, can you guess what this does?

(defaction purchase-order
  (with-session-transaction
    (unless (session.user *session*)
      (call 'login :message "You must be logged in to complete your purchase"))
    (let ((order (current-order *session*)))
      (when (order.products order)
        (call 'shipping-info :order order)))
      (dolist (service (order.services order))
        (setf (signup-infos service) (call 'sigup-info :service service)))
      (case (call 'payment-methods :order order
                  :allowed-methods (valid-payment-methods order))
        (:credit-card (call 'get-credit-card-info :order order))
        (:finance (if (user.financing user)
                      (call 'finance-handler :order order)
                      (progn
                        (call 'bad-financing-info)
                        (goto 'shopping-cart)))))
      (when (call 'confirm-order :order order)
        (if (close-out-order order)
            (call 'order-summary :order order)
            (call 'order-closing-error :order order))))
    (goto 'home-page))

It's the order purchasing page flow logic for an e-commerce site.
This single block of code controls a possibly infinite number of http
request/response interactions (at least 3) (and the evil back button),
yet reads like a linear sequence of function calls. I _could_ have
written the continuation passing style code which this block expands
to (all 200+ lines of it), but I wouldn't (trust me, I have tried).

I have written this exact same code in various languages and
frameworks (servlet/ASP/mod_perl) and this is _by far_ the
clearest.

-- 
-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: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0610030955090001@k-137-79-50-101.jpl.nasa.gov>
In article <············@enyo.uwa.edu.au>, ·····@cs.uwa.edu.au wrote:

> In comp.lang.functional Erann Gat
<··························@jpl.nasa.gov> wrote:
> :> I can't see why a LISP programmer would even want to write a macro.
> : That's because you are approaching this with a fundamentally flawed
> : assumption.  Macros are mainly not used to make the syntax prettier
> : (though they can be used for that).  They are mainly used to add features
> : to the language that cannot be added as functions.
> 
> Really? Turing-completeness and all that... I presume you mean "cannot
> so easily be added as functions", but even that would surprise me.

No, I meant what I wrote.  Turing-completeness is a red herring with
respect to a discussion of programming language features.  If it were not
then there would be no reason to program in anything other than machine
language.


> : For example, imagine you want to be able to traverse a binary tree and do
> : an operation on all of its leaves.  In Lisp you can write a macro that
> : lets you write:
> : (doleaves (leaf tree) ...)
> : You can't do that in Python (or any other langauge).
> 
> My Lisp isn't good enough to answer this question from your code,
> but isn't that equivalent to the Haskell snippet: (I'm sure
> someone here is handy in both languages)
> 
> doleaves f (Leaf x)     = Leaf (f x)
> doleaves f (Branch l r) = Branch (doleaves f l) (doleaves f r)
> 
> I'd be surprised if Python couldn't do the above, so maybe doleaves
> is doing something more complex than it looks to me to be doing.

You need to change your mode of thinking.  It is not that other languages
cannot do what doleaves does.  It is that other langauges cannot do what
doleaves does in the way that doleaves does it, specifically allowing you
to put the code of the body in-line rather than forcing you to construct a
function.

Keep in mind also that this is just a trivial example.  More sophisticated
examples don't fit well in newsgroup postings.  Come see my ILC talk for
an example of what you can do with macros in Lisp that you will find more
convincing.

> : Here's another example of what you can do with macros in Lisp:
> 
> : (with-collector collect
> :   (do-file-lines (l some-file-name)
> :     (if (some-property l) (collect l))))
> 
> : This returns a list of all the lines in a file that have some property. 
> 
> OK, that's _definitely_ just a filter: filter someproperty somefilename
> Perhaps throw in a fold if you are trying to abstract "collect".

The net effect is a filter, but again, you need to stop thinking about the
"what" and start thinking about the "how", otherwise, as I said, there's
no reason to use anything other than machine language.

> : DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
> : any other way because they take variable names and code as arguments.
> 
> What does it mean to take a variable-name as an argument? How is that
> different to taking a pointer? What does it mean to take "code" as an
> argument? Is that different to taking a function as an argument?

These questions are answered in various books.  Go seek them out and read
them.  Paul Graham's "On Lisp" is a good place to start.

E.
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-9700A3.10461306102003@news.service.uci.edu>
In article 
<···········································@k-137-79-50-101.jpl.nasa.go
v>,
 ··························@jpl.nasa.gov (Erann Gat) wrote:

> > : Here's another example of what you can do with macros in Lisp:
> > 
> > : (with-collector collect
> > :   (do-file-lines (l some-file-name)
> > :     (if (some-property l) (collect l))))
> > 
> > : This returns a list of all the lines in a file that have some property. 
> > 
> > OK, that's _definitely_ just a filter: filter someproperty somefilename
> > Perhaps throw in a fold if you are trying to abstract "collect".
> 
> The net effect is a filter, but again, you need to stop thinking about the
> "what" and start thinking about the "how", otherwise, as I said, there's
> no reason to use anything other than machine language.

Answer 1: literal translation into Python.  The closest analogue of 
with-collector etc would be Python's simple generators (yield keyword) 
and do-with-file-lines is expressed in python with a for loop.  So:

def lines_with_some_property(some_file_name):
    for l in some_file_name:
        if some_property(l):
            yield l

Your only use of macros in this example is to handle the with-collector 
syntax, which is handled in a clean macro-free way by Python's "yield".
So this is unconvincing as a demonstration of why macros are a necessary 
part of a good programming language.

Of course, with-collector could be embedded in a larger piece of code, 
while using yield forces lines_with_some_property to be a separate 
function, but modularity is good...

Answer 2: poetic translation into Python.  If I think about "how" I want 
to express this sort of filtering, I end up with something much less 
like the imperative-style code above and much more like:

[l for l in some_file_name if some_property(l)]

I have no problem with the assertion that macros are an important part 
of Lisp, but you seem to be arguing more generally that the lack of 
macros makes other languages like Python inferior because the literal 
translations of certain macro-based code are impossible or more 
cumbersome.  For the present example, even that argument fails, but more 
generally you'll have to also convince me that even a freer poetic 
translation doesn't work.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0610031219540001@k-137-79-50-101.jpl.nasa.gov>
In article <······························@news.service.uci.edu>, David
Eppstein <········@ics.uci.edu> wrote:

> In article 
> <···········································@k-137-79-50-101.jpl.nasa.go
> v>,
>  ··························@jpl.nasa.gov (Erann Gat) wrote:
> 
> > > : Here's another example of what you can do with macros in Lisp:
> > > 
> > > : (with-collector collect
> > > :   (do-file-lines (l some-file-name)
> > > :     (if (some-property l) (collect l))))
> > > 
> > > : This returns a list of all the lines in a file that have some property. 
> > > 
> > > OK, that's _definitely_ just a filter: filter someproperty somefilename
> > > Perhaps throw in a fold if you are trying to abstract "collect".
> > 
> > The net effect is a filter, but again, you need to stop thinking about the
> > "what" and start thinking about the "how", otherwise, as I said, there's
> > no reason to use anything other than machine language.
> 
> Answer 1: literal translation into Python.  The closest analogue of 
> with-collector etc would be Python's simple generators (yield keyword) 
> and do-with-file-lines is expressed in python with a for loop.  So:
> 
> def lines_with_some_property(some_file_name):
>     for l in some_file_name:
>         if some_property(l):
>             yield l

You left out the with-collector part.

But it's true that my examples are less convincing given the existence of
yield (which I had forgotten about).  But the point is that in pre-yield
Python you were stuck until the langauge designers got around to adding
it.

I'll try to come up with a more convincing short example if I find some
free time today.

E.
From: Jock Cooper
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3u16loo6f.fsf@jcooper02.sagepub.com>
··························@jpl.nasa.gov (Erann Gat) writes:

> In article <······························@news.service.uci.edu>, David
> Eppstein <········@ics.uci.edu> wrote:
> 
> > In article 
> > <···········································@k-137-79-50-101.jpl.nasa.go
> > v>,
> >  ··························@jpl.nasa.gov (Erann Gat) wrote:
> > 
> > > > : Here's another example of what you can do with macros in Lisp:
> > > > 
> > > > : (with-collector collect
> > > > :   (do-file-lines (l some-file-name)
> > > > :     (if (some-property l) (collect l))))
> > > > 
> > > > : This returns a list of all the lines in a file that have some property. 
> > > > 
> > > > OK, that's _definitely_ just a filter: filter someproperty somefilename
> > > > Perhaps throw in a fold if you are trying to abstract "collect".
> > > 
> > > The net effect is a filter, but again, you need to stop thinking about the
> > > "what" and start thinking about the "how", otherwise, as I said, there's
> > > no reason to use anything other than machine language.
> > 
> > Answer 1: literal translation into Python.  The closest analogue of 
> > with-collector etc would be Python's simple generators (yield keyword) 
> > and do-with-file-lines is expressed in python with a for loop.  So:
> > 
> > def lines_with_some_property(some_file_name):
> >     for l in some_file_name:
> >         if some_property(l):
> >             yield l
> 
> You left out the with-collector part.
> 
> But it's true that my examples are less convincing given the existence of
> yield (which I had forgotten about).  But the point is that in pre-yield
> Python you were stuck until the langauge designers got around to adding
> it.
> 
> I'll try to come up with a more convincing short example if I find some
> free time today.
> 

I'm afraid it's very hard to give any convincing examples of the
utility of macros -- as long as you are sticking to trivial examples.
On the other hand, you can't exactly post real world complex examples
of how macros saved you time and LOC (we all have em) because reader's
eyes would just glaze over.  I think macros are just another one of 
CL's features that some most people just don't get until they actually
use them.  But here's a small one:

I wrote about 60 lines worth of macro based code (including a few reader
 macros) that allows me to write things like:

(with-dbconnection
  (sql-loop-in-rows 
   "select col1, col2 from somewhere where something"
   :my-package row-var "pfx"
   ...
   ...some code...
   ...))

In the "some code" section, the result columns' values are accessed by
#!pfx-colname (eg #!pfx-col1), or directly from row-var using
#?pfx-colname (which returns the position).  Also, error handling code
can be automatically included by the macro code.  How much time and
effort (and possible bugs) has this saved me?  Well at least 60+ lines
or more of boilerplate every time I use this pattern..  Plus the expansions
for #!colname include error checks/warnings etc. -- all hidden from view.  

Jock
---
www.fractal-recursions.com
From: Daniel P. M. Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blt6b2$hrc$1@camelot.ccs.neu.edu>
Erann Gat wrote:
> [...] But the point is that in pre-yield
> Python you were stuck until the langauge designers got around to adding
> it.
> 
> I'll try to come up with a more convincing short example if I find some
> free time today.
> 

Haven't some people implemented an entire class system as one huge macro?

- Daniel
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blsbpf$i9n$1@newsreader2.netcologne.de>
David Eppstein wrote:

> In article 
> <···········································@k-137-79-50-101.jpl.nasa.go
> v>,
>  ··························@jpl.nasa.gov (Erann Gat) wrote:
> 
> 
>>>: Here's another example of what you can do with macros in Lisp:
>>>
>>>: (with-collector collect
>>>:   (do-file-lines (l some-file-name)
>>>:     (if (some-property l) (collect l))))
>>>
>>>: This returns a list of all the lines in a file that have some property. 
>>>
>>>OK, that's _definitely_ just a filter: filter someproperty somefilename
>>>Perhaps throw in a fold if you are trying to abstract "collect".
>>
>>The net effect is a filter, but again, you need to stop thinking about the
>>"what" and start thinking about the "how", otherwise, as I said, there's
>>no reason to use anything other than machine language.
> 
> 
> Answer 1: literal translation into Python.  The closest analogue of 
> with-collector etc would be Python's simple generators (yield keyword) 
> and do-with-file-lines is expressed in python with a for loop.  So:
> 
> def lines_with_some_property(some_file_name):
>     for l in some_file_name:
>         if some_property(l):
>             yield l
> 
> Your only use of macros in this example is to handle the with-collector 
> syntax, which is handled in a clean macro-free way by Python's "yield".
> So this is unconvincing as a demonstration of why macros are a necessary 
> part of a good programming language.

I don't know a lot about Python, so here is a question. Is something 
along the following lines possible in Python?

(with-collectors (collect-pos collect-neg)
   (do-file-lines (l some-file-name)
     (if (some-property l)
       (collect-pos l)
       (collect-neg l))))


I actually needed something like this in some of my code...

Pascal
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-59EA3F.11592206102003@news.service.uci.edu>
In article <············@newsreader2.netcologne.de>,
 Pascal Costanza <········@web.de> wrote:

> I don't know a lot about Python, so here is a question. Is something 
> along the following lines possible in Python?
> 
> (with-collectors (collect-pos collect-neg)
>    (do-file-lines (l some-file-name)
>      (if (some-property l)
>        (collect-pos l)
>        (collect-neg l))))
> 
> 
> I actually needed something like this in some of my code...

Not using simple generators afaik.  The easiest way would probably be to 
append into two lists:

    collect_pos = []
    collect_neg = []
    for l in some_file_name:
        if some_property(l):
            collect_pos.append(l)
        else:
            collect_neg.append(l)

If you needed to do this a lot of times you could encapsulate it into a 
function of some sort:

def posneg(filter,iter):
    results = ([],[])
    for x in iter:
        results[not filter(x)].append(x)
    return results

collect_pos,collect_neg = posneg(some_property, some_file_name)

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <dezgb.4$KR3.672@typhoon.nyu.edu>
David Eppstein wrote:

> In article <············@newsreader2.netcologne.de>,
>  Pascal Costanza <········@web.de> wrote:
> 
> 
>>I don't know a lot about Python, so here is a question. Is something 
>>along the following lines possible in Python?
>>
>>(with-collectors (collect-pos collect-neg)
>>   (do-file-lines (l some-file-name)
>>     (if (some-property l)
>>       (collect-pos l)
>>       (collect-neg l))))
>>
>>
>>I actually needed something like this in some of my code...
> 
> 
> Not using simple generators afaik.  The easiest way would probably be to 
> append into two lists:
> 
>     collect_pos = []
>     collect_neg = []
>     for l in some_file_name:
                ^^^^^^^^^^^^^^

Please be precise.  You are missing the definition of 'some_file_name'. 
  The CL macro can hide the fact that you are passing the iterator 
either a string or a structured pathname or an iterator instance.  In 
Python you have to include the definition of 'some_file_name'.

In CL the following will work (assuming that the DO-FILE-LINES CL macro 
is written correctly)

	(let ((some-file-name "/tmp/foo.txt"))
	   (with-collectors (collect-pos collect-neg)
	      (do-file-lines (l some-file-name)
	         (if (some-property l)
	            (collect-pos l)
	            (collect-neg l)))))

In Pyhton

	some_file_name = '/tmp/foo.txt'
	collect_pos = []
	collect_pos = []
	for l in some_file_name:

will happily bind 'l' to the characters in '/tmp/foo.txt'.


Cheers
--
Marco
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blu4q0$1568$1@f1node01.rhrz.uni-bonn.de>
David Eppstein wrote:
> In article <············@newsreader2.netcologne.de>,
>  Pascal Costanza <········@web.de> wrote:
> 
> 
>>I don't know a lot about Python, so here is a question. Is something 
>>along the following lines possible in Python?
>>
>>(with-collectors (collect-pos collect-neg)
>>   (do-file-lines (l some-file-name)
>>     (if (some-property l)
>>       (collect-pos l)
>>       (collect-neg l))))
>>
>>
>>I actually needed something like this in some of my code...
> 
> 
> Not using simple generators afaik.  The easiest way would probably be to 
> append into two lists:
> 
>     collect_pos = []
>     collect_neg = []
>     for l in some_file_name:
>         if some_property(l):
>             collect_pos.append(l)
>         else:
>             collect_neg.append(l)

...but this means that

collect = []
for l in some_file_name
   if some_property:
       collect.append(l)

...is another solution for the single collector case. Now we have two 
ways to do it. Isn't this supposed to be a bad sign in the context of 
Python? I am confused...

> If you needed to do this a lot of times you could encapsulate it into a 
> function of some sort:
> 
> def posneg(filter,iter):
>     results = ([],[])
>     for x in iter:
>         results[not filter(x)].append(x)
>     return results
> 
> collect_pos,collect_neg = posneg(some_property, some_file_name)

What about dealing with an arbitrary number of filters?

(defmacro predicate-collect (list &body predicates)
   (let ((collectors (mapcar (lambda (predicate)
                                (declare (ignore predicate))
                                (gensym "COLLECT"))
                             predicates))
         (collect-t (gensym "COLLECT")))
      `(with-collectors (,@collectors ,collect-t)
          (dolist (l ,list)
            (cond ,@(mapcar (lambda (predicate collector)
                              `((funcall ,predicate l) (,collector l)))
                             predicates collectors)
                  (t (,collect-t l)))))))

An example:

 > (predicate-collect '(-5 -4 -3 -2 -1 0 1 2 3 4 5)
     (function evenp)
     (lambda (n) (< n 0))
     (lambda (n) (> n 3)))
(-4 -2 0 2 4)
(-5 -3 -1)
(5)
(1 3)


I use the list collector macros by Tim Bradshaw here - see 
http://www.tfeb.org/lisp/hax.html#COLLECTING


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Hannu Kankaanp??
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <840592e1.0310070604.c737696@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<·············@f1node01.rhrz.uni-bonn.de>...
> ...but this means that
> 
> collect = []
> for l in some_file_name
>    if some_property:
>        collect.append(l)
> 
> ...is another solution for the single collector case. Now we have two 
> ways to do it. Isn't this supposed to be a bad sign in the context of 
> Python? I am confused...

It's all about what's the "correct" way to do it. In this case, it
would be

collect = [l for l in some_file_name if some_property]

And this would be expanded to the for-loop form *only* if it is needed.
Of course I can do

x = 5
x += y

Or I can do

x = 5 + y

That's not breaking against Python's principles. The latter
way is the right way.

(surely there are many debatable cases of which is the right
way, but the principle is adhered to as often as possible.
That's the best one can ever have)
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ruicnbLiaIaMQR-iU-KYvw@comcast.com>
"Pascal Costanza" <········@web.de> wrote in message
··················@f1node01.rhrz.uni-bonn.de...
> What about dealing with an arbitrary number of filters?

[macro snipped]

What about it?  Using macros for somewhat simple functions stikes me
as overkill.

> An example:
>
>  > (predicate-collect '(-5 -4 -3 -2 -1 0 1 2 3 4 5)
>      (function evenp)
>      (lambda (n) (< n 0))
>      (lambda (n) (> n 3)))
> (-4 -2 0 2 4)
> (-5 -3 -1)
> (5)
> (1 3)

In Python:

def  multisplit(seq, *preds):
    predn = len(preds)
    bins = [[] for i in range(predn+1)]
    predpends = [(p,b.append) for (p,b) in zip(preds,bins)]
    rpend = bins[predn].append
    for item in seq:
        for pred,pend in predpends:
            if pred(item):
                pend(item)
                break
        else: rpend(item)
    return bins

multisplit(range(-5,6), lambda i: not i%2, lambda i: i<0, lambda i:
i>3)

[[-4, -2, 0, 2, 4], [-5, -3, -1], [5], [1, 3]]

Terry J. Reedy
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm0r15$34g$1@newsreader2.netcologne.de>
Terry Reedy wrote:
> "Pascal Costanza" <········@web.de> wrote in message
> ··················@f1node01.rhrz.uni-bonn.de...
> 
>>What about dealing with an arbitrary number of filters?
> 
> 
> [macro snipped]
> 
> What about it?  Using macros for somewhat simple functions stikes me
> as overkill.

You're right. The use of with-collectors makes it more appropriate to 
express it as a macro, but of course, one can use a simple function when 
you don't stick to with-collectors.

> 
>>An example:
>>
>> > (predicate-collect '(-5 -4 -3 -2 -1 0 1 2 3 4 5)
>>     (function evenp)
>>     (lambda (n) (< n 0))
>>     (lambda (n) (> n 3)))
>>(-4 -2 0 2 4)
>>(-5 -3 -1)
>>(5)
>>(1 3)
> 
> 
> In Python:
> 
> def  multisplit(seq, *preds):
>     predn = len(preds)
>     bins = [[] for i in range(predn+1)]
>     predpends = [(p,b.append) for (p,b) in zip(preds,bins)]
>     rpend = bins[predn].append
>     for item in seq:
>         for pred,pend in predpends:
>             if pred(item):
>                 pend(item)
>                 break
>         else: rpend(item)
>     return bins
> 
> multisplit(range(-5,6), lambda i: not i%2, lambda i: i<0, lambda i:
> i>3)
> 
> [[-4, -2, 0, 2, 4], [-5, -3, -1], [5], [1, 3]]

For the sake of completeness, here is the Lisp version:

(defun predicate-collect (list &rest predicates)
   (let ((table (make-hash-table))
         (preds (append predicates
                        (list (constantly t)))))
     (dolist (elem list)
       (loop for pred in preds
             until (funcall pred elem)
             finally (push elem (gethash pred table))))
     (mapcar (lambda (pred)
               (nreverse (gethash pred table)))
             preds)))


? (predicate-collect
    '(-5 -4 -3 -2 -1 0 1 2 3 4 5)
    (function evenp)
    (lambda (n) (< n 0))
    (lambda (n) (> n 3)))

((-4 -2 0 2 4) (-5 -3 -1) (5) (1 3))


Pascal
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065550576.16721.python-list@python.org>
|> def posneg(filter,iter):
|>     results = ([],[])
|>     for x in iter:
|>         results[not filter(x)].append(x)
|>     return results
|> collect_pos,collect_neg = posneg(some_property, some_file_name)

Pascal Costanza <········@web.de> wrote previously:
|What about dealing with an arbitrary number of filters?

Easy enough:

    def categorize_exclusive(filters, iter):
        results = tuple([[] for _ in len(filters)])
        for x in iter:
            for n, filter in enumerate(filters):
                if filter(x):
                    results[n].append(x)
                    break
    return results

Or if you want to let things fall in multiple categories:

    def categorize_inclusive(filters, iter):
        results = tuple([[] for _ in len(filters)])
        for x in iter:
            for n, filter in enumerate(filters):
                if filter(x):
                    results[n].append(x)
    return results

Or if you want something to satisfy ALL the filters:

    def categorize_compose(filters, iter):
        results = tuple([[] for _ in len(filters)])
        for x in iter:
            results[compose(filters)(x)].append(x)
    return results

The implementation of 'compose()' is left as an exercise to readers :-).
Or you can buy my book, and read the first chapter.

Yours, David...

--
Keeping medicines from the bloodstreams of the sick; food from the bellies
of the hungry; books from the hands of the uneducated; technology from the
underdeveloped; and putting advocates of freedom in prisons.  Intellectual
property is to the 21st century what the slave trade was to the 16th.
--
Buy Text Processing in Python: http://tinyurl.com/jskh
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065550637.20363.python-list@python.org>
|> def posneg(filter,iter):
|>     results = ([],[])
|>     for x in iter:
|>         results[not filter(x)].append(x)
|>     return results
|> collect_pos,collect_neg = posneg(some_property, some_file_name)

Pascal Costanza <········@web.de> wrote previously:
|What about dealing with an arbitrary number of filters?

Easy enough:

    def categorize_exclusive(filters, iter):
        results = tuple([[] for _ in len(filters)])
        for x in iter:
            for n, filter in enumerate(filters):
                if filter(x):
                    results[n].append(x)
                    break
    return results

Or if you want to let things fall in multiple categories:

    def categorize_inclusive(filters, iter):
        results = tuple([[] for _ in len(filters)])
        for x in iter:
            for n, filter in enumerate(filters):
                if filter(x):
                    results[n].append(x)
    return results

Or if you want something to satisfy ALL the filters:

    def categorize_compose(filters, iter):
        results = tuple([[] for _ in len(filters)])
        for x in iter:
            results[compose(filters)(x)].append(x)
    return results

The implementation of 'compose()' is left as an exercise to readers :-).
Or you can buy my book, and read the first chapter.

Yours, David...

--
Keeping medicines from the bloodstreams of the sick; food from the bellies
of the hungry; books from the hands of the uneducated; technology from the
underdeveloped; and putting advocates of freedom in prisons.  Intellectual
property is to the 21st century what the slave trade was to the 16th.
--
Buy Text Processing in Python: http://tinyurl.com/jskh
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065555441.8896.python-list@python.org>
My answer sucked in a couple ways.

(1) As Bengt Ricther pointed out up-thread, I should have changed David
Eppstein's names 'filter' and 'iter' to something other than the
built-in names.

(2) The function categorize_compose() IS named correctly, but it doesn't
DO what I said it would.  If you want to fulfill ALL the filters, you
don't to compose them, but... well, 'all()' them:

|    def categorize_jointly(preds, it):
|        results = [[] for _ in len(preds)]
|        for x in it:
|            results[all(filters)(x)].append(x)
|        return results

Now if you wonder what the function 'all()' does, you could download:

    http://gnosis.cx/download/gnosis/util/combinators.py

But the relevant part is:

  from operator import mul, add, truth
  apply_each = lambda fns, args=[]: map(apply, fns, [args]*len(fns))
  bools = lambda lst: map(truth, lst)
  bool_each = lambda fns, args=[]: bools(apply_each(fns, args))
  conjoin = lambda fns, args=[]: reduce(mul, bool_each(fns, args))
  all = lambda fns: lambda arg, fns=fns: conjoin(fns, (arg,))

For 'lazy_all()', look at the link.

See, Python is Haskell in drag.

Yours, David...

--
Keeping medicines from the bloodstreams of the sick; food from the bellies
of the hungry; books from the hands of the uneducated; technology from the
underdeveloped; and putting advocates of freedom in prisons.  Intellectual
property is to the 21st century what the slave trade was to the 16th.
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8CVgb.8$KR3.1846@typhoon.nyu.edu>
David Mertz wrote:
> My answer sucked in a couple ways.
> 
> (1) As Bengt Ricther pointed out up-thread, I should have changed David
> Eppstein's names 'filter' and 'iter' to something other than the
> built-in names.
> 
> (2) The function categorize_compose() IS named correctly, but it doesn't
> DO what I said it would.  If you want to fulfill ALL the filters, you
> don't to compose them, but... well, 'all()' them:
> 
> |    def categorize_jointly(preds, it):
> |        results = [[] for _ in len(preds)]
> |        for x in it:
> |            results[all(filters)(x)].append(x)
> |        return results
> 
> Now if you wonder what the function 'all()' does, you could download:
> 
>     http://gnosis.cx/download/gnosis/util/combinators.py
> 
> But the relevant part is:
> 
>   from operator import mul, add, truth
>   apply_each = lambda fns, args=[]: map(apply, fns, [args]*len(fns))
>   bools = lambda lst: map(truth, lst)
>   bool_each = lambda fns, args=[]: bools(apply_each(fns, args))
>   conjoin = lambda fns, args=[]: reduce(mul, bool_each(fns, args))
>   all = lambda fns: lambda arg, fns=fns: conjoin(fns, (arg,))
> 
> For 'lazy_all()', look at the link.
> 
> See, Python is Haskell in drag.

Come on.  Haskell has a nice type system.  Python is an application of 
Greespun's Tenth Rule of programming.

Cheers
--
Marco




> 
> Yours, David...
> 
> --
> Keeping medicines from the bloodstreams of the sick; food from the bellies
> of the hungry; books from the hands of the uneducated; technology from the
> underdeveloped; and putting advocates of freedom in prisons.  Intellectual
> property is to the 21st century what the slave trade was to the 16th.
> 
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065643519.2023.python-list@python.org>
There's something pathological in my posting untested code.  One more
try:

    def categorize_jointly(preds, it):
        results = [[] for _ in preds]
        for x in it:
            results[all(preds)(x)].append(x)
        return results

|Come on.  Haskell has a nice type system.  Python is an application of
|Greespun's Tenth Rule of programming.

Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
does them much better, for example... and so does Python.

Yours, David...

--
 ·····@   _/_/_/_/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY:_/_/_/_/ v i
gnosis  _/_/                    Postmodern Enterprises         _/_/  s r
.cx    _/_/  MAKERS OF CHAOS....                              _/_/   i u
      _/_/_/_/_/ LOOK FOR IT IN A NEIGHBORHOOD NEAR YOU_/_/_/_/_/    g s
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Y1%gb.2569662$Bf5.354645@news.easynews.com>
David Mertz wrote:

> There's something pathological in my posting untested code.  One more
> try:
> 
>     def categorize_jointly(preds, it):
>         results = [[] for _ in preds]
>         for x in it:
>             results[all(preds)(x)].append(x)
>         return results
> 
> |Come on.  Haskell has a nice type system.  Python is an application of
> |Greespun's Tenth Rule of programming.
> 
> Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
> does them much better, for example... and so does Python.
> 
What is your basis for that statement?  I personally like the way Lisp 
does it much better, and I program in both Lisp and Python.  With Python 
  it's not immediately apparent if you are passing in a simple variable 
or a HOF.  Whereas in lisp with #' it's immediately obvious that you are 
receiving or sending a HOF that will potentially alter how the call 
operates.

IMO, that syntax is far clearner.

> Yours, David...
> 
> --
>  ·····@   _/_/_/_/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY:_/_/_/_/ v i
> gnosis  _/_/                    Postmodern Enterprises         _/_/  s r
> .cx    _/_/  MAKERS OF CHAOS....                              _/_/   i u
>       _/_/_/_/_/ LOOK FOR IT IN A NEIGHBORHOOD NEAR YOU_/_/_/_/_/    g s
> 
> 


-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <6Pfhb.190589$hE5.6425564@news1.tin.it>
Doug Tolton wrote:

> David Mertz wrote:
> 
>> There's something pathological in my posting untested code.  One more
>> try:
>> 
>>     def categorize_jointly(preds, it):
>>         results = [[] for _ in preds]
>>         for x in it:
>>             results[all(preds)(x)].append(x)
>>         return results
>> 
>> |Come on.  Haskell has a nice type system.  Python is an application of
>> |Greespun's Tenth Rule of programming.
>> 
>> Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
>> does them much better, for example... and so does Python.
>> 
> What is your basis for that statement?  I personally like the way Lisp
> does it much better, and I program in both Lisp and Python.  With Python
>   it's not immediately apparent if you are passing in a simple variable
> or a HOF.  Whereas in lisp with #' it's immediately obvious that you are
> receiving or sending a HOF that will potentially alter how the call
> operates.
> 
> IMO, that syntax is far clearner.

I think it's about a single namespace (Scheme, Python, Haskell, ...) vs
CLisp's dual namespaces.  People get used pretty fast to having every
object (whether callable or not) "first-class" -- e.g. sendable as an
argument without any need for stropping or the like.  To you, HOFs may
feel like special cases needing special syntax that toots horns and
rings bells; to people used to passing functions as arguments as a way
of living, that's as syntactically obtrusive as, say, O'CAML's mandate
that you use +. and not plain + when summing floats rather than ints
(it's been a couple years since I last studied O'CAML's, so for all I
know they may have changed that now, but, it IS in the book;-).

No doubt they could make a case that float arithmetic has potentially
weird and surprising characteristics and it's a great idea to make it
"immediately obvious" that's it in use -- and/or the case that this
allows stronger type inference and checking than SML's or Haskell's
use of plain + here allows.  Rationalization is among the main uses
for the human brain, after all -- whatever feature one likes because
of habit, one can make SOME case or other for;-).


Alex
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ismytl8h.fsf@bird.agharta.de>
[Followup-To ignored because I don't read comp.lang.python]

On Thu, 09 Oct 2003 16:13:54 GMT, Alex Martelli <·····@aleax.it> wrote:

> I think it's about a single namespace (Scheme, Python, Haskell, ...)
> vs CLisp's dual namespaces.  People get used pretty fast to having
> every object (whether callable or not) "first-class" --
> e.g. sendable as an argument without any need for stropping or the
> like.  To you, HOFs may feel like special cases needing special
> syntax that toots horns and rings bells; to people used to passing
> functions as arguments as a way of living, that's as syntactically
> obtrusive as, say, O'CAML's mandate that you use +. and not plain +
> when summing floats rather than ints

In Common Lisp (not "CLisp", that's an implementation) functions /are/
first-class and sendable as an argument "without any need for
stropping or the like." What exactly are you talking about?

Edi.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <874qyi137r.fsf@thalassa.informatimago.com>
Edi Weitz <···@agharta.de> writes:

> [Followup-To ignored because I don't read comp.lang.python]
> 
> On Thu, 09 Oct 2003 16:13:54 GMT, Alex Martelli <·····@aleax.it> wrote:
> 
> > I think it's about a single namespace (Scheme, Python, Haskell, ...)
> > vs CLisp's dual namespaces.  People get used pretty fast to having
> > every object (whether callable or not) "first-class" --
> > e.g. sendable as an argument without any need for stropping or the
> > like.  To you, HOFs may feel like special cases needing special
> > syntax that toots horns and rings bells; to people used to passing
> > functions as arguments as a way of living, that's as syntactically
> > obtrusive as, say, O'CAML's mandate that you use +. and not plain +
> > when summing floats rather than ints
> 
> In Common Lisp (not "CLisp", that's an implementation) functions /are/
> first-class and sendable as an argument "without any need for
> stropping or the like." What exactly are you talking about?

Read him.  

He's  talking  about  NAMESPACES.  "namespace"  occurs  twice  in  his
paragraph, while  "function" occurs only once, that  should have given
you a hint.

Namely, he's saying that people used to write: (mapcar cadr '((a 1) (b 2)))
don't like having to write: (mapcar #'cadr '((a 1) (b 2))) in Common-Lisp.
[ Personnaly, I rather write it as: (mapcar (function cadr) '((a 1) (b 2))) 
The less read macro the better I feel.]


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87smm2m2w9.fsf@bird.agharta.de>
On 10 Oct 2003 00:00:24 +0200, Pascal Bourguignon <····@thalassa.informatimago.com> wrote:

> Edi Weitz <···@agharta.de> writes:
> 
> > [Followup-To ignored because I don't read comp.lang.python]
> > 
> > On Thu, 09 Oct 2003 16:13:54 GMT, Alex Martelli <·····@aleax.it> wrote:
> > 
> > > I think it's about a single namespace (Scheme, Python, Haskell,
> > > ...)  vs CLisp's dual namespaces.  People get used pretty fast
> > > to having every object (whether callable or not) "first-class"
> > > -- e.g. sendable as an argument without any need for stropping
> > > or the like.  To you, HOFs may feel like special cases needing
> > > special syntax that toots horns and rings bells; to people used
> > > to passing functions as arguments as a way of living, that's as
> > > syntactically obtrusive as, say, O'CAML's mandate that you use
> > > +. and not plain + when summing floats rather than ints
> > 
> > In Common Lisp (not "CLisp", that's an implementation) functions
> > /are/ first-class and sendable as an argument "without any need
> > for stropping or the like." What exactly are you talking about?
> 
> Read him.  
> 
> He's talking about NAMESPACES.  "namespace" occurs twice in his
> paragraph, while "function" occurs only once, that should have given
> you a hint.

Thanks, I think my reading comprehension is quite good. What you said
doesn't change the fact that Mr. Martelli's wording insinuates that in
Scheme and Python functions are first-class objects and in Common Lisp
they're not. For the sake of c.l.p readers who might not know CL I
think this should be corrected.

* (let ((fn (lambda (x) (* x x))))
    (mapcar fn (list 1 2 3 4 5)))

(1 4 9 16 25)

There you have it. I can create a function, assign it to a variable
and pass it to another function like any other object, that's what I'd
call a "first-class object."

> Namely, he's saying that people used to write: (mapcar cadr '((a 1)
> (b 2))) don't like having to write: (mapcar #'cadr '((a 1) (b 2)))
> in Common-Lisp.

This old namespace debate only makes me yawn, sorry.

> [ Personnaly, I rather write it as: (mapcar (function cadr) '((a 1)
> (b 2))) The less read macro the better I feel.]

Sincere condolences... :)

Edi.
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <%LBhb.195718$hE5.6619080@news1.tin.it>
Edi Weitz wrote:
   ...
>> > > I think it's about a single namespace (Scheme, Python, Haskell,
>> > > ...)  vs CLisp's dual namespaces.  People get used pretty fast
>> > > to having every object (whether callable or not) "first-class"
>> > > -- e.g. sendable as an argument without any need for stropping
   ...
>> He's talking about NAMESPACES.  "namespace" occurs twice in his
>> paragraph, while "function" occurs only once, that should have given
>> you a hint.
> 
> Thanks, I think my reading comprehension is quite good. What you said
> doesn't change the fact that Mr. Martelli's wording insinuates that in
> Scheme and Python functions are first-class objects and in Common Lisp

I put "first class" in quotes and immediately explained what I meant.

> they're not. For the sake of c.l.p readers who might not know CL I
> think this should be corrected.
> 
> * (let ((fn (lambda (x) (* x x))))
>     (mapcar fn (list 1 2 3 4 5)))
> 
> (1 4 9 16 25)
> 
> There you have it. I can create a function, assign it to a variable
> and pass it to another function like any other object, that's what I'd
> call a "first-class object."

Yes, but:

>> Namely, he's saying that people used to write: (mapcar cadr '((a 1)
>> (b 2))) don't like having to write: (mapcar #'cadr '((a 1) (b 2)))
>> in Common-Lisp.
> 
> This old namespace debate only makes me yawn, sorry.

If so then why jump on assertions related exactly just to that --
namespaces?  Re-read my quote above, o you of self-proclaimed "quite
good" reading comprehension: I was trying to explain to Doug Tolton 
why many think that Haskell, Scheme or Python "do HOFs better",
while he was claiming that the use of #' if "far clearner" (sic)
because "in lisp with #' it's immediately obvious that you are
receiving or sending a HOF that will potentially alter how the
call operates".  I.e., it IS strictly a namespace debate from the
word go.  Whether it SHOULD be emphasized with horns and bells
that "warning, HOF coming!!!" -- as Doug claimed -- or not.

If you're bored by debating namespaces, don't jump into a debate
on namespaces -- seems simple common sense (as opposed to
common lisp?)...


Alex
From: james anderson
Subject: stropping [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F85923F.409EA48B@setf.de>
Alex Martelli wrote:
> 
> Doug Tolton wrote:
> 
> ...
> >> Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
> >> does them much better, for example... and so does Python.
> >>
> > What is your basis for that statement?  I personally like the way Lisp
> > does it much better, and I program in both Lisp and Python.  With Python
> >   it's not immediately apparent if you are passing in a simple variable
> > or a HOF.  Whereas in lisp with #' it's immediately obvious that you are
> > receiving or sending a HOF that will potentially alter how the call
> > operates.
> >
> > IMO, that syntax is far clearner.
> 
> I think it's about a single namespace (Scheme, Python, Haskell, ...) vs
> CLisp's dual namespaces.  People get used pretty fast to having every
> object (whether callable or not) "first-class" -- e.g. sendable as an
> argument without any need for stropping or the like.  To you, HOFs may
> feel like special cases needing special syntax that toots horns and
> rings bells; to people used to passing functions as arguments as a way
> of living, that's as syntactically obtrusive as, say, O'CAML's mandate
> that you use +. and not plain + when summing floats rather than ints
> (it's been a couple years since I last studied O'CAML's, so for all I
> know they may have changed that now, but, it IS in the book;-).
> 

it can't really be the #' which is so troubling.

? (defmacro define (name parameters &rest body)
  `(set (defun ,name ,parameters ,@body)
        (function ,name)))
DEFINE
? (define lof (a b) (cons a b))
#<Compiled-function LOF #x78467E6>
? (mapcar lof '(1 2 3) '(a s d))
((1 . A) (2 . S) (3 . D))
? 

what is the real issue?

...
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F85B46B.9070407@nospam.com>
Alex Martelli wrote:

> Doug Tolton wrote:
> 
> 
>>David Mertz wrote:
>>
>>
>>>There's something pathological in my posting untested code.  One more
>>>try:
>>>
>>>    def categorize_jointly(preds, it):
>>>        results = [[] for _ in preds]
>>>        for x in it:
>>>            results[all(preds)(x)].append(x)
>>>        return results
>>>
>>>|Come on.  Haskell has a nice type system.  Python is an application of
>>>|Greespun's Tenth Rule of programming.
>>>
>>>Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
>>>does them much better, for example... and so does Python.
>>>
>>
>>What is your basis for that statement?  I personally like the way Lisp
>>does it much better, and I program in both Lisp and Python.  With Python
>>  it's not immediately apparent if you are passing in a simple variable
>>or a HOF.  Whereas in lisp with #' it's immediately obvious that you are
>>receiving or sending a HOF that will potentially alter how the call
>>operates.
>>
>>IMO, that syntax is far clearner.
> 
> 
> I think it's about a single namespace (Scheme, Python, Haskell, ...) vs
> CLisp's dual namespaces.  People get used pretty fast to having every
> object (whether callable or not) "first-class" -- e.g. sendable as an
> argument without any need for stropping or the like.  To you, HOFs may
> feel like special cases needing special syntax that toots horns and
> rings bells; to people used to passing functions as arguments as a way
> of living, that's as syntactically obtrusive as, say, O'CAML's mandate
> that you use +. and not plain + when summing floats rather than ints
> (it's been a couple years since I last studied O'CAML's, so for all I
> know they may have changed that now, but, it IS in the book;-).
Yeah I'm not a big fan of +. and /. etc.  Every operation on floating 
point values has to be explicitly specified.  You can't even do a 2 +. 
3.0.  Instead you have do do (float_of_int 2) +. 3.0
I'm not a huge fan of their syntax either.  I don't think they've 
removed it, because it's in the first chapter of the tutorial on their site.

I also uses HOF's daily, and I don't generally run into problems 
specifying that a variable is in fact a function.  I like the sharp 
quote thouge because it makes it clear that something a little out of 
the ordinary is occurring.  Honestly though either way is fine with me. 
  I can see the arguments both ways.

btw CLisp is an implementation of Common Lisp.  If you want to shorten 
it, it's usually less ambiquous if you use CL.

I'm not going to comment on the dual versus single namespaces, because 
that isn't an area I'm very familiar with how Lisp operates.


-- 
Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <wbBhb.22$KR3.4841@typhoon.nyu.edu>
Ok.  At this point I feel the need to apoligize to everybody for my 
rants and I promise I will do my best to end this thread.

I therefor utter the H-word and hopefully cause this thread to stop.

Cheers
--
marco
From: Matthew Danish
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <20031014050046.GM1454@mapcar.org>
On Wed, Oct 08, 2003 at 03:59:19PM -0400, David Mertz wrote:
> |Come on.  Haskell has a nice type system.  Python is an application of
> |Greespun's Tenth Rule of programming.
> Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
> does them much better, for example... and so does Python.

Wow.  The language with the limited lambda form, whose Creator regrets
including in the language, is ... better ... at HOFs?

You must be smoking something really good.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.89.1066110046.2192.python-list@python.org>
Matthew Danish <·······@andrew.cmu.edu> wrote previously:
|On Wed, Oct 08, 2003 at 03:59:19PM -0400, David Mertz wrote:
|> |Come on.  Haskell has a nice type system.  Python is an application of
|> |Greespun's Tenth Rule of programming.
|> Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
|> does them much better, for example... and so does Python.

|Wow.  The language with the limited lambda form, whose Creator regrets
|including in the language, is ... better ... at HOFs?
|You must be smoking something really good.

I guess a much better saying than Greenspun's would be something like:
"Those who know only Lisp are doomed to repeat it (whenver they look at
another language)."  It does a better job of getting at the actual
dynamic.

People who know something about languages that are NOT Lisp know that
there is EXACTLY ZERO relation between lambda forms and HOFs. Well, OK,
I guess you couldn't have playful Y combinators if every function has a
name... but there's little loss there.

In point of fact, Python could completely eliminate the operator
'lambda', and remain exactly as useful for HOFs. Some Pythonistas seem
to want this, and it might well happen in Python3000.  It makes no
difference... the alpha and omega of HOFs is that functions are first
class objects that can be passed and returned.  Whether they happen to
have names is utterly irrelevant, anonymity is nothing special.

Haskell could probably get rid of anonymous functions even more easily.
It won't, there's no sentiment for that among Haskell programmers.  But
there is not conceptual problem in Haskell with replacing every lambda
(more nicely spelled "\" in that language) with a 'let' or 'where'.

Yours, David...

--
 ·····@  _/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY: \_\_\_\_    n o
gnosis  _/_/             Postmodern Enterprises            \_\_
.cx    _/_/                                                 \_\_  d o
      _/_/_/ IN A WORLD W/O WALLS, THERE WOULD BE NO GATES \_\_\_ z e
From: Donn Cave
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <donn-9E699D.10085714102003@nntp1.u.washington.edu>
In article <··············@mycroft.actrix.gen.nz>,
 Paul Foley <···@below.invalid> wrote:
> On Tue, 14 Oct 2003 01:26:54 -0400, David Mertz wrote:
...
>> In point of fact, Python could completely eliminate the operator
>> 'lambda', and remain exactly as useful for HOFs. Some Pythonistas seem
>> to want this, and it might well happen in Python3000.  It makes no
>> difference... the alpha and omega of HOFs is that functions are first
>> class objects that can be passed and returned.  Whether they happen to
>> have names is utterly irrelevant, anonymity is nothing special.
> 
> True enough.  Naming things is a pain though.  Imagine if you couldn't
> use numbers without naming them: e.g., if instead of 2 + 3 you had to
> do something like
> 
>   two = 2
>   three = 3
>   two + three
> 
> Bleargh!  It "makes no difference" in much the same way that using
> assembler instead of Python "makes no difference" -- you can do the
> same thing either one, but one way is enormously more painful.
> 
> [Mind you, Python's lambda is next to useless anyway]

Sure, Python is a procedural programming language with things
like "if" statements that don't play very well in the context
of a lambda body, and with a notion of identifiers, variables
and scope that doesn't favor some of the conveniences that
lambda writers enjoy in functional programming languages.  So
lambda is doomed to suffer from some limitations, and this seems
to bug some people no end.

It isn't clear that there's a real problem here, though, as
opposed to an occasion for contributing to the hot air supply
on USENET.  (Heavens, what possessed me to read any of this
thread!?)  Even if you suppose that Python programmers have
the same need for lambdas as one would in an FPL, what little
value they have is clearly in just the kind of applications
that actually work in Python anyway.  The last time this came
up in another newsgroup, I rewrote a sort of well known
snippet of Haskell (a state monad) with named functions in
place of the lamdbdas the way you always see it, and proposed
that it was easier to read that way, and if anyone came forward
to contradict me I don't recall it.  I think there is some
perverse thriftiness in most of us that makes us want to economise
on a carriage return here a name there, until our code becomes
so distilled that it's too perfect - too hard to understand.
Python is not about this kind of perfection, in my opinion.

   Donn Cave, ····@u.washington.edu
From: Dave Benjamin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbooeu0.i7b.ramen@lackingtalent.com>
In article <··························@nntp1.u.washington.edu>, Donn Cave wrote:
>
> ...to contradict me I don't recall it.  I think there is some
> perverse thriftiness in most of us that makes us want to economise
> on a carriage return here a name there, until our code becomes
> so distilled that it's too perfect - too hard to understand.
> Python is not about this kind of perfection, in my opinion.

True, but there are other reasons for anonymity besides the conservation of
character count (heh). Sometimes, you just don't know if something needs to
be reusable. Maybe YAGNI. For me, I typically go through an exploratory
phase when writing a new module where I don't name a lot of things, don't
create a lot of objects, and just try to solve a problem. I find that the
ability to toss around "thunks" helps me find a solution through
experimentation. Once the code is solid, I lift anonymous functions and
extract methods and classes where access patterns dictate the ability to
reuse and eliminate redundancy. At this point, I actually see the solution,
so I don't have to anticipate what sort of structure I'm going to need.

This is just one manner of solving problems, of course. However, it happens
to work particularly well (for me) in new domains which I lack the
experience necessary to work out a good structure in advance. With every
named object in a program comes the implicit assumption that the object will
later need to be called for by name. This goes for functions, classes, and
temporary variables.

I'm not trying to jump into the fire here, but I just wanted to illustrate
how anonynimity might be about imperfection, too. After all, you can always
repent^H^H^H^Hfactor later. =)

Peace,
Dave

-- 
.:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g   l i f e   o u t   o f   t h e   c o n t a i n e r :
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <6mWdnVM6bOIOiRGiU-KYhA@comcast.com>
"Paul Foley" <···@below.invalid> wrote in message
···················@mycroft.actrix.gen.nz...
> True enough.  Naming things is a pain though.  Imagine if you
couldn't
> use numbers without naming them: e.g., if instead of 2 + 3 you had
to
> do something like
>
>   two = 2
>   three = 3
>   two + three

For float constants in a language (such as Fortran) with multiple
float types (of different precisions), naming as part of a declaration
of precision is (or at least has been) a standard practice in some
circles.  It makes it easy to change the precision used throughout a
program.

> [Mind you, Python's lambda is next to useless anyway]

It is quite useful for its designed purpose, which is to abbreviate
and place inline short one-use function definitions of the following
pattern: def _(*params): return <expression using params>.

However, making the keyword 'lambda' instead of something like 'func'
was a mistake for at least two reasons:
1) it confuses those with no knowledge of lambda calculus and for whom
it is an strange, arbitrary term, possibly conjuring images of little
sheep, rather than being familar and mnemonic;
2) it raises unrealistic expectations in who know of 'lambda' as an
anonymous version of 'defun' (or whatever), leading them to make
statements such as the above.

Terry J. Reedy
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f8c24c6@news.sentex.net>
In article <······················@comcast.com>,
	"Terry Reedy" <·······@udel.edu> writes:
> ...
>>   two = 2
>>   three = 3
>>   two + three
> 
> For float constants in a language (such as Fortran) with multiple
> float types (of different precisions), naming as part of a declaration
> of precision is (or at least has been) a standard practice in some
> circles.  It makes it easy to change the precision used throughout a
> program.

this is a good practice when the literals are parameters that you want
to change occasionally.  other reasons why you want to do that is that
typing certain constants (e.g. pi or e) is error prone, so writing
them down once and binding them to a (descriptive) name is preferrably
to having to type them repeatedly.  but unless they play a parameter
role, binding short literals to name doesn't serve any purpose

>> [Mind you, Python's lambda is next to useless anyway]
> 
> It is quite useful for its designed purpose, which is to abbreviate
> and place inline short one-use function definitions of the following
> pattern: def _(*params): return <expression using params>.

the last version of python i used was 1.5.x, and then the absence of
closures made the anonymous functions pretty useless

> ...

hs

-- 

ceterum censeo SCO esse delendam
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yuudnZUSvvC4oBGiU-KYjA@comcast.com>
"Hartmann Schaffer" <··@heaven.nirvananet> wrote in message
·············@news.sentex.net...
> In article <······················@comcast.com>,
> "Terry Reedy" <·······@udel.edu> writes:
> > For float constants in a language (such as Fortran) with multiple
> > float types (of different precisions), naming as part of a
declaration
> > of precision is (or at least has been) a standard practice in some
> > circles.  It makes it easy to change the precision used throughout
a
> > program.
>
> this is a good practice when the literals are parameters that you
want
> to change occasionally.  other reasons why you want to do that is
that
> typing certain constants (e.g. pi or e) is error prone, so writing
> them down once and binding them to a (descriptive) name is
preferrably
> to having to type them repeatedly.  but unless they play a parameter
> role, binding short literals to name doesn't serve any purpose

My last sentence above gives a purpose, which is *the* purpose which
lead the editors of Applied Statistics to 'strongly advise' (up to
1985 at least, don't know about today) algorithm authors to "denote
all REAL constants symbolically" (A. S. Algorithms, p. 30).  I'm just
reporting, not advocating.  This in not an issue for standard Python,
which only allows access to C doubles.

> >> [Mind you, Python's lambda is next to useless anyway]
> >
> > It is quite useful for its designed purpose, which is to
abbreviate
> > and place inline short one-use function definitions of the
following
> > pattern: def _(*params): return <expression using params>.
>
> the last version of python i used was 1.5.x, and then the absence of
> closures made the anonymous functions pretty useless

The default-parameter hack which substituted for closures made lambdas
then more awkward, but I believe they were mostly just as useful as
today as callbacks and as HOF args.  In any case, closures were
introduced over two years ago in 2.1, and your original statement says
'is', not 'used to be some years ago'.

Terry J. Reedy
From: Jock Cooper
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3r81f1lu9.fsf@jcooper02.sagepub.com>
"Terry Reedy" <·······@udel.edu> writes:
> The default-parameter hack which substituted for closures made lambdas
> then more awkward, but I believe they were mostly just as useful as
> today as callbacks and as HOF args.  In any case, closures were
> introduced over two years ago in 2.1, and your original statement says
> 'is', not 'used to be some years ago'.

Isn't it true though that the lambda can only contain a single expression
and no statements?  That seems to limit closures somewhat.
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-434779.17173814102003@news.service.uci.edu>
In article <··············@jcooper02.sagepub.com>,
 Jock Cooper <·····@mail.com> wrote:

> "Terry Reedy" <·······@udel.edu> writes:
> > The default-parameter hack which substituted for closures made lambdas
> > then more awkward, but I believe they were mostly just as useful as
> > today as callbacks and as HOF args.  In any case, closures were
> > introduced over two years ago in 2.1, and your original statement says
> > 'is', not 'used to be some years ago'.
> 
> Isn't it true though that the lambda can only contain a single expression
> and no statements?  That seems to limit closures somewhat.

It limits lambdas.  It doesn't limit named functions.  Unlike lisp, a 
Python function definition can be nested within a function call, and the 
inner function can access variables in the outer function's closure.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-E717FC.17220014102003@news.service.uci.edu>
In article <······························@news.service.uci.edu>,
 David Eppstein <········@ics.uci.edu> wrote:

> > Isn't it true though that the lambda can only contain a single expression
> > and no statements?  That seems to limit closures somewhat.
> 
> It limits lambdas.  It doesn't limit named functions.  Unlike lisp, a 
> Python function definition can be nested within a function call, and the 
> inner function can access variables in the outer function's closure.

To clarify, by "unlike lisp" I meant only that defun doesn't nest (at 
least in the lisps I've programmed) -- of course you could use flet, or 
bind a variable to a lambda, or whatever.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F8C9ED9.5DB4A607@setf.de>
David Eppstein wrote:
> 
> In article <······························@news.service.uci.edu>,
>  David Eppstein <········@ics.uci.edu> wrote:
> 
> > > Isn't it true though that the lambda can only contain a single expression
> > > and no statements?  That seems to limit closures somewhat.
> >
> > It limits lambdas.  It doesn't limit named functions.  Unlike lisp, a
> > Python function definition can be nested within a function call, and the
> > inner function can access variables in the outer function's closure.
> 
> To clarify, by "unlike lisp" I meant only that defun doesn't nest (at
> least in the lisps I've programmed) -- of course you could use flet, or
> bind a variable to a lambda, or whatever.

? which lisps have you been using?

i do not observe the spec for defun
(http://www.lispworks.com/reference/HyperSpec/Body/m_defun.htm)
to place any restrictions on its context. anscillary discussion introduces the
issue of compile-time side-effects, eg whether the definition of the function
is known to exist for the purpose of error-checking, but there are no
constraints apparent to this reader on where the form may appear.

to wit


? (defun function1 (a)
    (defun function2 (b) (+ a b)))
FUNCTION1
? (function1 2)
FUNCTION2
? (function2 3)
5
? (function1 5)
FUNCTION2
? (function2 3)
8
? (defun function* (a list)
    (apply #'+ (mapcar (defun function2 (b) (+ a b)) list)))
FUNCTION*
? (function* 1 '(1 2 3))
9
? 

that is, both the invocation for side-effect and for the returned value appear
to have the intended effect. on the other hand, it's not clear why one would
want to do this, so perhaps you mean something else?

...
From: Jock Cooper
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m37k36sa1b.fsf@jcooper02.sagepub.com>
David Eppstein <········@ics.uci.edu> writes:

> In article <······························@news.service.uci.edu>,
>  David Eppstein <········@ics.uci.edu> wrote:
> 
> > > Isn't it true though that the lambda can only contain a single expression
> > > and no statements?  That seems to limit closures somewhat.
> > 
> > It limits lambdas.  It doesn't limit named functions.  Unlike lisp, a 
> > Python function definition can be nested within a function call, and the 
> > inner function can access variables in the outer function's closure.
> 
> To clarify, by "unlike lisp" I meant only that defun doesn't nest (at 
> least in the lisps I've programmed) -- of course you could use flet, or 
> bind a variable to a lambda, or whatever.
> 

Ok so in Python a function can DEF another function in its body.  I assume
this can be returned to the caller.  When you have a nested DEF like that,
is the nested function's name globally visible? 
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-BA76E3.11114115102003@news.service.uci.edu>
In article <··············@jcooper02.sagepub.com>,
 Jock Cooper <·····@mail.com> wrote:

> Ok so in Python a function can DEF another function in its body.  I assume
> this can be returned to the caller.  When you have a nested DEF like that,
> is the nested function's name globally visible? 

Not by default, but it can be made to be via an appropriate "global" 
declaration.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Jacek Generowicz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <tyfekxe32bi.fsf@pcepsft001.cern.ch>
David Eppstein <········@ics.uci.edu> writes:

> To clarify, by "unlike lisp" I meant only that defun doesn't nest

... and now you'll have to clarify what you mean by "defun doesn't
nest" ...

> of course you could use flet, or bind a variable to a lambda, or
> whatever.

Yes, you use flet (or labels) if you want a local function definition,
and defun if you want a global one. Lisp caters for both
possibilities. Does Python ?

(And by "cater" I do _not_ mean

  def foo(...):
      ...

  globals()['foo'] = foo


Now, if Python had macros ...

)
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-D98964.09503815102003@news.service.uci.edu>
In article <···············@pcepsft001.cern.ch>,
 Jacek Generowicz <················@cern.ch> wrote:

> > To clarify, by "unlike lisp" I meant only that defun doesn't nest
> 
> ... and now you'll have to clarify what you mean by "defun doesn't
> nest" ...

The context of this was in accessing closures from function defs.
Maybe you can call defun from within another function, but it won't give 
you a closure.

> > of course you could use flet, or bind a variable to a lambda, or
> > whatever.
> 
> Yes, you use flet (or labels) if you want a local function definition,
> and defun if you want a global one. Lisp caters for both
> possibilities. Does Python ?

Yes.

def outer():
   x = 3
   global inner
   def inner():
      print x

outer()
inner()

...prints 3, as expected.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Alexey Dejneka
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3y8vmz5kr.fsf@comail.ru>
David Eppstein <········@ics.uci.edu> writes:

> In article <···············@pcepsft001.cern.ch>,
>  Jacek Generowicz <················@cern.ch> wrote:
> 
> > > To clarify, by "unlike lisp" I meant only that defun doesn't nest
> > 
> > ... and now you'll have to clarify what you mean by "defun doesn't
> > nest" ...
> 
> The context of this was in accessing closures from function defs.
> Maybe you can call defun from within another function, but it won't give 
> you a closure.

Really?

* (defun outer (x)
    (defun inner ()
      x))
OUTER
* (outer 3)
INNER
* (inner)
3
* (outer 11)
STYLE-WARNING: redefining INNER in DEFUN

INNER
* (inner)
11


-- 
Regards,
Alexey Dejneka

"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-61FECD.12410715102003@news.service.uci.edu>
In article <··············@comail.ru>,
 Alexey Dejneka <········@comail.ru> wrote:

> > The context of this was in accessing closures from function defs.
> > Maybe you can call defun from within another function, but it won't give 
> > you a closure.
> 
> Really?

Apparently I was mistaken, at least for modern lisps.  I haven't 
programmed in lisp for a long time; the most recent lisp manual I can 
find at hand is a 1981 Chinual, which still seems to be using dynamic 
scoping and requires an explicit function call to create a closure.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87oewi9spr.fsf@bird.agharta.de>
On Wed, 15 Oct 2003 12:41:07 -0700, David Eppstein <········@ics.uci.edu> wrote:

> Apparently I was mistaken, at least for modern lisps.  I haven't
> programmed in lisp for a long time; the most recent lisp manual I
> can find at hand is a 1981 Chinual, which still seems to be using
> dynamic scoping and requires an explicit function call to create a
> closure.

Fair enough. But then we should compare this Lisp to the state of
Python around 1981... :)

Edi.
From: Greg Ewing (using news.cis.dfn.de)
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bn7nk4$u7cii$1@ID-169208.news.uni-berlin.de>
Jacek Generowicz wrote:
> Yes, you use flet (or labels) if you want a local function definition,
> and defun if you want a global one. Lisp caters for both
> possibilities. Does Python ?

If you mean the ability to have a nested function definition
that actually defines a top-level function, then yes, it
does...

Python 2.2 (#1, Jul 11 2002, 14:19:37)
[GCC 3.0.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
 >>> def f():
...   global g
...   def g():
...     print "Urk!"
...
 >>> g()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
NameError: name 'g' is not defined
 >>> f()
 >>> g()
Urk!
 >>>

Although I'm having a hard time imagining why you'd
actually *want* to do such a thing!

-- 
Greg Ewing, Computer Science Dept,
University of Canterbury,	
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.105.1066178851.2192.python-list@python.org>
|> Isn't it true though that the lambda can only contain a single
|> expression and no statements?  That seems to limit closures somewhat.

David Eppstein <········@ics.uci.edu> wrote previously:
|It limits lambdas.  It doesn't limit named functions.  Unlike lisp, a
|Python function definition can be nested within a function call, and the
|inner function can access variables in the outer function's closure.

I don't really know Lisp, so I could be wrong.  But my understanding is
that CL has a 'let' special form that works fine within a function
definition.  In particular, you should be able to define inner functions
by binding a name to a lambda, using 'let'.

So there's nothing really special about the fact that Python (or
Haskell, ML, etc) can nest function definition.  Of course, Haskell's
'let' and 'where' are quite wonderful... even better, syntaxwise, than
Python's nested 'def's.

Yours, David...

P.S. On the prior poster's misunderstanding:  Lambdas in Python are
actually completely general.  There is nothing you cannot express using
a single expression, even side effects--it just gets ugly doing it.
Basically, just like in CL, a list or tuple is a single expression, and
it evaluates its elements in predictable left-to-right order... you can
work out the rest of the ugly details from that fact.  Or you can look
at my articles on "FP in Python"--however, my intent in those is NOT to
enable obfuscated Python, but to point to actual useful techniques.
It's a fine line though.

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <·····@gnosis.cx> ]--------------------------
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsfzhu68qf.fsf@black132.ex.ac.uk>
·····@gnosis.cx (David Mertz) writes:

> |> Isn't it true though that the lambda can only contain a single
> |> expression and no statements?  That seems to limit closures somewhat.
> 
> David Eppstein <········@ics.uci.edu> wrote previously:
> |It limits lambdas.  It doesn't limit named functions.  Unlike lisp, a
> |Python function definition can be nested within a function call, and the
> |inner function can access variables in the outer function's closure.
> 
> I don't really know Lisp, so I could be wrong.  But my understanding is
> that CL has a 'let' special form that works fine within a function
> definition.  In particular, you should be able to define inner functions
> by binding a name to a lambda, using 'let'.

Yes David's comment only applies to ancient, non-lexically scoped lisps
(elisp is the only practical example I'm aware of).

'as
From: Björn Lindberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <hcsbrsipw9n.fsf@tjatte.nada.kth.se>
·····@gnosis.cx (David Mertz) writes:

> |> Isn't it true though that the lambda can only contain a single
> |> expression and no statements?  That seems to limit closures somewhat.
> 
> David Eppstein <········@ics.uci.edu> wrote previously:
> |It limits lambdas.  It doesn't limit named functions.  Unlike lisp, a
> |Python function definition can be nested within a function call, and the
> |inner function can access variables in the outer function's closure.
> 
> I don't really know Lisp, so I could be wrong.  But my understanding is
> that CL has a 'let' special form that works fine within a function
> definition.  In particular, you should be able to define inner functions
> by binding a name to a lambda, using 'let'.
> 
> So there's nothing really special about the fact that Python (or
> Haskell, ML, etc) can nest function definition.  Of course, Haskell's
> 'let' and 'where' are quite wonderful... even better, syntaxwise, than
> Python's nested 'def's.

It is possible (& allowed) to nest defun forms in Lisp, but it does
not achieve the same effect as nesting def:s in python. defun will
name the function in the global environment, so a nested defun will
still define a top-level function. To define a nested function local
in scope to the surrounding function, one of FLET or LABELS is used.


Bj�rn
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f8e083f@news.sentex.net>
In article <······················@comcast.com>,
	"Terry Reedy" <·······@udel.edu> writes:
> ...
>> >> [Mind you, Python's lambda is next to useless anyway]
>> >
>> > It is quite useful for its designed purpose, which is to
> abbreviate
>> > and place inline short one-use function definitions of the
> following
>> > pattern: def _(*params): return <expression using params>.
>>
>> the last version of python i used was 1.5.x, and then the absence of
>> closures made the anonymous functions pretty useless
> 
> The default-parameter hack which substituted for closures made lambdas
> then more awkward, but I believe they were mostly just as useful as
> today as callbacks and as HOF args.  In any case, closures were
> introduced over two years ago in 2.1, and your original statement says
> 'is', not 'used to be some years ago'.

maybe you should keep track of who said what.  this "original
statement was by somebody else

hs

-- 

ceterum censeo SCO esse delendam
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.97.1066151245.2192.python-list@python.org>
Paul Foley <···@below.invalid> wrote previously:
|True enough.  Naming things is a pain though.  Imagine if you couldn't
|use numbers without naming them:

This is plain idiotic.  Someone else posted it equally disingenuously
too, FWIW.

Numbers aren't functions.  Just because you can take a noun from a
sentence, and insert a different noun that changes the truth value is
REALLY not interesting.  Let's try it:

    Imagine you couldn't use MACROS without naming them
    Imagine you couldn't use MODULES without naming them
    Imagine you couldn't use KEYWORDS without naming them
    ...

If you want to suggest some ACTUAL advantage to HOFs, fine.  Do it.  But
please no annoying non-analogies.

In any case, I started my little splinter only in response to someone
who claimed that you needed lambdas to use HOFs. An obviously wrong,
and annoyingly stupid, claim.  Pointing out that Haskell or Python could
easily drop lambda, with no detriment, simply makes that point.

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <·····@gnosis.cx> ]--------------------------
From: Jacek Generowicz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <tyfismq32sh.fsf@pcepsft001.cern.ch>
·····@gnosis.cx (David Mertz) writes:

> HOFs are not a special Lisp thing.  Haskell does them much better,
> for example... and so does Python.

·····@gnosis.cx (David Mertz) writes:

> the alpha and omega of HOFs is that functions are first class
> objects that can be passed and returned.

How do you reconcile these two statements ?

[Hint: functions in Lisps are "first class objects that can be passed
and returned"; how does Python (or Haskell) do this "alpha and omega
of HOFs" "much better" ?]
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87fzhtlvni.fsf@thalassa.informatimago.com>
Jacek Generowicz <················@cern.ch> writes:

> ·····@gnosis.cx (David Mertz) writes:
> 
> > HOFs are not a special Lisp thing.  Haskell does them much better,
> > for example... and so does Python.
> 
> ·····@gnosis.cx (David Mertz) writes:
> 
> > the alpha and omega of HOFs is that functions are first class
> > objects that can be passed and returned.
> 
> How do you reconcile these two statements ?
> 
> [Hint: functions in Lisps are "first class objects that can be passed
> and returned"; how does Python (or Haskell) do this "alpha and omega
> of HOFs" "much better" ?]


Well, to be,  a first class object is an object  I can "process".  For
example, a list is a first class object:

[37]> (setq x '(a b c))
(A B C)
[42]> (setf (cadr x) 'd)
D
[43]> x
(A D C)


So, to be really a first class object, a function should let itself be
modified too:

[44]> (setq f (function (lambda (x) (+ 1 x))))
#<CLOSURE :LAMBDA (X) (+ 1 X)>

Oops, an opaque type, I can't change the body.

[46]> (setq f (lambda (x) (+ 1 x)))
#<CLOSURE :LAMBDA (X) (+ 1 X)>

No luck.

[47]> (setq f '(lambda (x) (+ 1 x)))
(LAMBDA (X) (+ 1 X))

Ok, ok, this is only a list...

[48]> (setf (second (caddr f)) 2)
2
[49]> f
(LAMBDA (X) (+ 2 X))
[50]> (funcall f 3)
*** - FUNCALL: argument (LAMBDA (X) (+ 2 X)) is not a function.

See, not a first class object...


[52]> (eval `(,f 3))
5

Ha!  My precious, precious eval...


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.135.1066277221.2192.python-list@python.org>
> the alpha and omega of HOFs is that functions are first class
> objects that can be passed and returned.

Pascal Bourguignon <····@thalassa.informatimago.com> wrote previously:
|So, to be really a first class object, a function should let itself be
|modified too:
|[44]> (setq f (function (lambda (x) (+ 1 x))))
|#<CLOSURE :LAMBDA (X) (+ 1 X)>
|Oops, an opaque type, I can't change the body.
|[46]> (setq f (lambda (x) (+ 1 x)))
|#<CLOSURE :LAMBDA (X) (+ 1 X)>

FWIW, you can change the body in Python:

    >>> def foo(x):
    ...     x += 3
    ...     x *= 2
    ...     return x
    ...
    >>> foo(4)
    14
    >>> def bar(y):
    ...     y -= 4
    ...     return y
    ...
    >>> foo.func_code = bar.func_code
    >>> foo(4)
    0
    >>> print foo
    <function foo at 0xbf9cc>


But this is a completely silly thing to do.  The only real meaning of my
comment that Haskell and Python are better for HOFs than is Lisp is that
I find the expression and use of HOFs more "natural"--largely because of
a friendlier syntax.  In the Haskell case--but not Python--the uniform
use of currying makes working with arbitrary level functions
particularly easy.

For this point, I don't really care if some folks retort that Lisp
syntax is actually more natural, or easier to work with.  Fine, I don't
care; let's accept the stipulation.  But the underlying issue was the
spurious claim that lambda forms were somehow required for HOFs, which
is totally bogus.  Python could get by with only 'def', Lisp with only
'defun', and Haskell only '=' and 'where'... and all of them would be
just as capable at using combinatorial and other HOFs.

My little mention spurred this other subthread about things to name and
not name, which repeated some of the same silliness.  Basically, the
truth is that you do not NEED lambda for anything.  Moreover, it is far
more common to use lambdas where aesthetics and readability would be
better without them than it is to use names where lambdas would be
better.  But I am certainly NOT one of the people who advocates taking
lambda out of Python (or out of Haskell or Lisp either, for that
matter--especially since Haskell's '\' symbol is so elegant)--in fact,
in Python circles I am pretty much "Mr. Functional Programming" (Dr.,
actually), try google.  And my book uses way more lambdas than probably
any other Python book... but it's not because I think they're necessary,
or even relevant, to HOFs.

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Iran nuclear neocon POTUS patriot Pakistan weaponized uranium invasion UN
smallpox Gitmo Castro Tikrit armed revolution Carnivore al-Qaeda sarin
---[ Gnosis Software ("We know stuff") <·····@gnosis.cx> ]---------------
From: Jacek Generowicz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <tyf65ip383h.fsf@pcepsft001.cern.ch>
·····@gnosis.cx (David Mertz) writes:

> But the underlying issue was the spurious claim that lambda forms
> were somehow required for HOFs, which is totally bogus.  Python
> could get by with only 'def', Lisp with only 'defun', and Haskell
> only '=' and 'where'... and all of them would be just as capable at
> using combinatorial and other HOFs.

Yes, but arguments such as these are the first step down the slippery
slope to Turing Equivalence. For just about any feature in just about
any language, you could argue that the langugage could get by without
it ... and taking this to its logical conclusion, you end up with
assembler.

I love Python, but the fact that its support for anonymous, inline
defined, literal (however you wish to call them) functions is severely
limited annoys me on a frequent basis. It makes programming in Python
more difficult or painful for me than it would otherwise be.

Ultimately, all these Python v Lisp arguments boil down to the
differing philosophies:

Python:

- Keep it simple

- Guido knows what's best for me


Lisp:

- Provide as much power to the programmer as possible, out of the box

- I know what's best for me, and I want a language that allows me to
  invest effort in making difficult things easy for me


All these isolated arguments over what each one of us finds better
about some feature of one language or the other, are completely
pointless. (And they are downright vandalistic, when half of the
criticisms of the "other" language are baseless, as they so often seem
to be.)

If you buy into the Python philosophy, use Python. If you buy into the
Lisp philosophy, use Lisp. I happen to buy into both; each has its
appeal in certain environments.

So, yes, Python could do without lambda altogether, and I would still
program in it. It would be less pleasant than it is now, but still
orders of magnitude more pleasant than C++ or Java. On the other hand,
Python could provide fully-fledged anonymous functions, and then it
would be even more pleasant to use. That is one of the (many) things I
love about Common Lisp; it tries so damn hard to make my life easy for
me. It is devoid of arbitrary restrictions.

Arguing that your favourite language is better than all others,
because the crappier ones provide you with a more restricted toolset,
while the better ones provide you with too good a toolset, is,
frankly, naive and childish.

Google for: paul graham blub
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.139.1066295084.2192.python-list@python.org>
|> But the underlying issue was the spurious claim that lambda forms
|> were somehow required for HOFs, which is totally bogus.  Python
|> could get by with only 'def', Lisp with only 'defun', and Haskell
|> only '=' and 'where'... and all of them would be just as capable at
|> using combinatorial and other HOFs.

Jacek Generowicz <················@cern.ch> wrote previously:
|Yes, but arguments such as these are the first step down the slippery
|slope to Turing Equivalence. For just about any feature in just about
|any language, you could argue that the langugage could get by without
|it ... and taking this to its logical conclusion, you end up with
|assembler.

There is no such slope.  OF COURSE everything is *computable* in every
language.  That's obvious and trivial.  Well, so are lots of things, but
it's not the point I've made.

What I am talking about is HIGHER ORDER FUNCTIONS.  I.e. things
(abstractions) that don't exist in assembly language or in Turing
machines.  You don't need that abstraction to do any computation, but
obviously, HOFs have a certain utility and beauty.

And you DO NOT NEED lambdas for HOFs!  Categorically so--it's not that
you can use only a subset of HOFs if you only have def/defun/=.  A
language that doesn't have lambda, but treats functions as first class,
can express EVERY HOF that one that adds lambda can.

This point is quite neutral as to whether lambda forms are otherwise
worthwhile.  It's just a basic fact that a bunch of posters oddly want
to deny.

Yours, David...

--
·····@  | The specter of free information is haunting the `Net!  All the
gnosis  | powers of IP- and crypto-tyranny have entered into an unholy
.cx     | alliance...ideas have nothing to lose but their chains.  Unite
        | against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmng2k$o4n$0@216.39.172.122>
On Thu, 16 Oct 2003 05:01:44 -0400, ·····@gnosis.cx (David Mertz) wrote:

>|> But the underlying issue was the spurious claim that lambda forms
>|> were somehow required for HOFs, which is totally bogus.  Python
>|> could get by with only 'def', Lisp with only 'defun', and Haskell
>|> only '=' and 'where'... and all of them would be just as capable at
>|> using combinatorial and other HOFs.
>
>Jacek Generowicz <················@cern.ch> wrote previously:
>|Yes, but arguments such as these are the first step down the slippery
>|slope to Turing Equivalence. For just about any feature in just about
>|any language, you could argue that the langugage could get by without
>|it ... and taking this to its logical conclusion, you end up with
>|assembler.
>
>There is no such slope.  OF COURSE everything is *computable* in every
>language.  That's obvious and trivial.  Well, so are lots of things, but
>it's not the point I've made.
>
>What I am talking about is HIGHER ORDER FUNCTIONS.  I.e. things
>(abstractions) that don't exist in assembly language or in Turing
>machines.  You don't need that abstraction to do any computation, but
>obviously, HOFs have a certain utility and beauty.
>
>And you DO NOT NEED lambdas for HOFs!  Categorically so--it's not that
>you can use only a subset of HOFs if you only have def/defun/=.  A
>language that doesn't have lambda, but treats functions as first class,
>can express EVERY HOF that one that adds lambda can.

ISTM there could be ways that you need BOTH named and un-named functions.
I.e., a function NEEDS a name in order to call itself recursively
(unless you create some specialized syntax for a recursive call).

OTOH, if you evaluate a def in a namespace where you don't know what
all the names are, you have a collision risk when you choose a name.
An un-named function eliminates that risk.

I.e., even if the function-definition part is identical in syntax and
capability, ISTM the name-binding side effect could be an issue.
Practically, it is probably rare that you can't use a named function,
but really def is a convenience construct that does name binding after
doing (what would be) a full-fledged lambda thing IMO.

Why should the following kind of thing be arbitrarily restricted?
(currently for two reasons -- a name is useless here and def
is a statement, not allowed in this contex):

 >>> funlist = [
 ...     (lambda value:
 ...         lambda:'My value is %s'%value
 ...             # imagine freedom to have full suites here
 ...     )(y) for y in range(5)
 ... ]
 >>> for fun in funlist: print fun()
 ...
 My value is 0
 My value is 1
 My value is 2
 My value is 3
 My value is 4

(Not that a bound method (aka callable object if bound method is __call__) might
not be as good or better in many cases, but that might lead to asking whether
you NEED to be able to define functions outside of classes ;-)

ISTM there are uses for lists (and dicts for that matter) of functions
where the def names would at best be ignored side effects. E.g., perhaps
key or macro-key-sequence bindings for an editor, or event bindings for a GUI, etc.

>
>This point is quite neutral as to whether lambda forms are otherwise
>worthwhile.  It's just a basic fact that a bunch of posters oddly want
>to deny.
>
ISTM you are focusing on the defined function to the exclusion of
the name-binding-as-side-effect, and saying you don't need lambdas
because def's can generate the same functions, but ISTM that's not the whole story ;-)

Regards,
Bengt Richter
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.151.1066361549.2192.python-list@python.org>
|>And you DO NOT NEED lambdas for HOFs!

····@oz.net (Bengt Richter) wrote previously:
|there could be ways that you need BOTH named and un-named functions.

Nope, you do not NEED both.  It can be convenient or expressive to have
both, but it is certainly not necessary for HOFs or any other
computational purpose.  And I have yet to see an example where a
hypothetical loss of unnamed functions would *significantly* worsen
expressiveness.

|a function NEEDS a name in order to call itself recursively

Nope.  That's the point of the Y combinator; you don't need a name to do
this (just first class anonymous functions).  See, for example:

    http://en2.wikipedia.org/wiki/Y_combinator

|OTOH, if you evaluate a def in a namespace where you don't know what
|all the names are, you have a collision risk when you choose a name.
|An un-named function eliminates that risk.

Sure, that can occassionally be useful in eliminating the small risk.
But so can 'grep'.  There are always more names out there to use.  This
particular convenience is VERY small.

|Why should the following kind of thing be arbitrarily restricted?
| >>> funlist = [
| ...     (lambda value:
| ...         lambda:'My value is %s'%value
| ...             # imagine freedom to have full suites here
| ...     )(y) for y in range(5)
| ... ]
| >>> for fun in funlist: print fun()

Obviously, you cannot spell 'funlist' quite that way in Python.  But the
available spellings are not bad looking IMO.  E.g., with no lambda:

    >>> def ValFactory(x):
    ...     def say_val(x=x): return 'My value is %s' % x
    ...     return say_val
    ...
    >>> funlist = map(ValFactory, range(5))

I'm not sure the point here.  My spelling happens to be Python's (or at
least one option in Python)... and it works fine without any lambdas.
If you want, you can even 'del' the name 'ValFactory' after the list is
created.

Yours, David...

--
    _/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY: Postmodern Enterprises _/_/_/
   _/_/    ~~~~~~~~~~~~~~~~~~~~[·····@gnosis.cx]~~~~~~~~~~~~~~~~~~~~~  _/_/
  _/_/  The opinions expressed here must be those of my employer...   _/_/
 _/_/_/_/_/_/_/_/_/_/ Surely you don't think that *I* believe them!  _/_/
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmoj6o$rp5$0@216.39.172.122>
On Thu, 16 Oct 2003 23:10:52 -0400, ·····@gnosis.cx (David Mertz) wrote:

>|>And you DO NOT NEED lambdas for HOFs!
>
>····@oz.net (Bengt Richter) wrote previously:
>|there could be ways that you need BOTH named and un-named functions.
>
>Nope, you do not NEED both.  It can be convenient or expressive to have
>both, but it is certainly not necessary for HOFs or any other
>computational purpose.  And I have yet to see an example where a
>hypothetical loss of unnamed functions would *significantly* worsen
>expressiveness.
>
>|a function NEEDS a name in order to call itself recursively
You snipped the line following the preceding:
(unless you create some specialized syntax for a recursive call)

>
>Nope.  That's the point of the Y combinator; you don't need a name to do
>this (just first class anonymous functions).  See, for example:
>
>    http://en2.wikipedia.org/wiki/Y_combinator
I'd call that a specialized syntax, to serve my purposes ;-)

>
>|OTOH, if you evaluate a def in a namespace where you don't know what
>|all the names are, you have a collision risk when you choose a name.
>|An un-named function eliminates that risk.
>
>Sure, that can occassionally be useful in eliminating the small risk.
>But so can 'grep'.  There are always more names out there to use.  This
>particular convenience is VERY small.
That's what I meant by the first line in
"""
Practically, it is probably rare that you can't use a named function,
but really def is a convenience construct that does name binding after
doing (what would be) a full-fledged lambda thing IMO.
"""
>
>|Why should the following kind of thing be arbitrarily restricted?
>| >>> funlist = [
>| ...     (lambda value:
>| ...         lambda:'My value is %s'%value
>| ...             # imagine freedom to have full suites here
>| ...     )(y) for y in range(5)
>| ... ]
>| >>> for fun in funlist: print fun()
>
>Obviously, you cannot spell 'funlist' quite that way in Python.  But the
The above spelling works fine, being verbatim cut/paste). Just not if you want
to replace the comment as it invites you to imagine. I guess the hypothetical
version is what you were referring to by 'that way.'

>available spellings are not bad looking IMO.  E.g., with no lambda:
I pre-agreed, following my example with:
"""
(Not that a bound method (aka callable object if bound method is __call__) might
not be as good or better in many cases, ...
"""
>
>    >>> def ValFactory(x):
>    ...     def say_val(x=x): return 'My value is %s' % x
>    ...     return say_val
>    ...
>    >>> funlist = map(ValFactory, range(5))
>
>I'm not sure the point here.  My spelling happens to be Python's (or at
>least one option in Python)... and it works fine without any lambdas.

The relevant phrase from the post you are replying to was
"... where the def names would at best be ignored side effects." (Although
you are forced to use the temp bindings to return the function).

>If you want, you can even 'del' the name 'ValFactory' after the list is
>created.
Sure. Interesting you chose to use the default-value hack rather than
a closure ;-). What I had in mind when I pre-agreed was something like

 >>> class SayVal(object):
 ...     def __init__(self, v): self.v=v
 ...     def __call__(self): return 'My value is %s' % self.v
 ...
 >>> funlist = map(SayVal, range(5))
 >>> for f in funlist: print f()
 ...
 My value is 0
 My value is 1
 My value is 2
 My value is 3
 My value is 4

Regards,
Bengt Richter
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.181.1066417144.2192.python-list@python.org>
····@oz.net (Bengt Richter) wrote previously:
|>Nope.  That's the point of the Y combinator; you don't need a name to do
|>this (just first class anonymous functions).  See, for example:
|>    http://en2.wikipedia.org/wiki/Y_combinator
|I'd call that a specialized syntax, to serve my purposes ;-)

Well... it's specialized.  But it's not a syntax, just a somewhat odd
HOF.  But I would definitely agree that I don't want all my recursion to
be based on anonymous functions.

|>This particular convenience is VERY small.
|That's what I meant by the first line in

Yeah, but I put the 'very' in caps :-).

|the hypothetical version is what you were referring to by 'that way.'

Yeah, sorry about my pronoun.  I meant "can't spell the full suite..."

|>    >>> def ValFactory(x):
|>    ...     def say_val(x=x): return 'My value is %s' % x
|>    ...     return say_val
|Sure. Interesting you chose to use the default-value hack rather than
|a closure ;-). What I had in mind when I pre-agreed was something like
| >>> class SayVal(object):
| ...     def __init__(self, v): self.v=v
| ...     def __call__(self): return 'My value is %s' % self.v

Well... the "default value hack" *IS* a closure.

I know I'm in the minority here, but it feels like more of a hack to me
to make class instances whose (main) purpose is to "act like functions"
(i.e. have custom '.__call__()' methods).  In my mind, when I want a
bunch of related callables, the natural approach is writing a function
factory, not a class.

But either way, Bengt's is another perfectly good spelling for a
collection of callables that allow full suites.  Not being Dutch, I
can't say which one is the "one obvious way."

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <·····@gnosis.cx> ]--------------------------
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F8FDB6D.2BCB8B5B@setf.de>
David Mertz wrote:
> 
> ...
> 
> |a function NEEDS a name in order to call itself recursively
> 
> Nope.  That's the point of the Y combinator; you don't need a name to do
> this (just first class anonymous functions).  See, for example:
> 
>     http://en2.wikipedia.org/wiki/Y_combinator
> 

please bear with me on something which i have evidently misunderstood.
what are the symbols 'h' and 'x' in the referenced exposition on the "y
combinator" if they are not names?
is the essential distinction, that one does not "need" free "names"?

?
From: Ray Blaak
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <uwub3ztxo.fsf@STRIPCAPStelus.net>
·····@gnosis.cx (David Mertz) writes:
> |a function NEEDS a name in order to call itself recursively
> 
> Nope.  That's the point of the Y combinator; you don't need a name to do
> this (just first class anonymous functions).

Actually you do need a name. The Y combinator is just a way to give a name to
the anonymous function, where the name is a parameter name. It is only with
that name that the recursive invocation is done.

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
········@STRIPCAPStelus.net                    The Rhythm has my soul.
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.180.1066417141.2192.python-list@python.org>
······@gnosis.cx (David Mertz) writes:
|> |a function NEEDS a name in order to call itself recursively
|> Nope.  That's the point of the Y combinator; you don't need a name to do
|> this (just first class anonymous functions).

Ray Blaak <········@STRIPCAPStelus.net> wrote previously:
|Actually you do need a name. The Y combinator is just a way to give a name to
|the anonymous function, where the name is a parameter name. It is only with
|that name that the recursive invocation is done.

Well, OK.  This is true.  But the context was basically whether you
could write whole programs as big lambda abstractions--e.g.  Lisp minus
'defun' and 'set', or Python minus 'def'.

"Normal" recursive programs let the programmer know the name of the
function she is writing, and use that name for the recursion call.  You
could use the Y combinator even if pixies would come it at random and
change the bound name 'h' to something else, throughout your code; the
name itself is never -used- beyond the lambda.

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <·····@gnosis.cx> ]--------------------------
From: Rainer Deyke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <tBYjb.801112$Ho3.214760@sccrnsc03>
Ray Blaak wrote:
> Actually you do need a name. The Y combinator is just a way to give a
> name to the anonymous function, where the name is a parameter name.
> It is only with that name that the recursive invocation is done.

This is technically not true.  See
http://www.eleves.ens.fr:8080/home/madore/programs/unlambda/#lambda_elim.


-- 
Rainer Deyke - ·······@eldwood.com - http://eldwood.com
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <zng0vd16.fsf@comcast.net>
····@oz.net (Bengt Richter) writes:

> ISTM there could be ways that you need BOTH named and un-named functions.
> I.e., a function NEEDS a name in order to call itself recursively
> (unless you create some specialized syntax for a recursive call).

Y do you think that?  I bet you could come up with a way to do it
if you applied yourself...
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7q2dneIXY78AMhOiRVn-gA@comcast.com>
> Ultimately, all these Python v Lisp arguments boil down to the
> differing philosophies:

Agreed so far...

> Python:
> - Keep it simple

Simple can be powerful ;-)

> - Guido knows what's best for me

Hogwash.  I don't believe that, and neither does Guido.

> Lisp:
> - Provide as much power to the programmer as possible, out of the
box

Vroom, vroom, maybe I should take it out for a spin .... at the local
racetrack.

> - I know what's best for me, and I want a language that allows me to
>   invest effort in making difficult things easy for me

This I agree with, and it is why I currently choose Python.

Presenting the choice as 'toady language' versus 'real man language'
is rather biased.

Terry J. Reedy
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmlscu$hp8$1@newsreader2.netcologne.de>
Jacek Generowicz wrote:

> Ultimately, all these Python v Lisp arguments boil down to the
> differing philosophies:
> 
> Python:
> 
> - Keep it simple
> 
> - Guido knows what's best for me
> 
> 
> Lisp:
> 
> - Provide as much power to the programmer as possible, out of the box
> 
> - I know what's best for me, and I want a language that allows me to
>   invest effort in making difficult things easy for me

I second that. To me, this is indeed the important difference, and the 
most important reason why I love Lisp.

Most languages are of the first kind: some language designer thinks he 
knows better what's best for the users of his language than those users 
themselves. Such people use language design as a mask of authoritarian 
power. See for example http://www.iol.ie/~pcassidy/ARC/guru.html


Pascal
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfszng1fewt.fsf@black132.ex.ac.uk>
Pascal Costanza <········@web.de> writes:

> Jacek Generowicz wrote:
> 
> > Ultimately, all these Python v Lisp arguments boil down to the
> > differing philosophies:
> > Python:
> > - Keep it simple

Yep.

> > - Guido knows what's best for me

That's not quite right: s/me/python/. The thing that the lisp community
apparently has problems to grasp is that software development is largely a
team effort. In order to build an effective general purpose programming
language you need a tremendous amounts of coordinated community effort (brooks
et. al nonwithstanding a handful of elite hackers just won't write all those
libraries, documentation etc.).

Python has demonstrated that it can support such a community, CL hasn't yet
(although it certainly has demonstrated that it can attract top programmers).

Maybe the social downside of a language that is very malleable and adaptable
is that it entails to fragmentation. If whenever a new need becomes apparent
anyone can to kludge a quick fix together with macros, maybe several
semi-private half-baked solutions are developed whereas in python the fact
that a community effort is needed to change and adapt/enhance the whole
language and the fact that someone is in charge ensures coherence (while
preventing "committee designs"[1]).

Or maybe there is no such downside and it's just the AI winter or some other
historical accident. Who knows.

> > Lisp:
> > - Provide as much power to the programmer as possible, out of the box

This is just completely ridiculous. CL out of the box -- in stark contrast to
python -- is just about useless for almost any real world task (certainly as
far as the free implementations are concerned and the only fully-featured,
cross-platform Cl I'm aware of is Allegro CL, which is uhm, pricey).

> > - I know what's best for me, and I want a language that allows me to
> >   invest effort in making difficult things easy for me

Great for you (BTW what happened to that JVM in lisp of yours -- should only
have taken a couple of weeks/months or so to write, right?). But whether CL
makes difficult things easy or not, it sure makes many easy things difficult.

> 
> I second that. To me, this is indeed the important difference, and the most
> important reason why I love Lisp.

Sure, just because CL is a worse general purpose language than python (in the
sense of best fit for most programmers for most tasks (representatively
sampled) -- I'm not sure python has much competition in this regard, BTW)
doesn't mean that CL can't be a more rewarding programing language for some
people.

After all most programers and most programming tasks encountered are not
terribly exciting.

But claims that CL is more productive (even for good programmers who actually
know both CL and python) in *general*, as you've implied in another post, are
pretty, uhm, unconvincing.
 
> Most languages are of the first kind: some language designer thinks he knows
> better what's best for the users of his language than those users themselves.
> Such people use language design as a mask of authoritarian power. 
> See for example http://www.iol.ie/~pcassidy/ARC/guru.html

To me this reads as "You're bunch of brainless puppets of a crypto-fascist".
Now WHAT ON EARTH motivates you to *cross-post* inflammatory crap like this?

Did it occur to you that people maybe use python not so much because they are
retards but because it's vastly more effective than CL at the tasks they
currently need to perform? Should I send you a few hundred lines of my python
code so that you can try translating them into CL?

'as

Footnotes:

[1] I decided to cut this footnote as I intend this to be my last post on the
    matter. I'll send it to you in private email, if you really want to know.
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <wub512qq.fsf@ccs.neu.edu>
Alexander Schmolck <··········@gmx.net> writes:

> Did it occur to you that people maybe use python not so much because they are
> retards but because it's vastly more effective than CL at the tasks they
> currently need to perform? Should I send you a few hundred lines of my python
> code so that you can try translating them into CL?

Sounds like an interesting challenge...
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-F48D95.11430616102003@news.service.uci.edu>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> 
wrote:

> Alexander Schmolck <··········@gmx.net> writes:
> 
> > Did it occur to you that people maybe use python not so much because they 
> > are
> > retards but because it's vastly more effective than CL at the tasks they
> > currently need to perform? Should I send you a few hundred lines of my 
> > python
> > code so that you can try translating them into CL?
> 
> Sounds like an interesting challenge...

For simple use of built-in libraries,
http://online.effbot.org/2003_08_01_archive.htm#troll
looks like a good test case.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87fzhsoppg.fsf@bird.agharta.de>
On Thu, 16 Oct 2003 11:43:06 -0700, David Eppstein <········@ics.uci.edu> wrote:

> For simple use of built-in libraries,
> http://online.effbot.org/2003_08_01_archive.htm#troll
> looks like a good test case.

Quick hack follows.

  ···@bird:/tmp > cat troll.lisp
  (asdf:oos 'asdf:load-op :aserve)
  (asdf:oos 'asdf:load-op :cl-ppcre)

  (defparameter *scanner*
    (cl-ppcre:create-scanner
     "<a href=\"AuthorThreads.asp[^\"]*\">([^<]+)</a></td>\\s*
  <td align=\"center\">[^<]+</td>\\s*
  <td align=\"center\">[^<]+</td>\\s*
  <td align=\"center\">\\d+</td>\\s*
  <td align=\"center\">(\\d+)</td>\\s*
  <td align=\"center\">(\\d+)</td>\\s*
  <td align=\"center\">\\d+</td>\\s*
  <td align=\"center\">(\\d+)</td>\\s*"))

  (defun troll-checker (name)
    (let ((target
            (net.aserve.client:do-http-request
             (format nil "http://netscan.research.microsoft.com/Static/author/authorprofile.asp?searchfor=~A" name)
             :protocol :http/1.0)))
      (cl-ppcre:do-scans (match-start match-end reg-starts reg-ends *scanner* target)
        (flet ((nth-group (n)
                 (subseq target (aref reg-starts n) (aref reg-ends n))))
          (let* ((group (nth-group 0))
                 (posts (parse-integer (nth-group 1)))
                 (replies (parse-integer (nth-group 2)))
                 (threads-touched (parse-integer (nth-group 3)))
                 (reply-to-post-ratio (/ replies posts))
                 (threads-to-post-ratio (/ threads-touched posts)))
            (unless (< posts 10)
              (format t "~55A R~,2F T~,2F ~:[~;TROLL~:[?~;!~]~]~%"
                      (subseq group 0 (min 55 (length group)))
                      reply-to-post-ratio
                      threads-to-post-ratio
                      (and (> reply-to-post-ratio .8)
                           (< threads-to-post-ratio .4))
                      (< threads-to-post-ratio .2))))))))

  (compile 'troll-checker)

  ···@bird:/tmp > cmucl
  ; Loading #p"/home/edi/.cmucl-init".
  CMU Common Lisp 18e, running on bird.agharta.de
  With core: /usr/local/lib/cmucl/lib/lisp.core
  Dumped on: Thu, 2003-04-03 15:47:12+02:00 on orion
  Send questions and bug reports to your local CMUCL maintainer,
  or see <http://www.cons.org/cmucl/support.html>.
  Loaded subsystems:
      Python 1.1, target Intel x86
      CLOS 18e (based on PCL September 16 92 PCL (f))
  * (load "troll")

  ; loading system definition from /usr/local/lisp/Registry/aserve.asd into
  ; #<The ASDF1017 package, 0/9 internal, 0/9 external>
  ; registering #<SYSTEM ASERVE {4854AEF5}> as ASERVE
  ; loading system definition from /usr/local/lisp/Registry/acl-compat.asd into
  ; #<The ASDF1059 package, 0/9 internal, 0/9 external>
  ; registering #<SYSTEM ACL-COMPAT {4869AD35}> as ACL-COMPAT
  ; loading system definition from /usr/local/lisp/Registry/htmlgen.asd into
  ; #<The ASDF1145 package, 0/9 internal, 0/9 external>
  ; registering #<SYSTEM HTMLGEN {487E64C5}> as HTMLGEN
  ; loading system definition from /usr/local/lisp/Registry/cl-ppcre.asd into
  ; #<The ASDF1813 package, 0/9 internal, 0/9 external>
  ; registering #<SYSTEM #:CL-PPCRE {48F32835}> as CL-PPCRE
  ; Compiling LAMBDA (NAME):
  ; Compiling Top-Level Form:
  T
  * (troll-checker ····@agharta.de")
  comp.lang.lisp                                          R0.93 T0.63
  NIL
  * (troll-checker ·········@ics.uci.edu")
  rec.photo.digital                                       R1.00 T0.76
  rec.arts.sf.written                                     R0.99 T0.57
  comp.lang.python                                        R0.98 T0.64
  rec.photo.equipment.35mm                                R1.00 T0.73
  sci.math                                                R1.00 T0.77
  rec.puzzles                                             R1.00 T0.75
  comp.theory                                             R1.00 T0.56
  comp.graphics.algorithms                                R1.00 T0.87
  comp.sys.mac.apps                                       R1.00 T0.69
  NIL
  * (troll-checker ·····@thalassa.informatimago.com")
  comp.lang.lisp                                          R0.91 T0.44
  fr.comp.os.unix                                         R1.00 T0.70
  es.comp.os.linux.programacion                           R1.00 T0.67
  fr.comp.lang.lisp                                       R1.00 T0.40 TROLL?
  comp.unix.programmer                                    R1.00 T0.92
  sci.space.moderated                                     R1.00 T0.43
  gnu.emacs.help                                          R0.95 T0.84
  sci.space.policy                                        R1.00 T0.33 TROLL?
  alt.folklore.computers                                  R1.00 T0.43
  comp.lang.scheme                                        R0.83 T0.58
  fr.comp.os.mac-os.x                                     R0.92 T0.83
  NIL

Granted, Portable AllegroServe[1] and CL-PPCRE[2] aren't "built-in"
(but freely available, compatible with various CL compilers, and easy
to install) and Python might have a bit more syntactic sugar but it
wasn't _too_ hard to do that in Lisp.

Edi

[1] <http://portableaserve.sf.net/>
[2] <http://weitz.de/cl-ppcre/>
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <smlrua5f.fsf@ccs.neu.edu>
David Eppstein <········@ics.uci.edu> writes:

> In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> 
> wrote:
>
>> Alexander Schmolck <··········@gmx.net> writes:
>> 
>> > Did it occur to you that people maybe use python not so much because they 
>> > are
>> > retards but because it's vastly more effective than CL at the tasks they
>> > currently need to perform? Should I send you a few hundred lines of my 
>> > python
>> > code so that you can try translating them into CL?
>> 
>> Sounds like an interesting challenge...
>
> For simple use of built-in libraries,
> http://online.effbot.org/2003_08_01_archive.htm#troll
> looks like a good test case.

I did the troll example and discovered this:

  - I hadn't gotten around to defining the client-side part of the
    interface shim I was using with AllegroServe.  (As it happens, I
    am using the AllegroServe library in another project that I needed
    to retrofit.  I'm so used to the shim interface I figured I'd just
    continue to use it.)

  - It doesn't work too well when 'netscan.research.microsoft.com'
    isn't responding.  (wasted half an hour assuming I had bug.)

  - My solution was so close to Edi Weitz's that I'd be accused of
    plagiarism if I posted it.  I used AllegroServe, a portable
    regular expression library (not the same one as Edi Weitz used,
    but the API was quite similar), an iteration generator (Edi
    used the one provided by the regexp library, I used Waters'
    series), and a format expression.

  - I'm a comp.lang.lisp troll.  My apologies to all.  (I'm in good
    company, though.  Kenny Tilton, Kent Pitman, Erann Gat, Tim
    Bradshaw, Pascal Costanza...)

  - The problem was so straightforward that it offers but one
    solution.  The variations are only in the names of the variables
    and the choice of iteration construct (with a generator-based
    mechanism being the favored choice in our sample of three
    implementations).


Alexander Schmolck sent me some code to play with, so I'm going to
take a look at it.
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <871xtbltrx.fsf@bird.agharta.de>
On Fri, 17 Oct 2003 12:00:28 -0400, Joe Marshall <···@ccs.neu.edu> wrote:

> - I'm a comp.lang.lisp troll.  My apologies to all.  (I'm in good
>   company, though.  Kenny Tilton, Kent Pitman, Erann Gat, Tim
>   Bradshaw, Pascal Costanza...)

Now I'm jealous. I had hopes that I also was a troll but it looks like
I'm not... :(

Edi.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmp538$15pq$1@f1node01.rhrz.uni-bonn.de>
Edi Weitz wrote:
> On Fri, 17 Oct 2003 12:00:28 -0400, Joe Marshall <···@ccs.neu.edu> wrote:
> 
> 
>>- I'm a comp.lang.lisp troll.  My apologies to all.  (I'm in good
>>  company, though.  Kenny Tilton, Kent Pitman, Erann Gat, Tim
>>  Bradshaw, Pascal Costanza...)
> 
> 
> Now I'm jealous. I had hopes that I also was a troll but it looks like
> I'm not... :(

Maybe they can add a special case for you in the algorithm?


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Edi Weitz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87wub3ken3.fsf@bird.agharta.de>
On Fri, 17 Oct 2003 18:24:08 +0200, Pascal Costanza <········@web.de> wrote:

> Edi Weitz wrote:
>
> > Now I'm jealous. I had hopes that I also was a troll but it looks
> > like I'm not... :(
> 
> Maybe they can add a special case for you in the algorithm?

You mean I could be a troll who's also cheating? Sounds good... :)

Edi.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmp663$15pu$2@f1node01.rhrz.uni-bonn.de>
Edi Weitz wrote:
> On Fri, 17 Oct 2003 18:24:08 +0200, Pascal Costanza <········@web.de> wrote:
> 
> 
>>Edi Weitz wrote:
>>
>>
>>>Now I'm jealous. I had hopes that I also was a troll but it looks
>>>like I'm not... :(
>>
>>Maybe they can add a special case for you in the algorithm?
> 
> 
> You mean I could be a troll who's also cheating? Sounds good... :)

Yay! :)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310161450.7fd3045b@posting.google.com>
Alexander Schmolck <··········@gmx.net> wrote in message news:<···············@black132.ex.ac.uk>...
> Did it occur to you that people maybe use python not so much because they are
> retards but because it's vastly more effective than CL at the tasks they
> currently need to perform?

People use Python most likely for these reasons:

- they read some articles about it in popular press
- it is relatively new
- it came with their Linux distribution

The second point is important. When something is new, there is a
ready-made explanation for not being popular. When the pointy haired
boss asks why isn't the whole world using Python for everything, you
just have to say ``It's too new, so only the smart, hip people who
have their ears to the ground are using it, but just wait a few
years.''

It's easy to add a positive adornment to the explanation which gives
rise to an expectation of success, and which in turn creates a
psychological pressure to adopt or else be left behind!

Soon, the language starts being mentioned on job advertisements as a
desireable skill, and the pressure starts to snowball. At this point,
hordes of immature programmers are paniced into learning it, just so
they can put it on their resumes and be able to say something about it
in interviews.

But these programmers resent being pressured into learning! They
resent the new programming language, even if they contribute to its
body of popularity.

This is why in ten, fifteen, maybe twenty years, when the popularity
bubble of that language has long burst, there will be hordes of
detractors who will have ready-made seemingly technical explanations
why that language is no longer popular.
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <R2Ajb.61883$pv6.8194@twister.nyc.rr.com>
Alexander Schmolck wrote:


> language you need a tremendous amounts of coordinated community effort (brooks
> et. al nonwithstanding a handful of elite hackers just won't write all those
> libraries, documentation etc.).

No, but a few Common Lispers are working hard to solve the chicken-egg 
problem that no matter how great it is, CL needs more libraries to get 
more users to get more libraries.

Hey, does anyone know the Python history well-enough to describe the 
curve of the size of its user base? And when was the first release 
available?

> 
> Python has demonstrated that it can support such a community, CL hasn't yet
> (although it certainly has demonstrated that it can attract top programmers).

Thanks for the "yet". <g> Ability to attract top programmers--that's 
good, right? :)

> 
> Maybe the social downside of a language that is very malleable and adaptable
> is that it entails to fragmentation. If whenever a new need becomes apparent
> anyone can to kludge a quick fix together with macros, ...

Ah, but this is where CL benefits frim its 1000-page list of built-in 
functions. One is not writing macros to get functionality a computer 
language should do (by general agreement within the community), such as 
iterators or OO, and certainly not to "fix" the language" (get a new 
language!).

One is writing macros (and HOFs and a tree of classes)  either to extend 
the language into a specific application domain such as the RoboCup 
simulated soccer AI research programme, and no language should do that, 
or to explore new paradigms in programming, ideas not yet available in 
one's preferred language. At one time that was OO, now I am doing that 
with the dataflow paradigm with my Cells library.

Scheme, however, with its itsy-bitsy teeny-weeny spec /does/ end up 
fragmented because they cannot share code when each user effectively has 
their own scheme.

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Nikodemus Siivola
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmn42h$uno$1@nyytiset.pp.htv.fi>
In comp.lang.lisp Kenny Tilton <·······@nyc.rr.com> wrote:

> one's preferred language. At one time that was OO, now I am doing that 
> with the dataflow paradigm with my Cells library.

By the by: is Cells asdf-installable yet?

Cheers,

 -- Nikodemus
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmmbn3$cri$1@newsreader2.netcologne.de>
Alexander Schmolck wrote:

> Python has demonstrated that it can support such a community, CL hasn't yet
> (although it certainly has demonstrated that it can attract top programmers).
> 
> Maybe the social downside of a language that is very malleable and adaptable
> is that it entails to fragmentation. If whenever a new need becomes apparent
> anyone can to kludge a quick fix together with macros, maybe several
> semi-private half-baked solutions are developed whereas in python the fact
> that a community effort is needed to change and adapt/enhance the whole
> language and the fact that someone is in charge ensures coherence (while
> preventing "committee designs"[1]).
> 
> Or maybe there is no such downside and it's just the AI winter or some other
> historical accident. Who knows.

Yes, I think we really can't know yet.

The thing I find amazing about languages like Python is that they have 
managed to get high-level language constructs accepted by the "masses" 
that have been considered too complicated, too inefficient, too whatever 
not so long ago. Obviously their designers have found a way to better 
communicate the value of such language constructs.

Of course, macros are possibly above a certain level of complexity and 
therefore can never reach the masses.

>>>Lisp:
>>>- Provide as much power to the programmer as possible, out of the box
> 
> 
> This is just completely ridiculous. CL out of the box -- in stark contrast to
> python -- is just about useless for almost any real world task (certainly as
> far as the free implementations are concerned and the only fully-featured,
> cross-platform Cl I'm aware of is Allegro CL, which is uhm, pricey).

Maybe we should differentiate between expressive power and 
"infrastructure power".

>>>- I know what's best for me, and I want a language that allows me to
>>>  invest effort in making difficult things easy for me
> 
> 
> Great for you (BTW what happened to that JVM in lisp of yours -- should only
> have taken a couple of weeks/months or so to write, right?).

Right. It runs the first tests. They have executed after about two 
months of development with about 8 hours per week of me working on the code.

However, I don't have the time to finish it at the moment. My priorities 
are different.

> But whether CL
> makes difficult things easy or not, it sure makes many easy things difficult.

Or so it seems.

>>I second that. To me, this is indeed the important difference, and the most
>>important reason why I love Lisp.
> 
> 
> Sure, just because CL is a worse general purpose language than python (in the
> sense of best fit for most programmers for most tasks (representatively
> sampled) -- I'm not sure python has much competition in this regard, BTW)
> doesn't mean that CL can't be a more rewarding programing language for some
> people.
> 
> After all most programers and most programming tasks encountered are not
> terribly exciting.

Are you talking about current trendy tasks, or also about tasks that 
might become important in the future?

> But claims that CL is more productive (even for good programmers who actually
> know both CL and python) in *general*, as you've implied in another post, are
> pretty, uhm, unconvincing.

I don't think I have said anything along these lines.

>>Most languages are of the first kind: some language designer thinks he knows
>>better what's best for the users of his language than those users themselves.
>>Such people use language design as a mask of authoritarian power. 
>>See for example http://www.iol.ie/~pcassidy/ARC/guru.html
> 
> 
> To me this reads as "You're bunch of brainless puppets of a crypto-fascist".
> Now WHAT ON EARTH motivates you to *cross-post* inflammatory crap like this?

Well, I haven't cross-posted inflammatory crap like this. This is only 
your interpretation of what I have posted.

> Did it occur to you that people maybe use python not so much because they are
> retards but because it's vastly more effective than CL at the tasks they
> currently need to perform?

Yes, I take that for granted.

> [1] I decided to cut this footnote as I intend this to be my last post on the
>     matter. I'll send it to you in private email, if you really want to know.

Yes, please.


Pascal
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bml1ea$ob4$0@216.39.172.122>
On Wed, 15 Oct 2003 00:04:21 +1300, Paul Foley <···@below.invalid> wrote:

>On Tue, 14 Oct 2003 01:26:54 -0400, David Mertz wrote:
>
>> Matthew Danish <·······@andrew.cmu.edu> wrote previously:
>> |On Wed, Oct 08, 2003 at 03:59:19PM -0400, David Mertz wrote:
>> |> |Come on.  Haskell has a nice type system.  Python is an application of
>> |> |Greespun's Tenth Rule of programming.
>> |> Btw. This is more nonsense.  HOFs are not a special Lisp thing.  Haskell
>> |> does them much better, for example... and so does Python.
>
>> |Wow.  The language with the limited lambda form, whose Creator regrets
>> |including in the language, is ... better ... at HOFs?
>> |You must be smoking something really good.
>
>> I guess a much better saying than Greenspun's would be something like:
>> "Those who know only Lisp are doomed to repeat it (whenver they look at
>> another language)."  It does a better job of getting at the actual
>> dynamic.
>
>Is there anyone who knows only Lisp?
>
>Those who know Lisp repeat it for a reason -- and it isn't because
>it's all they know!  [Besides, Greenspun's 10th isn't about _Lispers_
>reinventing Lisp; it's about _everybody else_ reinventing Lisp]
>
>> In point of fact, Python could completely eliminate the operator
>> 'lambda', and remain exactly as useful for HOFs. Some Pythonistas seem
>> to want this, and it might well happen in Python3000.  It makes no
>> difference... the alpha and omega of HOFs is that functions are first
>> class objects that can be passed and returned.  Whether they happen to
>> have names is utterly irrelevant, anonymity is nothing special.
>
True, but if you are forced to bind to a name in order to get hold of some
first class functions but not others, then some are IMO "more equal than others."
And unless you allow assignments in expressions, def foo():... will be excluded,
because it assigns/binds foo in the def evaluation context, whereas lambda doesn't.

For simple functions, things look a lot the same, e.g.,

 >>> def show():
 ...     def foo(x): return x+1
 ...     bar = lambda x: x+1
 ...     return foo,bar
 ...
 >>> import dis
 >>> dis.dis(show)
   2           0 LOAD_CONST               1 (<code object foo at 009033A0, file "<stdin>", line 2>)
               3 MAKE_FUNCTION            0
               6 STORE_FAST               0 (foo)
 
   3           9 LOAD_CONST               2 (<code object <lambda> at 009034A0, file "<stdin>", line 3>)
              12 MAKE_FUNCTION            0
              15 STORE_FAST               1 (bar)
 
   4          18 LOAD_FAST                0 (foo)
              21 LOAD_FAST                1 (bar)
              24 BUILD_TUPLE              2
              27 RETURN_VALUE
              28 LOAD_CONST               0 (None)
              31 RETURN_VALUE
 >>> foo,bar = show()
 >>> dis.dis(foo)
   2           0 LOAD_FAST                0 (x)
               3 LOAD_CONST               1 (1)
               6 BINARY_ADD
               7 RETURN_VALUE
               8 LOAD_CONST               0 (None)
              11 RETURN_VALUE
 >>> dis.dis(bar)
   3           0 LOAD_FAST                0 (x)
               3 LOAD_CONST               1 (1)
               6 BINARY_ADD
               7 RETURN_VALUE
 
The difference in the code generated seems to be mainly that lambda is guaranteed to have
a return value expression at the end, so there is no return case to solve by default boilerplate,
and it is left out.

Lambda is an expression, so this is possible with Python's syntax:

 >>> (lambda
 ... x
 ... :
 ... x
 ... +
 ... 1
 ... )
 <function <lambda> at 0x008FDE70>

(because indentation is ignored inside brackets). This obviously now precludes lambda bodies that
are dependent on indented code suites, and makes it (so far) impossible to put def foo():pass
inside expression brackets. But this is surface stuff w.r.t. the definition of the code body IMO.

The name part does make a difference, however, because it amounts to a forced assignment (note that
that you get MAKE_FUNCTION followed by STORE_FAST whether you assign a lambda expression "manually"
or do it by def. You get identical code (see above), but with lambda you don't have to have
a STORE_FAST LOAD_FAST to get the use of your function as "first class").

>True enough.  Naming things is a pain though.  Imagine if you couldn't
>use numbers without naming them: e.g., if instead of 2 + 3 you had to
>do something like
>
>  two = 2
>  three = 3
>  two + three
>
>Bleargh!  It "makes no difference" in much the same way that using
>assembler instead of Python "makes no difference" -- you can do the
>same thing either one, but one way is enormously more painful.
>
I think it makes a semantic difference, not just convenience.

>[Mind you, Python's lambda is next to useless anyway]

Well, even so, I would miss it, unless it's given a full life as a nameless def():
I don't think we can know if YAGNI will apply, since there is no current opportunity
for beautiful use cases to evolve or even viably to be conceived.

Regards,
Bengt Richter
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eHZgb.3279$dn6.2561@newsread4.news.pas.earthlink.net>
Marco Antoniotti:
> Come on.  Haskell has a nice type system.  Python is an application of
> Greespun's Tenth Rule of programming.

Oh?  Where's the "bug-ridden" part?  :)

That assertion also ignores the influence of user studies (yes,
research into how the syntax of a language affects its readabilty
and understandability) on Python's development; a topic which
is for the most part ignored in Lisp.

                    Andrew
                    ·····@dalkescientific.com
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <wubf49ap.fsf@comcast.net>
"Andrew Dalke" <······@mindspring.com> writes:

> Marco Antoniotti:
>> Come on.  Haskell has a nice type system.  Python is an application of
>> Greespun's Tenth Rule of programming.
>
> Oh?  Where's the "bug-ridden" part?  :)
>
> That assertion also ignores the influence of user studies (yes,
> research into how the syntax of a language affects its readabilty
> and understandability) on Python's development; a topic which
> is for the most part ignored in Lisp.

For some reason people who don't like fully parenthesized polish
notation seem to think that Lisp hackers don't know any better,
haven't seen anything else, and that if we were only shown the light,
we'd switch in an instant.

Allow me to point out that `standard algabraic notation' has been
available in Lisp for 40 years.  McCarthy designed M-expressions for
Lisp in 1962 (if not earlier) and the Lisp 1.5 manual is written using
them.

Vaughn Pratt's CGOL (which I mentioned before) was written in 1977.

Dylan adopted an algabraic syntax sometime in the late 80's 

In every one of these cases, algabraic syntax never quite caught on.

So either the syntax doesn't make a whole hell of a lot of difference
in readability, or readability doesn't make a whole hell of a lot of
difference in utility.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yD1hb.3530$dn6.3109@newsread4.news.pas.earthlink.net>
·············@comcast.net:
> So either the syntax doesn't make a whole hell of a lot of difference
> in readability, or readability doesn't make a whole hell of a lot of
> difference in utility.

Or the people who prefer the awesome power that is Lisp and
Scheme don't find the limited syntax to be a problem.

                    Andrew
                    ·····@dalkescientific.com
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <WV4hb.59675$nU6.10176536@twister.nyc.rr.com>
Andrew Dalke wrote:
> ·············@comcast.net:
> 
>>So either the syntax doesn't make a whole hell of a lot of difference
>>in readability, or readability doesn't make a whole hell of a lot of
>>difference in utility.
> 
> 
> Or the people who prefer the awesome power that is Lisp and
> Scheme don't find the limited syntax to be a problem.

OK, here you are saying that only a certain subset of programmers have 
the genetic makeup necessary to prefer the unlimited syntax. Unlikely.

It is nice that you also say this strongly correlates with those who 
like their programming languages to be powerful. But my guess is that 
that genetic thing won't hold up: if everyone who tries Lisp for more 
than two weeks gets used to the parens, and then after two months would 
not want to edit any other way, then what makes me think anyone who 
likes programming (even the ones in your imagination who do not want 
powerful languages) would love the syntax.

   ({function | macro | special-form} arguments*) => values*

Roughly speaking (I'm no BNFer) but... hellasweet! You can chant 
"simplicity" as much as you like, but /that/ is simple.

In C i put "int x;" at the top level and I have a global. In Lisp I am 
at first astonished to see I have to type (defparameter x) or defvar or 
defconstant. Wordy! Wordy! Wordy! But eventually I realize. Oh, why is 
the C "x" a global? There is no difference between that declaration and 
the one in:

void zzzz () {
    int x;
    .....}

Oh, well, you see, it is at the top level. ie, Weird things like a form 
being at the top level have huge unspoken implications. But with Lisp 
there is a great honking special form (macro?) such as "defparameter" 
that grabs you by the lapels and screams "GLOBAL!!!". But most of all, 
it manages to get the job done with The One True Syntax, using a 
dedicated macro instead of a special syntax (top-levelness) to establish 
the semantics.

You call that "limited"? Yer just flaming.

Anyway, the point is: fuggedaboutit. Lisp syntax is unlike all the other 
languages you have ever used, so it seems bizarre to the unitiated. But 
go to c.l.l. and flame the syntax and you will discover it is something 
Lispniks love. Including those who have used and excelled at all the 
other languages. And, as you concede, these are people who groove on the 
power of Lisp. Doesn't that make folks think they better go check out 
for themselves what these folks have discovered?

     http://alu.cliki.net/The%20RtLS%20by%20Road

Don't forget your Lisp-aware editor.


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <P77hb.3947$dn6.1061@newsread4.news.pas.earthlink.net>
Me:
> > Or the people who prefer the awesome power that is Lisp and
> > Scheme don't find the limited syntax to be a problem.

Kenny Tilton:
> OK, here you are saying that only a certain subset of programmers have
> the genetic makeup necessary to prefer the unlimited syntax. Unlikely.

Yes, it is very unlikely that I would say that...

Oh wait.  I didn't.

I prefer speaking in English even if Navajo might be a better language
for expressing certain concepts.  That doesn't mean that preference
is part of my genetic makeup.

I prefer the mambo basic over the salsa basic when dancing.
Doesn't mean that's part of my genetic makeup.

>    ({function | macro | special-form} arguments*) => values*
>
> Roughly speaking (I'm no BNFer) but... hellasweet! You can chant
> "simplicity" as much as you like, but /that/ is simple.

Actually, you could have a more minimal language with

    (name arguments*) => values*

but Lispers must have decided that *some* syntax makes
things easier.

And you can get still more minimal with FORTH where the
syntax is

    WORD *

> But with Lisp
> there is a great honking special form (macro?) such as "defparameter"
> that grabs you by the lapels and screams "GLOBAL!!!".

The word "global" would scream "GLOBAL!!!" a bit more.

> But most of all,
> it manages to get the job done with The One True Syntax, using a

TOTS?  If there was no need for backwards compatibility, I'll
argue that swapping [] and () would be better, since I don't need
to use shift to use the [ or ] characters.  (On a US keyboard.  And
yes, I know I could swap the keyboard layout.)  Assuming there
was no other code in the world and no other Lisp programmers,
wouldn't that be a better syntax?

> You call that "limited"? Yer just flaming.

Yes, I'm calling it limited.  I didn't say limiting, which appears to
be what you read.

No, I'm not flaming.

> But go to c.l.l. and flame the syntax and you will discover it is
something
> Lispniks love.

In case you hadn't noticed, this is cross posted on c.l.l.

I am fully aware of M-expressions for Lisp.  I know about
Dylan and it's Lispishness in a infix language.  I know that
Lispers enjoy their syntax.  I know it's the source of the ability
to support macros and other on-the-fly code manipulation.

I am not asking any of them -- nary a soul -- to abandon Lisp.
Nor am I flaming the syntax.

What I said was that Python is *not* an application of
Greespun's Tenth Rule of programming because 1) it isn't
bug-ridden, and 2) because Python explores ideas which
which had no influence on Lisp's development -- user
studies of non-professional programmers.

Where are the user studies which suggested () over [], or that
"car" is better than "first"/"1st" or that "cdr" is better than
"rest"/"rst"?

Yes, I know that the early teletypes might not have had
[ or ], and that car and cdr come from register names on
the machine Lisp was first implemented on.  If that's
indeed the justification then there may be a Lisp-ish language
which is equally as powerful, equally as elegant, etc *and*
which is slightly easier to learn and type.  But it wasn't chosen,
and it won't be used because of good social reasons: a huge
existing code base and people who now have Lisp "in their
fingers" and don't want to retrain for the slight advantage
that others might get.

"The One True Syntax" indeed.

(Okay, I admit it.  That one line was flaming *you*, but not
c.l.l'ers as a class.)

> And, as you concede, these are people who groove on the
> power of Lisp. Doesn't that make folks think they better go check out
> for themselves what these folks have discovered?

Sure.  More power to them.  For me, it looks like my
next really different language to learn might be OCaml.  ("really
different" because I needed to learn some Javascript recently,
and I don't find it different enough to give a different view of
the world.)

                    Andrew
                    ·····@dalkescientific.com
From: Daniel P. M. Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm30q6$dke$1@camelot.ccs.neu.edu>
Andrew Dalke wrote:
> [...]
> What I said was that Python is *not* an application of
> Greespun's Tenth Rule of programming because 1) it isn't
> bug-ridden, and 2) because Python explores ideas which
> which had no influence on Lisp's development -- user
> studies of non-professional programmers.

Do you know where I can find those studies?  I'm very intested in their
findings :)

By the way, what's a non-professional programmer?

> Where are the user studies which suggested () over [], or that
> "car" is better than "first"/"1st" or that "cdr" is better than
> "rest"/"rst"?
> 
> Yes, I know that the early teletypes might not have had
> [ or ], and that car and cdr come from register names on
> the machine Lisp was first implemented on.  If that's
> indeed the justification then there may be a Lisp-ish language
> which is equally as powerful, equally as elegant, etc *and*
> which is slightly easier to learn and type.  But it wasn't chosen,
> and it won't be used because of good social reasons: a huge
> existing code base and people who now have Lisp "in their
> fingers" and don't want to retrain for the slight advantage
> that others might get.

Well, if you count scheme as a lisp...

Welcome to DrScheme, version 205.3-cvs1oct2003.
Language: Pretty Big (includes MrEd and Advanced).
> [first [list 1 2 3 '[4 5]]]
1
 
- Daniel
From: Grzegorz Chrupala
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8b9e2260.0310090418.32c38181@posting.google.com>
"Daniel P. M. Silva" <······@ccs.neu.edu> wrote in message news:<············@camelot.ccs.neu.edu>...
 
> By the way, what's a non-professional programmer?

How about a person whose profession is not programming, but who often
writes computer programs?
--
G.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <kx8hb.3998$dn6.3349@newsread4.news.pas.earthlink.net>
Daniel P. M. Silva:
> Do you know where I can find those studies?  I'm very intested in their
> findings :)

Sure.  The research was done for ABC.  ABC's home page is
http://homepages.cwi.nl/~steven/abc/
    ABC is an interactive programming language and environment for
    personal computing, originally intended as a good replacement for
    BASIC. It was designed by first doing a task analysis of the
    programming task.

There's a publication list at
  http://homepages.cwi.nl/~steven/abc/publications.html

Guido, the author of Python, was involved in that project.  For his
commentary on ABC's influence on Python see:
 http://www.python.org/doc/essays/foreword.html

> By the way, what's a non-professional programmer?

The people I generally work for.  Research scientists,
usually computational chemists and computational biologists,
who need to write code but don't consider themselves to be
software developers and haven't had more than a semester
or two of formal training and would rather do more science
then spend time reading books on language practice or
theory, even if by doing so it made them more productive
in the long run.

> Welcome to DrScheme, version 205.3-cvs1oct2003.
> Language: Pretty Big (includes MrEd and Advanced).
> > [first [list 1 2 3 '[4 5]]]
> 1

Indeed?  Well I just found a mention on Paul Graham's site
that he excluded [] over () because it didn't provide enough
directionality.

Again, where's the studies?  :)

                    Andrew
                    ·····@dalkescientific.com
From: Dave Benjamin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnboa69o.lb1.ramen@lackingtalent.com>
In article <···················@newsread4.news.pas.earthlink.net>, Andrew Dalke wrote:
> Daniel P. M. Silva:
>> Do you know where I can find those studies?  I'm very intested in their
>> findings :)
> 
> Sure.  The research was done for ABC.  ABC's home page is
> http://homepages.cwi.nl/~steven/abc/
>     ABC is an interactive programming language and environment for
>     personal computing, originally intended as a good replacement for
>     BASIC. It was designed by first doing a task analysis of the
>     programming task.

Interestingly enough:

"The language is strongly-typed, but without declarations. Types are
 determined from context."
                - http://ftp.cwi.nl/abc/abc.intro

Sounds like type inference to me.

Also:

"There is no GOTO statement in ABC, and expressions do not have
side-effects."
                - http://homepages.cwi.nl/~steven/abc/teaching.html

Hints both at the statement/expression dichotomy of Python and the issue
that side-effects make it difficult to reason about a program, one of the
most important assertions made by functional proponents (IMHO).

Dave

-- 
.:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g   l i f e   o u t   o f   t h e   c o n t a i n e r :
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <BVbhb.25956$pv6.19338@twister.nyc.rr.com>
Andrew Dalke wrote:


> What I said was that Python is *not* an application of
> Greespun's Tenth Rule of programming because 1) it isn't
> bug-ridden, and 2) because Python explores ideas which
> which had no influence on Lisp's development -- user
> studies of non-professional programmers.

I wouldn't take the Greenspun crack too seriously. That's about 
applications recreating Lisp, not languages copying Lisp features. It's 
just a reaction to Python (a perfectly nice little scripting language) 
trying to morph into a language with the sophistication of Lisp.

As for non-professional programmers, the next question is whether a good 
language for them will ever be anything more than a language for them. 
Perhaps Python should just stay with the subset of capabalities that 
made it a huge success--it might not be able to scale to new 
sophistication without destroying the base simplicity.

Another question is whether Lisp would really be such a bad program for 
them.

You presume that only Lisp gurus can learn Lisp because of the syntax. 
But methinks a number of folks using Emacs Elisp and Autocad's embedded 
Lisp are non-professionals. And let's not forget Symbolic Composer 
(music composition) or Mirai (?) the 3D modelling/animation tool, both 
of which are authored at the highest level with Lisp.

Logo (a language aimed at children, including very young children) cuts 
both ways: it's a Lisp, but it dumped a lot of the parens, but then 
again it relies more on recursion.

You (Alex?) also worry about groups of programmers and whether what is 
good for the gurus will be good for the lesser lights. What you are 
saying is that the guru will dazzle the dorks with incomprehensible 
gobbledygook. That does happen, but those kinds of gurus should be fired.

To the contrary, macros in the hand of truly talented developers allow 
the gurus to build Lisp up to a higher-level language with new 
domain-specific constructs to empower the rest of the team.

You dissed Brooks in an earlier article (in favor of a Redmund Clone, of 
all things) but you should go back and read him again. Especially No 
Silver Bullet and NSB Revisited. He has a lot of great insights in 
there. (Your Redmond boy is counting LOC to assess languages, apparently 
because he can understand counting LOC. hmmm....)

Brooks talks about productivity coming from greater expressive power, 
from having the language more capable of expressing things at the same 
level at which the programmer is thinking. (He also touts Interlisp at 
one point!) But in NSB he says languages have reached the conceptual 
sophistication of their users. What Brooks missed (despite his awareness 
of Interlisp, which he dug because of its interactivity) is what few 
people understand, again, that macros let you build a domain-specific 
HLL on top of Lisp.

On a suffciently large project (well, there's another point: with Lisp 
one does not hire ten people (unless one is doing three projects)) the 
team should be divided into those who will be building the 
domain-specific embedded language and those who will be using it. 
Ideally the latter could be not just non-professional programmers, but 
even non-programmers.

> 
> Where are the user studies which suggested () over [], or that
> "car" is better than "first"/"1st" or that "cdr" is better than
> "rest"/"rst"?

Studies. You use that word so much. A good study is hard to find. You 
loved McConnel's LOC nonsense, but it is worthless. Ooooh, numbers! Look 
at all the numbers! [why [dont you] [just] [type out [a form [with [lots 
of brackets]]] and [see what [they [look [like]]]]?

They [ook [ike He[[.

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yIchb.25963$pv6.4679@twister.nyc.rr.com>
Kenny Tilton wrote:
> 
> 
> Andrew Dalke wrote:
> 
> 
>> What I said was that Python is *not* an application of
>> Greespun's Tenth Rule of programming because 1) it isn't
>> bug-ridden, and 2) because Python explores ideas which
>> which had no influence on Lisp's development -- user
>> studies of non-professional programmers.

Speaking of non-pros:

"Lisp is easy to learn

Lisp's syntax is simple, compact and spare. Only a handful of �rules� 
are needed. This is why Lisp is sometimes taught as the first 
programming language in university-level computer science courses. For 
the composer it means that useful work can begin almost immediately, 
before the composer understands much about the underlying mechanics of 
Lisp or the art of programming in general. In Lisp one learns by doing 
and experimenting, just as in music composition. "

From: http://pinhead.music.uiuc.edu/~hkt/nm/02/lisp.html

No studies, tho.

kenny

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm3pbf$tsa$1@f1node01.rhrz.uni-bonn.de>
Kenny Tilton wrote:

> Speaking of non-pros:
> 
> "Lisp is easy to learn
> 
> Lisp's syntax is simple, compact and spare. Only a handful of �rules� 
> are needed. This is why Lisp is sometimes taught as the first 
> programming language in university-level computer science courses. For 
> the composer it means that useful work can begin almost immediately, 
> before the composer understands much about the underlying mechanics of 
> Lisp or the art of programming in general. In Lisp one learns by doing 
> and experimenting, just as in music composition. "
> 
> From: http://pinhead.music.uiuc.edu/~hkt/nm/02/lisp.html
> 
> No studies, tho.

Here they are: http://home.adelphi.edu/sbloch/class/hs/testimonials/

(This is about Scheme.)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Ypghb.26946$pv6.19958@twister.nyc.rr.com>
Pascal Costanza wrote:
> Kenny Tilton wrote:
> 
>> Speaking of non-pros:
>>
>> "Lisp is easy to learn
>>
>> Lisp's syntax is simple, compact and spare. Only a handful of �rules� 
>> are needed. This is why Lisp is sometimes taught as the first 
>> programming language in university-level computer science courses. For 
>> the composer it means that useful work can begin almost immediately, 
>> before the composer understands much about the underlying mechanics of 
>> Lisp or the art of programming in general. In Lisp one learns by doing 
>> and experimenting, just as in music composition. "
>>
>> From: http://pinhead.music.uiuc.edu/~hkt/nm/02/lisp.html
>>
>> No studies, tho.
> 
> 
> Here they are: http://home.adelphi.edu/sbloch/class/hs/testimonials/
> 

Oh, please:

"My point is... before I started teaching Scheme, weak students would 
get overwhelmed by it all and would start a downward spiral. With 
Scheme, if they just keep plugging along, weak students will have a 
strong finish. And that's a great feeling for both of us!"

That kind of anecdotal crap is meaningless. We need statistics! 
Preferably with lots of decimal places so we know they are accurate.

:)

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Matthias
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <36w65iyjmyp.fsf@chagall.ti.uni-mannheim.de>
Kenny Tilton <·······@nyc.rr.com> writes:

> Pascal Costanza wrote:
> >> No studies, tho.
> > Here they are: http://home.adelphi.edu/sbloch/class/hs/testimonials/
> 
> Oh, please:
> 
> "My point is... before I started teaching Scheme, weak students would
> get overwhelmed by it all and would start a downward spiral. With
> Scheme, if they just keep plugging along, weak students will have a
> strong finish. And that's a great feeling for both of us!"
> 
> That kind of anecdotal crap is meaningless. We need statistics!
> Preferably with lots of decimal places so we know they are accurate.
> 
> :)

Why the smiley?  Many hours of discussions could be spared if there
were real, scientific, solid studies on the benefit of certain
language features or languages in certain domains or for certain types
of programmers.  It would help get successful languages become
accepted in slow/big/dump organizations.  It would point language
designers in the right directions. Project leaders could replace
trail-and-error by more efficient search techniques.  (Assuming for a
second, programmers or managers would make rational decisions when
choosing a programming language and having available trustworthy
data.)

I imagine such studies are quite hard to do properly, but having them
would be useful.
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <12ihb.27180$pv6.12141@twister.nyc.rr.com>
Matthias wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Pascal Costanza wrote:
>>
>>>>No studies, tho.
>>>
>>>Here they are: http://home.adelphi.edu/sbloch/class/hs/testimonials/
>>
>>Oh, please:
>>
>>"My point is... before I started teaching Scheme, weak students would
>>get overwhelmed by it all and would start a downward spiral. With
>>Scheme, if they just keep plugging along, weak students will have a
>>strong finish. And that's a great feeling for both of us!"
>>
>>That kind of anecdotal crap is meaningless. We need statistics!
>>Preferably with lots of decimal places so we know they are accurate.
>>
>>:)
> 
> 
> Why the smiley?  


Sorry, I was still laughing to myself about that study with the lines of 
code count (and measuring the power of a language by the number of 
machine instructions per line or whatever that was).

> ...Many hours of discussions could be spared if there
> were real, scientific, solid studies on the benefit of certain
> language features or languages...

Studies schmudies. Everyone knows 10% of the people do 90% of the code 
(well it might be 5-95). Go ask them. I think they are all saying (some) 
Lisp and/or Python right now.

  in certain domains or for certain types
> of programmers. 

There's that relativism thing again. I think a good programming language 
will be good for everyone, not some. What many people do not know is 
that Lisp (macros aside!) is just a normal computer language with a 
kazillion things done better, like generic functions and special 
variables to name just two. Norvig himself talked about this, pardon my 
alziness in not scaring up that well-know URL: Python is getting to be a 
lot like Lisp, though again macros forced him into some hand-waving.

>.. It would help get successful languages become
> accepted in slow/big/dump organizations. 

Why you starry-eyed dreamer, you! Yes, here comes the PHB now waving his 
copy of Software Engineering Quarterly.

  It would point language
> designers in the right directions. Project leaders could replace
> trail-and-error by more efficient search techniques.  (Assuming for a
> second, programmers or managers would make rational decisions when
> choosing a programming language and having available trustworthy
> data.)

Careful, any more of that and the MIB will come get you and send you 
back to the planet you came from.

> 
> I imagine such studies are quite hard to do properly, but having them
> would be useful.

OK, I am smiling again at the first half of that sentence. But there is 
hope. My Cells package naturally exposes the interdependency of program 
state, something Brooks (correctly) identified as a huge problem in 
software engineering, hence his (mistaken) conviction there could be no 
magic bullet.

Now Cells can (and have been to various degrees) been ported to C++, 
Java, and Python. If those ports were done as fully as possible, such 
that they passed the regression tests used on the Lisp reference 
implementation, we could then measure productivity, because (I am 
guessing) the internal state dependencies will serve quite nicely as a 
measure of "how much" program got written by a team, one which could be 
used to compare intelligently the productivity on different projects in 
different languages. (You can't have the same team do the same project, 
and you can't use two different teams, for obvious reasons.)

kenny


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm4vg6$86r$1@newsreader2.netcologne.de>
Matthias wrote:

> Why the smiley?  Many hours of discussions could be spared if there
> were real, scientific, solid studies on the benefit of certain
> language features or languages in certain domains or for certain types
> of programmers.

This presumes that language features can be judged in isolation. I think 
it's rather more likely that good programming languages are holistic 
systems, in the sense that the whole language is more than the sum of 
its features.


Pascal
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <CzBhb.195654$hE5.6616658@news1.tin.it>
Pascal Costanza wrote:

> Matthias wrote:
> 
>> Why the smiley?  Many hours of discussions could be spared if there
>> were real, scientific, solid studies on the benefit of certain
>> language features or languages in certain domains or for certain types
>> of programmers.
> 
> This presumes that language features can be judged in isolation. I think
> it's rather more likely that good programming languages are holistic
> systems, in the sense that the whole language is more than the sum of
> its features.

...and/or less, if N features are just offering N different ways to
perform essentially the same tasks, of course.  Still, be the whole
more or less than "the sum of the parts", one still can't rule out
(as no "hard-scientific studies" are ever likely to exist) such
non-linearities and complications.  This, of course, points out that
programming languages are NOT "mathematics", as some claim -- they
are engineering designs, and interact with human minds, sociology
of groups, cultural and educational features, at least as much as
they interact with the architecture and capabilities of computers.


Alex
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <11khb.4433$dn6.944@newsread4.news.pas.earthlink.net>
Pascal Costanza:
> Here [are some studies on using Scheme to teach programming]:
> http://home.adelphi.edu/sbloch/class/hs/testimonials/

Actually, those are testimonials, not studies.  For real studies,
look at some of the Smalltalk and especially Papert's work with
Logo.

The problem with testimonials is they are submitted by the people
who liked the language.  Eg, you don't see testimonials for a diet
loss plan which go "I used this plan and I gained 30 pounds in
only two weeks -- I loved it!"

One of my house mates in grad school learned Scheme at CMU
and related how much he didn't like the language.  You don't see
his testimonial on this site because he didn't dislike it intensely
enough to write an essay and convince some pro-Scheme site
to host it.

                    Andrew
                    ·····@dalkescientific.com
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <BXjhb.4430$dn6.297@newsread4.news.pas.earthlink.net>
Kenny Tilton:
> I wouldn't take the Greenspun crack too seriously. That's about
> applications recreating Lisp, not languages copying Lisp features.

Are you stating that all references of Greenspun's 10th rule,
when applied to Python, are meant in jest?  Many of the times
I've seen it used has come from a sense of arrogance; justified
or not.  The similar statement which bristles me the most is at the
top of biolisp.org, especially given how paltry the existing public
libraries are for doing bioinformatics in Lisp -- even compared
to Ruby.

> It's
> just a reaction to Python (a perfectly nice little scripting language)
> trying to morph into a language with the sophistication of Lisp.

Python isn't doing that.  It's lives in a perfectly good niche wherein
Lisp is not the most appropriate language.  At least not until there's a
macro which works like

(#python '
for i in range(100):
  print "Spam, ",
print
)

> As for non-professional programmers, the next question is whether a good
> language for them will ever be anything more than a language for them.
> Perhaps Python should just stay with the subset of capabalities that
> made it a huge success--it might not be able to scale to new
> sophistication without destroying the base simplicity.

But there's no reason to stay with only one language.  For those things
which are more appropriate in a different language (eg, adding a new
minimizer to an existing FORTRAN library, or writing an interface
to an existing C llibrary, or doing predicate based logic in Prolog)
then use that other language

I'm perfectly satisfied with claiming that Python is a great language
for scientific programming and that it is a less than perfect language
for doing aspect oriented programming.

> Another question is whether Lisp would really be such a bad program for
> them.

I am also perfectly satisfied with claiming that Lisp is not the best
language for the people I work with.

> You presume that only Lisp gurus can learn Lisp because of the syntax.

Not at all.  What I said is that Lisp gurus are self-selected to be
the ones who don't find the syntax to be a problem.  You incorrectly
assumed the converse to be true.

> But methinks a number of folks using Emacs Elisp and Autocad's embedded
> Lisp are non-professionals.

Methinks there are a great many more people using the VBA
interface to AutoCAD than its Lisp interface.  In fact, my friends
(ex-Autodesk) told me that's the case.

> And let's not forget Symbolic Composer
> (music composition) or Mirai (?) the 3D modelling/animation tool, both
> of which are authored at the highest level with Lisp.

As compared to csound (music synthesis) which is written in C?
Or Gnumeric with Python embedded?

Do you want me to truck out a similar list of programs with
Python embedded?  And that would prove ... what exactly?

> Logo (a language aimed at children, including very young children) cuts
> both ways: it's a Lisp, but it dumped a lot of the parens, but then
> again it relies more on recursion.

Okay, and then there's Alice, from www.alice.org , which
"addresses the specific needs of the subpopulation of middle
school girls" and aims to "provide the best possible first exposure
to programming for students ranging from middle schoolers
to college students."

What does it mean to be "a Lisp"?  Is Python considered "a Lisp"
for some definitions of Lisp?  If Greenspun's 10th law has any merit
whatsover then Python must surely be an "implementation of half
of Common Lisp."

> You (Alex?) also worry about groups of programmers and whether what is
> good for the gurus will be good for the lesser lights.

If you ever hear me call anyone who is not an expert programmer
a "lesser light" then I give you -- or anyone else here -- permission
to smack me cross-side the head.  The people I work for, who use
the software I write, are PhD-level chemists and biologists, who
are developing new drugs, who helped sequence the human genome,
and some of who may in a decade or two receive the Nobel prize
for their efforts.  These are not "lesser lights."

I never, ever, EVER made that claim and you are sticking words
in my mouth.  You consistently and incorrectly restate others'
claims into an obviously wrong-headed viewpoint that all it does
is highlight your own false assumptions and arrogance.

                    Andrew
                    ·····@dalkescientific.com
From: Daniel Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Pine.GSO.4.58.0310091729050.20757@denali.ccs.neu.edu>
On Thu, 9 Oct 2003, Andrew Dalke wrote:
> Python [...] lives in a perfectly good niche wherein
> Lisp is not the most appropriate language.  At least not until there's a
> macro which works like
>
> (#python '
> for i in range(100):
>   print "Spam, ",
> print
> )

There is! http://spyweb.hopto.org

:D

- Daniel
From: A.M. Kuchling
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <9J-dneXG4vKIlhuiRTvU2Q@speakeasy.net>
On Thu, 09 Oct 2003 20:56:01 GMT, 
	Andrew Dalke <······@mindspring.com> wrote:
> or not.  The similar statement which bristles me the most is at the
> top of biolisp.org, ...

Yee-*ouch*.  For those not reading the site: it modifies an aphorism from
Henry Spencer to "Those who do not know Lisp are condemned to reinvent
it.... poorly," and hyperlinks it to biopython.org.  Tacky. Sheesh, the
Perl/Python squabbling has pretty much died down these days; maybe they
missed the memo.

--amk
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Edlhb.27853$pv6.6215@twister.nyc.rr.com>
Andrew Dalke wrote:
> Kenny Tilton:
> 
>>I wouldn't take the Greenspun crack too seriously. That's about
>>applications recreating Lisp, not languages copying Lisp features.
> 
> 
> Are you stating that all references of Greenspun's 10th rule,
> when applied to Python, are meant in jest? 

Can't speak for others, but it certainly would be a mistake to apply it 
to another HLL.


> Python isn't doing that.  It's lives in a perfectly good niche wherein
> Lisp is not the most appropriate language.

OK, another Pythonista just told me GVR had greater ambitions. Just 
tellin ya what I hear.



>>You presume that only Lisp gurus can learn Lisp because of the syntax.
> 
> 
> Not at all.  What I said is that Lisp gurus are self-selected to be
> the ones who don't find the syntax to be a problem.  You incorrectly
> assumed the converse to be true.

No, I got that, but I just wrote it kinda convoluted. And that 
self-selection thing is just silly, until people over here:

    http://alu.cliki.net/Kenny's%20RtLS%20Top-Ten

...come back in a month and update their responses to say "Drat! That 
language is every bit as great as I thought it was, but that syntax is 
driving me nuts. I'm outtahere!"

Won't happen, btw. Hell, Tolton loved Lisp even before he picked up some 
editing tips.

You know, I just remembered a relevant experience I had, only with a 
very early release of Dylan during the search I conducted which led to 
Common Lisp, aka The Promised Land.

I actually made a bug report to the Dylan team: "hey, when I hit tab the 
cursor jumps way the hell out here, just inside the IF. I mean, that's 
pretty fucking cool if you meant that to happen, but what's going on?"

:)


> 
> 
>>But methinks a number of folks using Emacs Elisp and Autocad's embedded
>>Lisp are non-professionals.
> 
> 
> Methinks there are a great many more people using the VBA
> interface to AutoCAD than its Lisp interface.  In fact, my friends
> (ex-Autodesk) told me that's the case.

Sheesh, who hasn't been exposed to basic? From my generation, that is. 
:) But no matter, the point is anyone can handled parens if they try for 
more than an hour.


> What does it mean to be "a Lisp"?  Is Python considered "a Lisp"
> for some definitions of Lisp?

lessee:

symbols? no
sexprs? no
code as data as code? no

sorry, charlie.


>>You (Alex?) also worry about groups of programmers and whether what is
>>good for the gurus will be good for the lesser lights.
> 
> 
> If you ever hear me call anyone who is not an expert programmer
> a "lesser light" then I give you -- or anyone else here -- permission
> to smack me cross-side the head.

Boy, you sure can read a lot into a casually chosen cliche. But can we 
clear up once and for all whether these genius scientists are or are not 
as good a programmer as you? I thought I heard Python being recommended 
as better for non-professional programmers.

Mind you, to my horror my carefully trained goalie turned out not to 
scale at all into game play (my fault) so i am back to square one with 
two days to go, so maybe I am not following all this as well as I should.


-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <k3Chb.195815$hE5.6623121@news1.tin.it>
Kenny Tilton wrote:
   ...
>>>But methinks a number of folks using Emacs Elisp and Autocad's embedded
>>>Lisp are non-professionals.
>> 
>> Methinks there are a great many more people using the VBA
>> interface to AutoCAD than its Lisp interface.  In fact, my friends
>> (ex-Autodesk) told me that's the case.
> 
> Sheesh, who hasn't been exposed to basic? From my generation, that is.
> :) But no matter, the point is anyone can handled parens if they try for
> more than an hour.

Yes, but will that make them most happy or productive?  The Autocad
case appears to be relevant, though obviously only Autodesk knows
for sure.  When I was working in the mechanical CAD field, I had
occasion to speak with many Autocad users -- typically mechanical
drafters, or mechanical or civil engineers, by training and main working
experience -- who HAD painfully (by their tales) learned to "handle
parens", because their work required them occasionally to write Autocad
macros and once upon a time Autolisp was the only practical way to do it --
BUT had jumped ship gleefully to the VBA interface, happily ditching
years of Autolisp experience, just as soon as they possibly could (or
earlier, i.e. when the VBA thingy was very new and still creaky in its
integration with the rest of Autocad -- they'd rather brave the bugs
of the creaky new VBA thingy than stay with the Autolisp devil they
knew).  I don't know if syntax was the main determinant.  I do know
that quite a few of those people had NOT had any previous exposure to
any kind of Basic -- we're talking about mechanics-junkies, more likely
to spend their spare time hot-rodding their cars at home (Bologna is,
after all, about 20 Km from Ferrari, 20 Km on the other side from
Minardi, while the Ducati motorcycle factory is right here in town,
etc -- *serious* mechanics-freaks country!), rather than playing with
the early home computers, or program for fun.

So, I think Autocad does prove that non-professional programmers
(mechanical designers needing to get their designs done faster) CAN
learn to handle lisp if no alternatives are available -- and also
that they'd rather not do so, if any alternatives are offered.  (I
don't know how good a lisp Autolisp is, anyway -- so, as I mentioned,
there may well be NON-syntactical reasons for those guys' dislike
of it despite years of necessarily using it as the only tool with
which they could get their real job done -- but I have no data that
could lead me to rule out syntax as a factor, at least for users
who were OCCASIONAL users anyway, as programming never was their
REAL, MAIN job, just means to an end).


>>>You (Alex?) also worry about groups of programmers and whether what is
>>>good for the gurus will be good for the lesser lights.
>> 
>> If you ever hear me call anyone who is not an expert programmer
>> a "lesser light" then I give you -- or anyone else here -- permission
>> to smack me cross-side the head.
> 
> Boy, you sure can read a lot into a casually chosen cliche. But can we
> clear up once and for all whether these genius scientists are or are not
> as good a programmer as you? I thought I heard Python being recommended
> as better for non-professional programmers.

Dunno 'bout Andrew, but -- if the scientists (or their employers) are
paying Andrew for programming consultancy, training, and advice, would
it not seem likely that they consider that he's better at those tasks
than they are...?  Otherwise why would they bother?  Most likely the
scientists are better than him at _other_ intellectual pursuits -- be
it for reasons of nature, nurture, or whatever, need not interest us
here, but it IS a fact that some people are better at some tasks.
There is too much programming to be done, to let ONLY professional
programmers do it -- just like there's too much driving to be done, to
let only professional drivers do it -- still, the professionals can be
expected to be better at their tasks of specialistic expertise.


Alex
From: Kenny Tilton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bcEhb.69236$lZ6.10754493@twister.nyc.rr.com>
Alex Martelli wrote:

> drafters, or mechanical or civil engineers, by training and main working
> experience -- who HAD painfully (by their tales) learned to "handle
> parens",

Sound like they did not have parens-aware editors. Those do more than 
just show you the matching parens of the one beside the cursor, they 
also let you select code in the semantic chunks which are naturally 
aligned with diff levels of paired parens.

Now one of my keys to success is that I refactor /a lot/. That means my 
code is always Moving Toward the Light. So I never have to fuss with 
badly design code, I just refactor it. And this usually means moving 
existing code around, and deleting code that becomes obsolete as the 
design improves. So I am forever dragging chunks of code around, of 
various levels of nesting.

Now the incredible thing is that I can look a nested branch of an if 
statement (whose condition has just gotten factored out of existence) 
and double-click on the opening parens. I do not even have to go find 
the closing parens, the editor finds that and selects thru to that 
automatically.

Now I just cut and do the same thing on the whole if statement (which by 
now is a lot smaller) selecting that and the obsolete other branch with 
a single click. Paste. Miller time. Oops, I forgot ctrl-shift-p to 
automatically reindent the whole region.

Can Python do that?

I think we can summarize by saying macros are powerful, but you have 
seen a group of groups use them in different ways and cause confusion. 
OTOH, the Lispniks here have no idea what you are talking about, and we 
live with the little suckers. <cue andrew and his self-selection 
hand-waving.>

We probably also agree that 5% of the programmers in a group do 95% of 
the work, so what do you want to do? Worry about the unproductive 95% or 
empower the productive 5%?

The one thing organizations could do better is divide things up so the 
best programmers empowered the lesser lights, by having them create a 
domain-specific language on top of the host HLL, for the others to use.

Can Python do that?

Well, as you said a while ago, any Pythonista who wants powerful macros 
should Just Use Lisp. I agree.

I also agree with Marco: methinks it time to let this horse rest in 
peace, so the last word is yours.

kenny

ps. I was so delighted by Andrew's shenanigans with the (I'm guessing) 1 
3 6 4 2 5 thing that I did some staring myself. Six things give you 
fifteen comparisons. In the real list, five instances of 
worse-before-better can be found. ie, the metric failed one time in 
three. Now instead of getting fancy with statistics, can't we just say 
the metric sucks? Too unscholarly? Whats the Latin for that? We can 
dress it up. Well, I guess this is what statistics are for. When you 
have done all the research and collected all the numbers and the results 
  reveal the protocol itself was a flop, play with stats until you come 
up with a result to wave around? Beats tossing the whole study, I guess.

k

-- 
http://tilton-technology.com
What?! You are a newbie and you haven't answered my:
  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87brspzsg3.fsf@thalassa.informatimago.com>
"Andrew Dalke" <······@mindspring.com> writes:
> > It's
> > just a reaction to Python (a perfectly nice little scripting language)
> > trying to morph into a language with the sophistication of Lisp.
> 
> Python isn't doing that.  It's lives in a perfectly good niche wherein
> Lisp is not the most appropriate language.  At least not until there's a
> macro which works like
> 
> (#python '
> for i in range(100):
>   print "Spam, ",
> print
> )

This is trivial:

(DEFUN SPLIT-ARGUMENTS (STRING)
  (DO ((CHUNKS '()) (START 0) (POS 0))
      ((<= (LENGTH STRING) POS)
       (PROGN (WHEN (< START POS) (PUSH (SUBSEQ STRING START POS) CHUNKS))
              (NREVERSE CHUNKS)))
    (IF (CHAR= (CHAR STRING POS) (CHARACTER " "))
      (PROGN (WHEN (< START POS) (PUSH (SUBSEQ STRING START POS) CHUNKS))
             (INCF POS) (SETQ START POS))
      (INCF POS)))
  );;SPLIT-ARGUMENTS


(SET-DISPATCH-MACRO-CHARACTER
 (CHARACTER "#") (CHARACTER "!")
 (LAMBDA (STREAM CHAR ARG)
   (DECLARE (IGNORE CHAR ARG))
   ;; first read the interpreter path and arguments.
   ;; next read the script up to a line beginning with "!#".
   ;; then generate statements to the interpreter and feed it the script.
   (DO ((INTERPRETER (SPLIT-ARGUMENTS (READ-LINE STREAM NIL NIL T)))
        (SCRIPT '())
        (LINE (READ-LINE STREAM NIL NIL T)
              (READ-LINE STREAM NIL NIL T)))
       ((AND (<= 2 (LENGTH LINE)) (STRING= "!#" LINE :END2 2))
        `(LET ((INTERP-INPUT (EXT:RUN-PROGRAM ,(CAR INTERPRETER)
                               :ARGUMENTS ',(CDR INTERPRETER)
                               :INPUT :STREAM :OUTPUT :TERMINAL)))
           ;; Sorry, clisp specific. Please replace ext:run-program by
           ;; your favorite hook.
           (DOLIST (LINE ',(NREVERSE SCRIPT))
             (FORMAT INTERP-INPUT "~A~%" LINE))
           (CLOSE INTERP-INPUT)))
     (PUSH LINE SCRIPT))))



[27]> #!/usr/bin/python
for i in range(100):
  print "Spam, ",
print ""
!#


T
[28]> Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  


Therefore Python lives  in a perfectly good niche  wherein Lisp IS the
most appropriate language. QED you can forget Python.



And  of course,  while  trivial  when implemented  in  Lisp, it's  so
powerfull it's not limited to python:

[29]> #!/bin/bash
ls -m *.lisp
!#

T
[31]> ai.lisp, antispam-test.lisp, antispam.lisp, ascii.lisp, basic.lisp, 
benford.lisp, bits-old.lisp, bits.lisp, bottle.lisp, brent.lisp, c-order.lisp, 
clos-test.lisp, clx-sample.lisp, clx-tutorial.lisp, compare-lts.lisp, 
copy-over.lisp, dbc.lisp, ddj-combin.lisp, dec.lisp, def-if-undef.lisp, 
defstrmacro.lisp, deriv.lisp, diagram.lisp, directory-and-pathname.lisp, 
dot.clisprc.lisp, douze.lisp, exemple-cloture.lisp, expert.lisp, fast-io.lisp, 
fibonacci.lisp, fixed-point.lisp, four.lisp, html.lisp, ib.lisp, ig.lisp, 
inferior-lisp.lisp, integ.lisp, lecture-au-vol.lisp, lisp1-in-cl.lisp, 
livre-qui-rend-fou.lisp, lpt-bug.clisprc.lisp, marienbad.lisp, num.lisp, 
old-marienbad.lisp, packages.lisp, pg-psql.lisp, pg.lisp, pi.lisp, 
picture-test.lisp, posix-dirent.lisp, protocoles.lisp, pttp-1i.lisp, 
python.lisp, quine.lisp, scratch.lisp, sdraw.lisp, sum.lisp, symbol.lisp, 
test-format.lisp, test-special.lisp, test.lisp, text.lisp, tree.lisp, 
turing.lisp, wang.lisp, word-count.lisp



Personnaly, I prefer to write, consistently:
    
    (dotimes (i 100)
       (format t "Spam, ")) 
    (format t "~%")


That is, consistently with the rest of my programs.

The question being whether it's better to be needing several different
languages to solve a set of problems because none of them languages is
powerful  enough, or  if it's  better to  have one  good  and powerful
language that helps you solve all your problems?

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Daniel P. M. Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm5asg$c7k$1@camelot.ccs.neu.edu>
Pascal Bourguignon wrote:
> "Andrew Dalke" <······@mindspring.com> writes:
>> > It's
>> > just a reaction to Python (a perfectly nice little scripting language)
>> > trying to morph into a language with the sophistication of Lisp.
>> 
>> Python isn't doing that.  It's lives in a perfectly good niche wherein
>> Lisp is not the most appropriate language.  At least not until there's a
>> macro which works like
>> 
>> (#python '
>> for i in range(100):
>>   print "Spam, ",
>> print
>> )
> 
> This is trivial:
> 
> (DEFUN SPLIT-ARGUMENTS (STRING)
>   (DO ((CHUNKS '()) (START 0) (POS 0))
>       ((<= (LENGTH STRING) POS)
>        (PROGN (WHEN (< START POS) (PUSH (SUBSEQ STRING START POS) CHUNKS))
>               (NREVERSE CHUNKS)))
>     (IF (CHAR= (CHAR STRING POS) (CHARACTER " "))
>       (PROGN (WHEN (< START POS) (PUSH (SUBSEQ STRING START POS) CHUNKS))
>              (INCF POS) (SETQ START POS))
>       (INCF POS)))
>   );;SPLIT-ARGUMENTS
> 
> 
> (SET-DISPATCH-MACRO-CHARACTER
>  (CHARACTER "#") (CHARACTER "!")
>  (LAMBDA (STREAM CHAR ARG)
>    (DECLARE (IGNORE CHAR ARG))
>    ;; first read the interpreter path and arguments.
>    ;; next read the script up to a line beginning with "!#".
>    ;; then generate statements to the interpreter and feed it the script.
>    (DO ((INTERPRETER (SPLIT-ARGUMENTS (READ-LINE STREAM NIL NIL T)))
>         (SCRIPT '())
>         (LINE (READ-LINE STREAM NIL NIL T)
>               (READ-LINE STREAM NIL NIL T)))
>        ((AND (<= 2 (LENGTH LINE)) (STRING= "!#" LINE :END2 2))
>         `(LET ((INTERP-INPUT (EXT:RUN-PROGRAM ,(CAR INTERPRETER)
>                                :ARGUMENTS ',(CDR INTERPRETER)
>                                :INPUT :STREAM :OUTPUT :TERMINAL)))
>            ;; Sorry, clisp specific. Please replace ext:run-program by
>            ;; your favorite hook.
>            (DOLIST (LINE ',(NREVERSE SCRIPT))
>              (FORMAT INTERP-INPUT "~A~%" LINE))
>            (CLOSE INTERP-INPUT)))
>      (PUSH LINE SCRIPT))))
> 
> 
> 
> [27]> #!/usr/bin/python
> for i in range(100):
>   print "Spam, ",
> print ""
> !#
> 
> 
> T
> [28]> Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,
> [ Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam, 
> [Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,  Spam,
> 
 
I think Andrew probably meant something more complicated, like this:

(define add-n (#python ' lambda x: x + LISP.top.n.python_value() '))

(define n 1)

(python-number->LISP-number (add-n 1)) ; 2
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <aYwhb.258797$R32.8391498@news2.tin.it>
Pascal Bourguignon wrote:
   ...
> The question being whether it's better to be needing several different
> languages to solve a set of problems because none of them languages is
> powerful  enough, or  if it's  better to  have one  good  and powerful
> language that helps you solve all your problems?

A reasonably good way to highlight the key difference between the "horses
for courses" and "one ring to bind them all" schools of thought.

Would I rather have just one means of transportation "powerful enough"
to help me solve all my "going from A to B" problems?  Nope! I want a
bicycle for going short and middle distances on sunny days, a seat on
a reasonably fast jet plane for much longer trips, and several things
in-between.  A single ``thing'' able to cater for such hugely disparate
needs would be way too complicated to be an optimal solution to any
single one of them.

Would I rather have just one woodworking tool "powerful enough" to help
me solve all my "working wood" problems?  No way!  A suitably large
and complicated "Swiss Army Knife" may be handy in emergencies, but in
my little woodworking shop I want several separate, optimized tools, each
optimized for its own range of tasks.  A single "multi-blade" tool able
to cater for all of the disparate needs that arise in working wood would
be way too complicated and unwieldy to be an optimal solution to any
single one of them.

Do I want a single writing tool, or separate pencils, pens, markers,
highlighters...?  Do I want a single notation to write down ANYthing
on paper, or separate ones for music, algebraic formulas, shopping
lists, accounting, ...?  Do I want a single font to be used for ANY
writing, from books to billboards to shops' signs to handwriting...?

More generally, are there ANY situations in which "one size fits all"
is a GOOD, OPTIMAL solution, rather than a make-do approach?  Maybe
some can be found, but it seems to me that in most cases a range of
tools / solutions / approaches tailored to different classes of
problems may well be preferable.  So, it should come as no surprise
that I think this applies to computer languages.  In fact I am
sometimes amazed at how wide a range of problems I can solve quite
well with Python -- but I still want C for e.g. device drivers,
spreadsheets to "program" simple what-if scenarios and play around
interactively with parameters, make (or one of its successors, such
as SCons), bash for interactively typed one-liners, HTML / SGML etc
for documents, XML for data interchange with alien apps, SQL to
access relational databases, etc, etc -- and no doubt more besides.

See http://www.strakt.com/sol_capsao_7.html for example -- not
very detailed, but a generic description of a specialized declarative
language for Entity - Relationship descriptions, with embedded
actions in procedural languages [currently, Python only], that we're
developing as part of the CAPS framework (no macros were used in the
production of that language, just traditional boring parsers &c in
Python -- of course, it IS quite possible that _the specialized
language itself_ might benefit from having macros, that's a separate
issue from the one of _implementing_ that "BLM language").


Alex
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <smm1w5kx.fsf@ccs.neu.edu>
Alex Martelli <·····@aleax.it> writes:

> Would I rather have just one means of transportation "powerful enough"
> to help me solve all my "going from A to B" problems?  Nope! I want a
> bicycle for going short and middle distances on sunny days, a seat on
> a reasonably fast jet plane for much longer trips, and several things
> in-between.  A single ``thing'' able to cater for such hugely disparate
> needs would be way too complicated to be an optimal solution to any
> single one of them.
>
> Would I rather have just one woodworking tool "powerful enough" to help
> me solve all my "working wood" problems?  No way!  A suitably large
> and complicated "Swiss Army Knife" may be handy in emergencies, but in
> my little woodworking shop I want several separate, optimized tools, each
> optimized for its own range of tasks.  A single "multi-blade" tool able
> to cater for all of the disparate needs that arise in working wood would
> be way too complicated and unwieldy to be an optimal solution to any
> single one of them.
>
> Do I want a single writing tool, or separate pencils, pens, markers,
> highlighters...?  Do I want a single notation to write down ANYthing
> on paper, or separate ones for music, algebraic formulas, shopping
> lists, accounting, ...?  Do I want a single font to be used for ANY
> writing, from books to billboards to shops' signs to handwriting...?

A single web browser?  A single editor?  A single operating system?  A
single character encoding scheme?  A single analogy?
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87pth5jf2r.fsf@thalassa.informatimago.com>
Alex Martelli <·····@aleax.it> writes:

> Pascal Bourguignon wrote:
>    ...
> > The question being whether it's better to be needing several different
> > languages to solve a set of problems because none of them languages is
> > powerful  enough, or  if it's  better to  have one  good  and powerful
> > language that helps you solve all your problems?
> 
> A reasonably good way to highlight the key difference between the "horses
> for courses" and "one ring to bind them all" schools of thought.
> 
> Would I rather have just one means of transportation "powerful enough"
> to help me solve all my "going from A to B" problems?  Nope! I want a
> bicycle for going short and middle distances on sunny days, a seat on
> a reasonably fast jet plane for much longer trips, and several things
> in-between.  A single ``thing'' able to cater for such hugely disparate
> needs would be way too complicated to be an optimal solution to any
> single one of them.

You  can  never  compare  physical  stuff  with  software  stuff.   Do
mathematicians  switch   to  a  different   mathematical  language  to
demonstrate different  algorithms?  No.  They keep the  same language,
the same formalism, because it's  powerfull enough to let them express
all  their ideas.  What's  more the  mathematical  language is  supple
enough to let them extend it when they need new abstractions.

Software is a department of mathematics.

 
> Would I rather have just one woodworking tool "powerful enough" to help
> me solve all my "working wood" problems?  No way! 

Do you change your brain when you have a different problem?  


> Do I want a single writing tool, or separate pencils, pens, markers,
> highlighters...?  Do I want a single notation to write down ANYthing
> on paper, or separate ones for music, algebraic formulas, shopping
> lists, accounting, ...?  Do I want a single font to be used for ANY
> writing, from books to billboards to shops' signs to handwriting...?
> 
> More generally, are there ANY situations in which "one size fits all"
> is a GOOD, OPTIMAL solution, rather than a make-do approach?  Maybe
> some can be found, but it seems to me that in most cases a range of
> tools / solutions / approaches tailored to different classes of
> problems may well be preferable.  So, it should come as no surprise
> that I think this applies to computer languages.  In fact I am
> sometimes amazed at how wide a range of problems I can solve quite
> well with Python -- but I still want C for e.g. device drivers,
> spreadsheets to "program" simple what-if scenarios and play around
> interactively with parameters, make (or one of its successors, such
> as SCons), bash for interactively typed one-liners, HTML / SGML etc
> for documents, XML for data interchange with alien apps, SQL to
> access relational databases, etc, etc -- and no doubt more besides.
> 
> See http://www.strakt.com/sol_capsao_7.html for example -- not
> very detailed, but a generic description of a specialized declarative
> language for Entity - Relationship descriptions, with embedded
> actions in procedural languages [currently, Python only], that we're
> developing as part of the CAPS framework (no macros were used in the
> production of that language, just traditional boring parsers &c in
> Python -- of course, it IS quite possible that _the specialized
> language itself_ might benefit from having macros, that's a separate
> issue from the one of _implementing_ that "BLM language").
> 
> 
> Alex


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <RZDhb.261891$R32.8489994@news2.tin.it>
Kenny Tilton wrote:
   ...
> As for non-professional programmers, the next question is whether a good
> language for them will ever be anything more than a language for them.

Being a professional programmer, I find Python makes me very productive
at my job -- and yet I know from experience it's also an excellent language
for non-professional programmers.  So, the experiential answer is clear to 
me.

> Perhaps Python should just stay with the subset of capabalities that
> made it a huge success--it might not be able to scale to new
> sophistication without destroying the base simplicity.

Interestingly enough, you and I probably agree on that.  I don't _want_
Python to grow in any way that would "destroy the base simplicity"; indeed,
I'm looking forward to 3.0 (even though it's probably 3 years off or so)
exactly because it may get simplified again then, shedding some accumulated
legacy baggage (there is no reason, except backwards compatibility, to
have e.g "classic classes", range, xrange, etc etc).  Any proposed new 
feature, in my opinion, must be judged strictly on the criterion of: how 
much better than today's set of features would it let us do our jobs?  If 
it provides another roughly equivalent way to perform some of the same
tasks, that's a substantial minus (as it encourages divergence of language
dialects) and must be compensated by really big advantages elsewhere.

Today's Python has the features we need to productively build ambitious 
frameworks for asynchronous network clients and servers (Twisted), spam 
filters that apparently work better than Graham's (spambayes), search 
engines (Verity Ultraseek, nee Infoseek, as wel as Google), ship-design 
optimization apps (Tribon Vitesse), commercial games (Freedom Force, EVE 
Online, Star Trek Bridge Commander...), collaborative enterprise app 
frameworks (CAPS), scientific visualization tools such as MayaVi, business 
logic for factory and tool control (IBM/Philips Fishkill plant)... oh, 
you're perfectly capable of reading the various "Python success stories"
sites and booklets yourself, I don't want to bore you TOO much:-).  The
point is, it MIGHT, as you point out, be unfeasible to "scale to new
sophistication" -- beyond the few 100,000s function points MAXIMUM of
any of these Python successes (roughly equivalent to, say, a few 10's
of millions of lines of C code), to e.g. many millions of function points.

I think the world needs LOTS AND LOTS of application programs in
the 1000-100,000 function points range -- and Python's current set of
features has proven amply sufficient to provide those without damage
to "the base simplicity" which you mention.  If many applications of
many millions FP's (roughly equivalent to a billion lines of C, or so)
are needed, I don't know -- but, if so, I share your doubts about it making
any sense to destroy Python's simplicity in an attempt to tackle THOSE
monsters, "scaling to new sophistication".


> You (Alex?) also worry about groups of programmers and whether what is
> good for the gurus will be good for the lesser lights. What you are
> saying is that the guru will dazzle the dorks with incomprehensible
> gobbledygook. That does happen, but those kinds of gurus should be fired.

That's only part of the problem, of course -- programmers who are not
quite as good as they think they are and inflict their "enhancements" to
the language to everybody else are another issue.  Maybe they should
be fired, but such turnover in the team would decrease productivity
anyway.

> On a suffciently large project (well, there's another point: with Lisp
> one does not hire ten people (unless one is doing three projects)) the

Lisp isn't able to let 10 people work together productively on the
same project?  Oh my -- now THAT would be a huge problem;-).

> team should be divided into those who will be building the
> domain-specific embedded language and those who will be using it.
> Ideally the latter could be not just non-professional programmers, but
> even non-programmers.

If they're programming (in whatever language) they can't be
non-programmers, by definition.  But anyway, this misses the key
issue: who are the *real* experts of the application domain that
your "domain-specific" language is supposed to address so well?
E.g., the *real* experts on turbo-compressor design, on optimization
of ship designs, on the business logic of tool control, on logical
and physical design of integrated circuits, etc, etc?  Answer: they
are likely to be non-professional programmers.  Are THEY designing
the domain-specific language -- or is it going to be designed by
computer scientists who don't really grasp the intricacies of turbo
compressors, ships, etc, etc?

The Agile Programming (Extreme Programming, in particular) answer 
to this enormously important issue is that the whole team, customer
included, *works together* and *collectively owns* the whole body of code.

The computer scientist learns enough about turbo compressors, and
the turbo compressor expert enough about programming, by the
incredibly productive social process of *pair-programming* -- sitting
side by side and working together at testing and building code (in
this order -- but I won't bore you with test-driven-design paeans...;-).

This holistic approach is incompatible with your favourite "the gurus
build the domain-specific language, the peons just use it" approach.
It works particularly well when the language is as simple, as good at
"getting out of your way", as Python (or, admittedly, Ruby -- I have
enormous respect for Ruby! -- though I have some issues on quite
another plane that make me keep preferring Python for this specific,
and very important to me, kind of tasks).

It surely can feel "cooler" for the Guru (uppercase G mandatory) not
to have to mingle with such low-lifes as the lusers (a Guru's favourite
spelling of "users", apparently) -- to just sit in their ivory tower 
spitting out domain-specific embedded languages for domains they
_aren't_ as expert at as the peons.  But I've seen that approach at
work (for hardware design with various lisp variants and dialects) and
don't like the results I have observed, particularly in application domains
where the intended users ARE quite expert in their field (which is the 
case for many interesting apps -- not just those targeting the people
which our society acknowledges as "respected professionals", mind you:
a good secretary knows FAR more than I ever will on how to make an
office run, a shopkeeper on how things work in a shop, etc, etc).


Alex
From: Björn Lindberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <hcszngabtw2.fsf@tjatte.nada.kth.se>
"Andrew Dalke" <······@mindspring.com> writes:

> ·············@comcast.net:
> > So either the syntax doesn't make a whole hell of a lot of difference
> > in readability, or readability doesn't make a whole hell of a lot of
> > difference in utility.
> 
> Or the people who prefer the awesome power that is Lisp and
> Scheme don't find the limited syntax to be a problem.

All evidence points to the fact that Lisp syntax is no worse than
Algol-style syntax. As Joe explained, other syntaxes have been used
for Lisp many times over the years, but lispers seem to prefer the
s-exp one. If anything, one could draw the conclusion that s-exp
syntax must be /better/ than Algol-style syntax since the programmers
who have a choice which of them to use -- for the same language --
apparently choose s-exp syntax. You really have no grounds to call
Lisp syntax limited.


Bj�rn
From: Paolo Amoroso
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87u16itoj0.fsf@plato.moon.paoloamoroso.it>
[followup to comp.lang.lisp only]

Andrew Dalke writes:

> That assertion also ignores the influence of user studies (yes,
> research into how the syntax of a language affects its readabilty
> and understandability) on Python's development; a topic which
> is for the most part ignored in Lisp.

Over 40 years of experience with a sexp-based syntax, and the failure
of alternate syntaxes proposed for Lisp, may be enough "user
study". Experienced and productive lispers do like the syntax: why
should their opinions count less than those of novices?  Lisp is not
for dummies, by design.


Paolo
-- 
Paolo Amoroso <·······@mclink.it>
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <_YBgb.180859$hE5.6097138@news1.tin.it>
Pascal Costanza wrote:

> David Eppstein wrote:
>> In article <············@newsreader2.netcologne.de>,
>>  Pascal Costanza <········@web.de> wrote:
>> 
>>>I don't know a lot about Python, so here is a question. Is something
>>>along the following lines possible in Python?
>>>
>>>(with-collectors (collect-pos collect-neg)
>>>   (do-file-lines (l some-file-name)
>>>     (if (some-property l)
>>>       (collect-pos l)
>>>       (collect-neg l))))
>>>
>>>I actually needed something like this in some of my code...
>> 
>> Not using simple generators afaik.  The easiest way would probably be to
>> append into two lists:
>> 
>>     collect_pos = []
>>     collect_neg = []
>>     for l in some_file_name:
>>         if some_property(l):
>>             collect_pos.append(l)
>>         else:
>>             collect_neg.append(l)
> 
> ...but this means that
> 
> collect = []
> for l in some_file_name
>    if some_property:
>        collect.append(l)
> 
> ...is another solution for the single collector case. Now we have two

Of course, it is; it is by definition equivalent to the list comprehension:

    collect = [l for l in some_file_name if some_property(l)]

(you do need to call some_property with l as the argument, which you're
not doing above, but I think that's what you meant to do; also, I suspect
you want to loop on open(some_file_name) -- the lines of the file, as
opposed to its name -- but that's apparently a distraction by David).

> ways to do it. Isn't this supposed to be a bad sign in the context of
> Python? I am confused...

While in Python it's deemed _preferable_ that there be "one obvious way
to do it" (for any given "it"), it's a _preference_, and there are many
cases where it just can't practically hold (practicality beats purity).

It starts with the fact that both 2+3 and 3+2 are equally-obvious ways
to sum these two numbers -- it would be quite impractical to make Python
addition non-commutative to avoid the issue;-).


>> If you needed to do this a lot of times you could encapsulate it into a
>> function of some sort:
>> 
>> def posneg(filter,iter):
>>     results = ([],[])
>>     for x in iter:
>>         results[not filter(x)].append(x)
>>     return results
>> 
>> collect_pos,collect_neg = posneg(some_property, some_file_name)
> 
> What about dealing with an arbitrary number of filters?
   ...
>  > (predicate-collect '(-5 -4 -3 -2 -1 0 1 2 3 4 5)
>      (function evenp)
>      (lambda (n) (< n 0))
>      (lambda (n) (> n 3)))
> (-4 -2 0 2 4)
> (-5 -3 -1)
> (5)
> (1 3)

I think I would code this as follows:

def collect_by_first_predicate(finite_sequence, *predicates):
    # a utility predicate that's always satisfied
    def always(any): return True
    # len(predicates) + 1 lists to collect the various results
    results = [ [] for i in range(len(predicates)+1) ]
    collectors = [ (pred, result.append)
                   for pred, result in zip(predicates+(always,), results) ]
    for item in finite_sequence:
        for pred, collect in collectors:
            if pred(item):
                collect(item)
                break
    return results

print collect_by_first_predicate(range(-5, 6),
    lambda n: n%2==0,
    lambda n: n<0,
    lambda n: n>3)

this does emit, as desired,

[[-4, -2, 0, 2, 4], [-5, -3, -1], [5], [1, 3]]

however, this approach has some very serious limitations for certain
applications: in particular, both the sequence AND the number of
predicates absolutely HAVE to be finite.  There even isn't any way
to _express_ an infinite (unbounded) family of predicates as separate
arguments to a function; so if you wanted to use such an approach to
classify the items of finite_sequence by a family of predicates where, 
e.g., pred(i) asserts that the item is >10**i, for all i>0, you could not
use this approach (nor, I suspect, could you use your predicate-collect
approach for such purposes -- or am I missing something?).  To accept
an infinite family of predicates I would have to change the arguments
(so e.g. the second would be an iterator for said infinite family) to
start with.  The first 'sequence' argument COULD syntactically be an
infinite (unbounded) iterator, e.g. itertools.count() [the sequence
of all naturals, 0 upwards] -- but then the "for item in finite_sequence:"
loop inside the function would not terminate.

Pushing aside, for the moment, the issue of infinite numbers of
predicates, let's consider how best to deal with a finite number N
of predicates applied to a potentially unbounded/infinite sequence.
As such sequences, in Python, are represented by iterators, we
will presumably need to return N+1 iterators to represent the
"subsequences" -- one per predicate plus the "none of the above" one.

This is actually still somewhat tricky in terms of definition.
Suppose the predicates were, e.g.:
    lambda n: n>0
    lambda n: n<0
and the unbounded sequence contained no 0's.  Then, if and when
the called tried to get the "next item" of the "none of the above"
(third) returned iterator -- that would never return, forevermore
looping on the input sequence and looking uselessly for the 0
that would escape both of the predicates.  Alas, lazy computation
on unbound sequences DOES do this kind of things to you, at times.
As we can't solve the halting problem, we can't prevent it either,
in general.  So, I think we just need to live with the possibility
that any of the returned iterators may "hang" forever, depending
on the predicates and the (unbounded) input sequence.

Apart from this problem, there's another interesting issue.  When
the .next method gets called on any of the iterators we return,
which has no knowledge yet of its next item, we'll go through the
next items of the input sequence -- but that will produce items
to be returned as part of OTHER iterators, in general, before it
yields the next item for "this one".  So, SOME mechanism must
remember those for the future (inevitably this may require more
memory than we have, in which case, ka-boom, but this is just a
finite-machine special case of the above paragraph, in a way;-).

The natural way to do this in Python is to use class instances,
one per returned iterator, giving each of them a list to store
the "forthcoming" items of the corresponding iterator.  Might as
well make the instances the iterators themselves (just give them
the .next method, and a "def __iter__(self): return self" to
mark them as iterators).

def collect_by_first_predicate(sequence, *predicates):
    seq_iter = iter(sequence)
    def getanother():
        item = seq_iter.next()
        for collector in collectors:
            if collector.pred(item):
                collector.append(item)
                return
    class prediter(object):
        def __iter__(self): return self
        def __init__(self, pred):
            self.memory = []
            self.append = self.memory.append
            self.pred = pred
        def next(self):
            while not self.memory: getanother()
            return self.memory.pop(0)
    def always(any): return True
    collectors = [ prediter(pred) for pred in predicates+(always,) ]
    return collectors

print map(list, collect_by_first_predicate(range(-5, 6),
    lambda n: n%2==0,
    lambda n: n<0,
    lambda n: n>3)
    )

This, too, emits [[-4, -2, 0, 2, 4], [-5, -3, -1], [5], [1, 3]] , of
course (we do have to turn the returned iterators into lists to be
able to print them easily, but, here, we do know they're finite:-).


Of course, both of these implementations can easily be turned into
a collect_by_all_predicates (where an item is ranged in all collectors
corresponding to a predicate it satisfies, rather than in just one
of them) by simply omitting the return 'cut' after the collector.append
or collect(item) call in the respective for loop over collectors.


Back to the issue of potentially unbounded families of predicates
(and, thus, collectors), I think that sits badly with the concept of a
'catch-all predicate' -- if the family of predicates IS indeed
unbounded, the catch-all will never come into play.  And I'm not
sure I want to _return_ the resulting potentially unbounded family
of collectors as an iterator, necessarily -- I see use cases for
an 'indexable' ("random-access", so to speak, vs the 'sequentially
accessed' nature of iterators) return value.  So I've cobbled
together a sequence class that's basically a potentially expandable
list -- you can change the "return collectors" to
"return iter(collectors)" if you disagree with my qualms, of course.
So, here's a first sketch at a possible approach...:


class pseudo_seq_iter(object):
    def __iter__(self): return self
    def __init__(self, seq):
        self.seq = seq
        self.i = -1
    def next(self):
        self.i += 1
        try: return self.seq[self.i]
        except IndexError: raise StopIteration

def collect_by_first_predicate(sequence, predicates):
    seq_iter = iter(sequence)
    pred_iter = iter(predicates)
    def always(any): return True

    class collectors_sequence(list):
        def __getitem__(self, i):
            if i>=0:
                while i>=len(self) and (not self or self[-1].pred is not
always):
                    addapred()
                if i>=len(self): raise IndexError, i
            return list.__getitem__(self, i)
        def __iter__(self): return pseudo_seq_iter(self)
    collectors = collectors_sequence()

    def addapred():
        try: pred = pred_iter.next()
        except StopIteration: pred = always
        collectors.append(prediter(pred))

    def getanother():
        item = seq_iter.next()
        for collector in collectors:
            if collector.pred(item):
                collector.append(item)
                return

    class prediter(object):
        def __iter__(self): return self
        def __init__(self, pred):
            self.memory = []
            self.append = self.memory.append
            self.pred = pred
        def next(self):
            while not self.memory: getanother()
            return self.memory.pop(0)
    return collectors

print map(list, collect_by_first_predicate(range(-5, 6),
        [ lambda n: n%2==0,
          lambda n: n<0,
          lambda n: n>3
        ]
    ))

class divisible_by(object):
    def __init__(self, maxn=None):
        self.maxn = maxn
    def __getitem__(self, i):
        if i<0 or (self.maxn and i>self.maxn): raise IndexError, i
        return lambda x: (x%(i+2)) == 0
    def __iter__(self): return pseudo_seq_iter(self)

divisibles = collect_by_first_predicate(range(30), divisible_by(100))
for i in range(2,18):
    result = list(divisibles[i-2])
    if result: print i, result




I _have_ put some arbitrary limit on the divisible_by instance I
pass in the example, because, otherwise (as previously indicated)
trying to loop on an empty iterator among the 'divisibles' might
not terminate.  In this case, this can be because the "for collector
in collectors" loop in 'getanother' never terminates, if predicates
doesn't, and some item never satisfies any predicate; or because
the 'while not self.memory' loop in prediter.next does not terminate,
if 'getanother' can never find an item to add to that collector's
memory, and the sequence does not terminate either; i.e., we have
two possible 'infinities' to cause trouble here.  Anyway, this emits:

[····@lancelot alex]$ python ac.py
[[-4, -2, 0, 2, 4], [-5, -3, -1], [5], [1, 3]]
2 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
3 [3, 9, 15, 21, 27]
5 [5, 25]
7 [7]
11 [11]
13 [13]
17 [17]

which seems correct.  Still, I think this could be enhanced to
avoid _some_ of the avoidable nontermination cases -- e.g. by
letting getanother know _what_ generator is hungry for more,
it can avoid making more generators after that one, and just
stash away as-yet-unclassified items for possible future needs.

I don't particularly like the following, because the management
of stashed_away is finicky and error-prone, but, as a first cut,
it does work to refactor getanother into:

    def try_collecting(item, for_whom):
        for collector in collectors:
            if collector.pred(item):
                collector.append(item)
                return collector
            elif collector is for_whom:
                return None

    stashed_away = []
    def getanother(for_whom):
        for item in stashed_away[:]:
            put_where = try_collecting(item, for_whom)
            if put_where is not None:
                stashed_away.remove(item)
                if put_where is for_whom: return
        for item in seq_iter:
            put_where = try_collecting(item, for_whom)
            if put_where is None:
                stashed_away.append(item)
            elif put_where is for_whom: return
        raise StopIteration

and change the statement calling getanother (in prediter.next) to:

            while not self.memory: getanother(for_whom=self)

This lets us change the divisibles creation, as intended, to:

divisibles = collect_by_first_predicate(range(30), divisible_by())

i.e., with the family of predicates being unbounded (as long as
the sequence isn't also unbounded at the same time), while still
allowing attempts to loop on empty items of divisibles.

If I were to work on this further, I think I'd to so by wrapping
seq_iter into an "iterator with buffering for 'rejected for now,
show again later' items" class instance; encapsulating the
"stashing away" inside said class would simplify getanother again,
while retaining the essential behavior.


Alex
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blujqj$abk$0@216.39.172.122>
On Mon, 06 Oct 2003 11:59:22 -0700, David Eppstein <········@ics.uci.edu> wrote:

>In article <············@newsreader2.netcologne.de>,
> Pascal Costanza <········@web.de> wrote:
>
>> I don't know a lot about Python, so here is a question. Is something 
>> along the following lines possible in Python?
>> 
>> (with-collectors (collect-pos collect-neg)
>>    (do-file-lines (l some-file-name)
>>      (if (some-property l)
>>        (collect-pos l)
>>        (collect-neg l))))
>> 
>> 
>> I actually needed something like this in some of my code...
>
>Not using simple generators afaik.  The easiest way would probably be to 
>append into two lists:
>
>    collect_pos = []
>    collect_neg = []
>    for l in some_file_name:
>        if some_property(l):
>            collect_pos.append(l)
>        else:
>            collect_neg.append(l)
>
>If you needed to do this a lot of times you could encapsulate it into a 
>function of some sort:
>
>def posneg(filter,iter):
>    results = ([],[])
>    for x in iter:
>        results[not filter(x)].append(x)
>    return results
>
Um, about choosing names ...
 >>> filter
 <built-in function filter>
 >>> iter
 <built-in function iter>
;-)

>collect_pos,collect_neg = posneg(some_property, some_file_name)
>

Nah, just abuse a list comprehension:

 >>> seq = range(10)
 >>> test = lambda x: x%3==0
 >>> pos,neg = [(p,n) for p,n in[map(list,['']*2)]
 ...                  for q in [(x,test(x),i) for i,x in enumerate(seq)]
 ...                  if q[1] and p.append(q[0]) or not q[1] and n.append(q[0]) or not q[2]][0]
 >>> pos
 [0, 3, 6, 9]
 >>> neg
 [1, 2, 4, 5, 7, 8]

;-)

Regards,
Bengt Richter
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bltqr0$eoe$0@216.39.172.122>
On Mon, 06 Oct 2003 10:46:13 -0700, David Eppstein <········@ics.uci.edu> wrote:

>In article 
><···········································@k-137-79-50-101.jpl.nasa.go
>v>,
> ··························@jpl.nasa.gov (Erann Gat) wrote:
>
>> > : Here's another example of what you can do with macros in Lisp:
>> > 
>> > : (with-collector collect
>> > :   (do-file-lines (l some-file-name)
>> > :     (if (some-property l) (collect l))))
>> > 
>> > : This returns a list of all the lines in a file that have some property. 
>> > 
>> > OK, that's _definitely_ just a filter: filter someproperty somefilename
>> > Perhaps throw in a fold if you are trying to abstract "collect".
>> 
>> The net effect is a filter, but again, you need to stop thinking about the
>> "what" and start thinking about the "how", otherwise, as I said, there's
>> no reason to use anything other than machine language.
>
>Answer 1: literal translation into Python.  The closest analogue of 
>with-collector etc would be Python's simple generators (yield keyword) 
>and do-with-file-lines is expressed in python with a for loop.  So:
>
>def lines_with_some_property(some_file_name):
>    for l in some_file_name:
>        if some_property(l):
>            yield l
>
>Your only use of macros in this example is to handle the with-collector 
>syntax, which is handled in a clean macro-free way by Python's "yield".
>So this is unconvincing as a demonstration of why macros are a necessary 
>part of a good programming language.
>
>Of course, with-collector could be embedded in a larger piece of code, 
>while using yield forces lines_with_some_property to be a separate 
>function, but modularity is good...
>
>Answer 2: poetic translation into Python.  If I think about "how" I want 
>to express this sort of filtering, I end up with something much less 
>like the imperative-style code above and much more like:
>
>[l for l in some_file_name if some_property(l)]
>

Just thought of this: a generator list comprehension, so your could write

    [yield l for l in some_file_name if some_property(l)]

and get a generator that is the equivalent of your lines_with_some_property above.

I.e., in general you should be able to convert any list comprehension into a generator by
putting 'yield ' at the front. Has someone proposed this already? I seems a natural, unless
I am blindly optimistic, which is quite possible ;-)

>I have no problem with the assertion that macros are an important part 
>of Lisp, but you seem to be arguing more generally that the lack of 
>macros makes other languages like Python inferior because the literal 
>translations of certain macro-based code are impossible or more 
>cumbersome.  For the present example, even that argument fails, but more 
>generally you'll have to also convince me that even a freer poetic 
>translation doesn't work.
>

Regards,
Bengt Richter
From: Lulu of the Lotus-Eaters
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065549617.31509.python-list@python.org>
····@oz.net (Bengt Richter) wrote previously:
|Just thought of this: a generator list comprehension, so your could write
|    [yield l for l in some_file_name if some_property(l)]

Sadly, rejected:

    http://www.python.org/peps/pep-0289.html

--
Keeping medicines from the bloodstreams of the sick; food from the bellies
of the hungry; books from the hands of the uneducated; technology from the
underdeveloped; and putting advocates of freedom in prisons.  Intellectual
property is to the 21st century what the slave trade was to the 16th.
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <6%ygb.3$KR3.79@typhoon.nyu.edu>
David Eppstein wrote:

> In article 
> <···········································@k-137-79-50-101.jpl.nasa.go
> v>,
>  ··························@jpl.nasa.gov (Erann Gat) wrote:
> 
> 
>>>: Here's another example of what you can do with macros in Lisp:
>>>
>>>: (with-collector collect
>>>:   (do-file-lines (l some-file-name)
>>>:     (if (some-property l) (collect l))))
>>>
>>>: This returns a list of all the lines in a file that have some property. 
>>>
>>>OK, that's _definitely_ just a filter: filter someproperty somefilename
>>>Perhaps throw in a fold if you are trying to abstract "collect".
>>
>>The net effect is a filter, but again, you need to stop thinking about the
>>"what" and start thinking about the "how", otherwise, as I said, there's
>>no reason to use anything other than machine language.
> 
> 
> Answer 1: literal translation into Python.  The closest analogue of 
> with-collector etc would be Python's simple generators (yield keyword) 
> and do-with-file-lines is expressed in python with a for loop.  So:
> 
> def lines_with_some_property(some_file_name):
>     for l in some_file_name:
>         if some_property(l):
>             yield l
> 
> Your only use of macros in this example is to handle the with-collector 
> syntax, which is handled in a clean macro-free way by Python's "yield".
> So this is unconvincing as a demonstration of why macros are a necessary 
> part of a good programming language.
> 
> Of course, with-collector could be embedded in a larger piece of code, 
> while using yield forces lines_with_some_property to be a separate 
> function, but modularity is good...

BZZZZZT!  In CL the WITH-COLLECTOR macro is best defined as

	(defmacro with-collector (collector-name &body forms) ...)

That is to say that you can write things as

	(with-collector collect
	  (let ...
	     (block ...
	       (loop ...
	          (dotimes ... (collect whatever))))))

This means that your Python function is *NOT* equivalent to the CL 
macro.  Not even with your 'yield' (easily implementable in CL: meaning, 
in CL).

> 
> Answer 2: poetic translation into Python.  If I think about "how" I want 
> to express this sort of filtering, I end up with something much less 
> like the imperative-style code above and much more like:
> 
> [l for l in some_file_name if some_property(l)]

Very interesting.  The CL equivalent is

	[l in (lines-of some-file-name) if (some-property l)]

Now: I do have an implementation of this in CL. (I assume that your 
'some_file_name' is not just a string).

> 
> I have no problem with the assertion that macros are an important part 
> of Lisp, but you seem to be arguing more generally that the lack of 
> macros makes other languages like Python inferior because the literal 
> translations of certain macro-based code are impossible or more 
> cumbersome.  For the present example, even that argument fails, but more 
> generally you'll have to also convince me that even a freer poetic 
> translation doesn't work.

Well, the argument does not fail even in these cases as closer 
inspection reveals.  There are things you cannot do in Python that you 
can easily do in CL.  It is the converse that is only asymptotically 
provable as a rhethoric exercise :)

Greenspun's Tenth Rules! :)

Cheers
--
Marco
From: Matthias
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <36wr81qfxg9.fsf@chagall.ti.uni-mannheim.de>
·····@cs.uwa.edu.au writes:

> In comp.lang.functional Erann Gat <··························@jpl.nasa.gov> wrote:
> :> I can't see why a LISP programmer would even want to write a macro.
> : That's because you are approaching this with a fundamentally flawed
> : assumption.  Macros are mainly not used to make the syntax prettier
> : (though they can be used for that).  They are mainly used to add features
> : to the language that cannot be added as functions.
> 
> Really? Turing-completeness and all that... I presume you mean "cannot
> so easily be added as functions", but even that would surprise me.
> (Unless you mean cannot be added _to_Lisp_ as functions, because I don't
> know as much as I'd like to about Lisp's capabilities and limitations.)

IMHO, these discussions are less usefull when not accompanied by
specific examples.  What are these macros good for?  Some examples
where you might have difficulties with using ordinary functions:

1.) Inventing new control structures (implement lazy data structures,
  implement declarative control structures, etc.)  
  => This one is rarely needed in everyday application programming and
  can easily be misused.

2.) Serve as abbreviation of repeating code.  Ever used a code
  generator?  Discovered there was a bug in the generated code?  Had
  to fix it at a zillion places?
  => Macros serve as extremely flexible code generators, and there
  is only one place to fix a bug.
  => Many Design Patterns can be implemented as macros, allowing you
  to have them explicitly in your code.  This makes for better 
  documentation and maintainability.

3.) Invent pleasant syntax in limited domains.
  => Some people don't like Lips' prefix syntax.  It's changeable if you 
  have macros.
  => This feature can also be misused.

4.) Do computations at compile time instead of at runtime.
  => Have heard about template metaprogramming in the C++ world?
  People do a lot to get fast performance by shifting computation 
  to compile time.  Macros do this effortlessly.

These are four specific examples which are not easy to do without
macros.  In all cases, implementing them classically will lead to code
duplication with all the known maintainability issues.  In some cases
misuse will lead to unreadable or buggy code.  Thus, macros are
powerful tools for the hand of professionals.  You have to know if you
want a sharp knife (which may hurt you when misused) or a less sharper
one (where it takes more effort to cut with).
From: Raymond Wiker
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8665j2k4hf.fsf@raw.grenland.fast.no>
Matthias <··@spam.pls> writes:

> 1.) Inventing new control structures (implement lazy data structures,
>   implement declarative control structures, etc.)  
>   => This one is rarely needed in everyday application programming and
>   can easily be misused.

        This is, IMHO, wrong. One particular example is creating
macros (or read macros) for giving values to application-specific data
structures.

> You have to know if you want a sharp knife (which may hurt you when
> misused) or a less sharper one (where it takes more effort to cut
> with).

        It is easier to hurt yourself with a blunt knife than a sharp
one. 

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwmxbue53seq94@news.nscp.aoltw.net>
On Mon, 06 Oct 2003, Raymond Wiker <·············@fast.no> wrote:
> Matthias <··@spam.pls> writes:
>> (In certain cases macros) can easily be misused.
...
>> You have to know if you want a sharp knife (which may hurt you when
>> misused) or a less sharper one (where it takes more effort to cut
>> with).
>
> It is easier to hurt yourself with a blunt knife than a sharp
> one.

Actually I've noticed that I usually cut myself when I *switch* from
a dull knife to a sharp one.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvfzi6j9pr.fsf@firestorm.OCF.Berkeley.EDU>
David Rush <·····@aol.net> writes:

> On Mon, 06 Oct 2003, Raymond Wiker <·············@fast.no> wrote:
> > Matthias <··@spam.pls> writes:
> >> (In certain cases macros) can easily be misused.
> ...
> >> You have to know if you want a sharp knife (which may hurt you when
> >> misused) or a less sharper one (where it takes more effort to cut
> >> with).
> >
> > It is easier to hurt yourself with a blunt knife than a sharp
> > one.
> 
> Actually I've noticed that I usually cut myself when I *switch* from
> a dull knife to a sharp one.

I don't think the truism about cutting yourself with dull vs sharp
knives means to say anything about superficial cuts.  You don't lop
your finger off with a sharp knife, because you're handling it
carefully.  With a dull knife, your best bet is to put your weight
behind it; that's also a good way to lose a finger / dump core.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <4qymf5la.fsf@ccs.neu.edu>
David Rush <·····@aol.net> writes:

> On Mon, 06 Oct 2003, Raymond Wiker <·············@fast.no> wrote:
>> Matthias <··@spam.pls> writes:
>>> (In certain cases macros) can easily be misused.
> ...
>>> You have to know if you want a sharp knife (which may hurt you when
>>> misused) or a less sharper one (where it takes more effort to cut
>>> with).
>>
>> It is easier to hurt yourself with a blunt knife than a sharp
>> one.
>
> Actually I've noticed that I usually cut myself when I *switch* from
> a dull knife to a sharp one.

Grasp the sharp knife by the *handle* when switching.
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bltdvp$l1f$0@216.39.172.122>
On 06 Oct 2003 12:54:30 +0200, Matthias <··@spam.pls> wrote:

>·····@cs.uwa.edu.au writes:
>
>> In comp.lang.functional Erann Gat <··························@jpl.nasa.gov> wrote:
>> :> I can't see why a LISP programmer would even want to write a macro.
>> : That's because you are approaching this with a fundamentally flawed
>> : assumption.  Macros are mainly not used to make the syntax prettier
>> : (though they can be used for that).  They are mainly used to add features
>> : to the language that cannot be added as functions.
>> 
>> Really? Turing-completeness and all that... I presume you mean "cannot
>> so easily be added as functions", but even that would surprise me.
>> (Unless you mean cannot be added _to_Lisp_ as functions, because I don't
>> know as much as I'd like to about Lisp's capabilities and limitations.)
>
>IMHO, these discussions are less usefull when not accompanied by
>specific examples.  What are these macros good for?  Some examples
>where you might have difficulties with using ordinary functions:
>
>1.) Inventing new control structures (implement lazy data structures,
You mean like an object olazy with olazy.x and olazy.y, where x might
be an integer 123 and y might be the text of the latest bug python report
on sourceforge? Not so hard with properties (you'd proabably want to cache
the latest for y and not re-check for some reasonable interval, but that
doesn't change client code (unless you later decide you want the value to
be a tuple of (timestamp, text), etc.)

>  implement declarative control structures, etc.)  
You mean like case or such? It can be done, but Python could use a way
to define a nested functions that just use the local namespace of their lexically
enclosing function. Then case would be easy to build with a dictionary-based dispatch
of such functions.

Wild idea: It might be interesting to be able to do a kind of (quote thing) or 'thing
in Python, but to defer "trailer" evaluation (where trailer is what comes after an
object-specifying expression. E.g., in x.y[z+2](a=3) x has the trailer ".y[z+2](a=3)"
and x.y has the trailer [z+2](a=3), etc. Ok, you could currently write a class to
do deferred trailer evaluation in the form  qt=QT(x.y, '[z+2](a=3)') and then
evaluate/unquote it with qt.value ot qt.evaluate(), etc., but you couldn't just
bind and pass a QT instance like an ordinary object and expect an automatic evaluation
on access, as if the quoted expression appeared in that context.

BTW, with trailer, I am just generalizing the first impulse, which was just to do it
for an attribute name, so as to be able to wrap property as well as ordinary attribute
accesses for unqualified (i.e., deferred-qualification -- we're not talking about
rebinding a name (e.g., x above) that is unknown at access time, since it was lost
when the leader object was pased to QT).

There is an ambiguity when assigning to a name that's bound to a QT object though,
i.e., whether to rebind the name as usual without considering its current binding,
or whether to notice the binding to a QT object, and do as-if-the-entire-trailer-
expression-were-there target processing for the assignment. The latter would make
for "interesting" programming ;-) To rebind such a name, you'd have to get at it
via an indirect route, much as you have to do with an object's attribute name if
it is bound to a property.

>  => This one is rarely needed in everyday application programming and
>  can easily be misused.
>
>2.) Serve as abbreviation of repeating code.  Ever used a code
>  generator?  Discovered there was a bug in the generated code?  Had
>  to fix it at a zillion places?
>  => Macros serve as extremely flexible code generators, and there
>  is only one place to fix a bug.
>  => Many Design Patterns can be implemented as macros, allowing you
>  to have them explicitly in your code.  This makes for better 
>  documentation and maintainability.
You can generate code many ways in Python. What use case are you thinking of?

>
>3.) Invent pleasant syntax in limited domains.
>  => Some people don't like Lips' prefix syntax.  It's changeable if you 
>  have macros.
>  => This feature can also be misused.
You can do this also.

>
>4.) Do computations at compile time instead of at runtime.
>  => Have heard about template metaprogramming in the C++ world?
>  People do a lot to get fast performance by shifting computation 
>  to compile time.  Macros do this effortlessly.
This also, but Python has so many possible compile times ;-)

>
>These are four specific examples which are not easy to do without
>macros.  In all cases, implementing them classically will lead to code
>duplication with all the known maintainability issues.  In some cases
>misuse will lead to unreadable or buggy code.  Thus, macros are
>powerful tools for the hand of professionals.  You have to know if you
>want a sharp knife (which may hurt you when misused) or a less sharper
>one (where it takes more effort to cut with).
Python is pretty sharp ;-)
I think we need some realistic use cases for your "specific" [categories of]
examples in order to compare how problems would be approached.

Regards,
Bengt Richter
From: Matthias
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <36wisn1fc03.fsf@chagall.ti.uni-mannheim.de>
····@oz.net (Bengt Richter) writes:

> On 06 Oct 2003 12:54:30 +0200, Matthias <··@spam.pls> wrote:
> >1.) Inventing new control structures (implement lazy data structures,
> You mean like an object olazy with olazy.x and olazy.y, where x might
> be an integer 123 and y might be the text of the latest bug python report
> on sourceforge? Not so hard with properties (you'd proabably want to cache
> the latest for y and not re-check for some reasonable interval, but that
> doesn't change client code (unless you later decide you want the value to
> be a tuple of (timestamp, text), etc.)

Actually, I meant more lazy-like-lazy-in-Haskell.  Infinite data
structures and such.  "primes" being a list representing _all_ prime
numbers for instance.  You can build this as soon as you have closures
but making the construction easy to use for the application programmer
might be a challenge without macros.  But I don't know what
"properties" are in Python, possibly they are built for exactly that.

> >  implement declarative control structures, etc.)  
> You mean like case or such? 

No. I was thinking about Prolog and such.  Or nondeterministic
programming.  Or multimethod dispatch.

> >2.) Serve as abbreviation of repeating code.  Ever used a code
> >  generator?  Discovered there was a bug in the generated code?  Had
> >  to fix it at a zillion places?
> >  => Macros serve as extremely flexible code generators, and there
> >  is only one place to fix a bug.
> >  => Many Design Patterns can be implemented as macros, allowing you
> >  to have them explicitly in your code.  This makes for better 
> >  documentation and maintainability.
> You can generate code many ways in Python. What use case are you thinking of?

I was not talking about generating code /in/ Python but generating
code /for/ Python /within/ it.  For the Design Pattern use case take a
look at http://norvig.com/design-patterns/

> >3.) Invent pleasant syntax in limited domains.
> >  => Some people don't like Lips' prefix syntax.  It's changeable if you 
> >  have macros.
> >  => This feature can also be misused.
> You can do this also.

You can change Python's syntax?  Easily?

> >4.) Do computations at compile time instead of at runtime.
> >  => Have heard about template metaprogramming in the C++ world?
> >  People do a lot to get fast performance by shifting computation 
> >  to compile time.  Macros do this effortlessly.
> This also, but Python has so many possible compile times ;-)

I'm not sure I understand.

> Python is pretty sharp ;-)
> I think we need some realistic use cases for your "specific" [categories of]
> examples in order to compare how problems would be approached.

Well, if you don't want to learn about syntactic abstraction you'll
probably never miss it during your programming.  Just keep in mind
that before oo-abstraction became fashionable people didn't miss OOP
either.
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-D68971.08391407102003@news.service.uci.edu>
In article <···············@chagall.ti.uni-mannheim.de>,
 Matthias <··@spam.pls> wrote:

> ctually, I meant more lazy-like-lazy-in-Haskell.  Infinite data
> structures and such.  "primes" being a list representing _all_ prime
> numbers for instance.  You can build this as soon as you have closures
> but making the construction easy to use for the application programmer
> might be a challenge without macros.  But I don't know what
> "properties" are in Python, possibly they are built for exactly that.

You mean like as in
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117119
?

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm05c5$qm3$0@216.39.172.122>
On 07 Oct 2003 14:50:04 +0200, Matthias <··@spam.pls> wrote:

>····@oz.net (Bengt Richter) writes:
>
>> On 06 Oct 2003 12:54:30 +0200, Matthias <··@spam.pls> wrote:
>> >1.) Inventing new control structures (implement lazy data structures,
>> You mean like an object olazy with olazy.x and olazy.y, where x might
>> be an integer 123 and y might be the text of the latest bug python report
>> on sourceforge? Not so hard with properties (you'd proabably want to cache
>> the latest for y and not re-check for some reasonable interval, but that
>> doesn't change client code (unless you later decide you want the value to
>> be a tuple of (timestamp, text), etc.)
>
>Actually, I meant more lazy-like-lazy-in-Haskell.  Infinite data
>structures and such.  "primes" being a list representing _all_ prime
>numbers for instance.  You can build this as soon as you have closures
>but making the construction easy to use for the application programmer
>might be a challenge without macros.  But I don't know what
>"properties" are in Python, possibly they are built for exactly that.
No, generators are closer to "exactly that" e.g., in the following function,
"yield" is the keyword that makes it into a generator. The initial call effectively
becomes a factory function call that returns an initialized generator, and calls
to the generators' .next() method resumes execution first at the beginning, running
up to the first yield, where execution is suspended and the yield value returned to
the next() method caller. A subsequent .next() call resumes execution right after the
last yield, and so on forever or until the generator exits without hitting a yield,
which terminates the sequence.

 >>> def lazyprimes(prime_range_top):
 ...     import array
 ...     primes = array.array('l',[2])
 ...     yield 2
 ...     for prime_candidate in xrange(3,prime_range_top,2):
 ...         for p in primes:
 ...             if prime_candidate%p==0: break
 ...         else:
 ...             primes.append(prime_candidate)
 ...             yield prime_candidate
 ...
 >>> primegen = lazyprimes(1000) # primes under 1000
 >>> primegen.next()
 2

Properties allow you to create a class whose instances have a property attribute that
is accessed just like an ordinary attribute, but may invoke arbitrary functions to get
and/or set the apparent state. E.g.,

 >>> class Foo(object):
 ...     def __init__(self, k, ptop):
 ...         self.k = k
 ...         self.pnext = lazyprimes(ptop).next
 ...     p = property(lambda self: self.pnext())
 ...
 >>> foo = Foo(123, 32)

Here k is an ordinary instance attribute and p looks like another in the syntax of the
access in an expression, but it is hooked into a lazy prime generator:

 >>> foo.k
 123
 >>> foo.p
 2
 >>> foo.p, foo.p
 (3, 5)
 >>> foo.k
 123
 >>> [(foo.k, foo.p, c) for c in 'abcd']
 [(123, 7, 'a'), (123, 11, 'b'), (123, 13, 'c'), (123, 17, 'd')]
 >>> foo.pnext()
 19
 >>> foo.pnext()
 23
 >>> foo.p
 29
 >>> foo.p
 31
 >>> foo.p
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 5, in <lambda>
 StopIteration

Well, I should have provided for dealing with the end-of-sequence exception, most likely,
unless reaching it was an error. Not hard.

Getting back to primegen, which last yielded the first prime 2 above,
I'll bind a shorter name to the next method (bound to the particular generator),
for easier typing ;-)

 >>> pn = primegen.next
 >>> pn()
 3
Here we'll enumerate
 >>> for i,p in enumerate(iter(pn,31)): print i,p
 ...
 0 5
 1 7
 2 11
 3 13
 4 17
 5 19
 6 23
 7 29
 >>> pn()  # we used up 31 as the sentinel ending a series of calls to pn() so,
 37
 >>> # here we got the next one after 31
 ...
 >>> for i in xrange(10): print pn(), # 10 more
 ...
 41 43 47 53 59 61 67 71 73 79
 >>> pn() #one more
 83
 >>> primegen.next()
 89
 >>> for p in primegen: print p, # the rest
 ...
 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 2
 27 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 3
 67 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 5
 09 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 6
 61 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 8
 29 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997
 >>>

(In opportune line wrap on my console screen, but I assume it's clear enough). 

>
>> >  implement declarative control structures, etc.)  
>> You mean like case or such? 
>
>No. I was thinking about Prolog and such.  Or nondeterministic
>programming.  Or multimethod dispatch.
For the latter in Python, see
    http://www-106.ibm.com/developerworks/linux/library/l-pydisp.html
>
>> >2.) Serve as abbreviation of repeating code.  Ever used a code
>> >  generator?  Discovered there was a bug in the generated code?  Had
>> >  to fix it at a zillion places?
>> >  => Macros serve as extremely flexible code generators, and there
>> >  is only one place to fix a bug.
>> >  => Many Design Patterns can be implemented as macros, allowing you
>> >  to have them explicitly in your code.  This makes for better 
>> >  documentation and maintainability.
>> You can generate code many ways in Python. What use case are you thinking of?
>
>I was not talking about generating code /in/ Python but generating
>code /for/ Python /within/ it.  For the Design Pattern use case take a
>look at http://norvig.com/design-patterns/
I  was also talking about "generating codef /for/ Python /within/ it" -- even in
a recrusive routine, see answer to 4. below ;-)

>
>> >3.) Invent pleasant syntax in limited domains.
>> >  => Some people don't like Lips' prefix syntax.  It's changeable if you 
>> >  have macros.
>> >  => This feature can also be misused.
>> You can do this also.
>
>You can change Python's syntax?  Easily?
No, I didn't mean that literally, but just as you can create source dynamically
and compile it for subsequent execution (as with the trivial text source template below),
you could define an app-specific mini language and translate and compile it for use later
in the same program run. If you create a class and populate class variables from values
in a config file, are you doing this? I think so, at a trivial level. If you wrote an
import function that could import a subset of scheme and have it dynamically translated
to something that looks like a python module to the python user, have you changed python's
syntax? No. Have you made other syntax available to the python programmer? Yes.

I had an infatuation with scheme, some years back now. I still think she was sweet ;-)

>
>> >4.) Do computations at compile time instead of at runtime.
>> >  => Have heard about template metaprogramming in the C++ world?
>> >  People do a lot to get fast performance by shifting computation 
>> >  to compile time.  Macros do this effortlessly.
>> This also, but Python has so many possible compile times ;-)
>
>I'm not sure I understand.

 >>> import time
 >>> def multicomp(maxrec=5, level=0):
 ...     fooname = 'foo_level_%s'%level
 ...     source = """
 ... def %s(): print 'I was compiled at level %s on %s.'
 ... """% (fooname, level, time.ctime())
 ...     d={}
 ...     exec source in d
 ...     time.sleep(2) # to guarantee time stamp change
 ...     if level<maxrec: return (d[fooname],)+ multicomp(maxrec,level+1)
 ...     return (d[fooname],)
 ...
 >>> mc = multicomp()
 >>> for f in mc: print 'My name is %r and'%(f.__name__,),; f()
 ...
 My name is 'foo_level_0' and I was compiled at level 0 on Tue Oct 07 21:19:18 2003.
 My name is 'foo_level_1' and I was compiled at level 1 on Tue Oct 07 21:19:20 2003.
 My name is 'foo_level_2' and I was compiled at level 2 on Tue Oct 07 21:19:22 2003.
 My name is 'foo_level_3' and I was compiled at level 3 on Tue Oct 07 21:19:24 2003.
 My name is 'foo_level_4' and I was compiled at level 4 on Tue Oct 07 21:19:26 2003.
 My name is 'foo_level_5' and I was compiled at level 5 on Tue Oct 07 21:19:28 2003.
 >>>

Ok, the recursion was gratuitous, except that it shows compilation happening dynamically,
and you can easily see you could leave such routines compiled at the outer level for
execution any time you wanted, and thus get "many compile times" ;-)
 
>
>> Python is pretty sharp ;-)
>> I think we need some realistic use cases for your "specific" [categories of]
>> examples in order to compare how problems would be approached.
>
>Well, if you don't want to learn about syntactic abstraction you'll
>probably never miss it during your programming.  Just keep in mind
>that before oo-abstraction became fashionable people didn't miss OOP
>either.

Actually, I would like to learn more about it. I am fascinated by the
interplay between the worlds of concrete representations and abstract entities,
and their interrelated transformations. ISTM macros definitely have a place in the pantheon.
I have yet to grok scheme's hygienic macro stuff, though ;-) One of these days...

Regards,
Bengt Richter
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87wubid3tl.fsf@thalassa.informatimago.com>
·····@cs.uwa.edu.au writes:
> What does it mean to take a variable-name as an argument? How is that
> different to taking a pointer? What does it mean to take "code" as an
> argument? Is that different to taking a function as an argument?

The  difference is  that  you can  declare  (compilation-time) it  and
associated variables or functions.

For example,  I recently  defined this macro,  to declare at  the same
time a  class and a  structure, and to  define a couple of  methods to
copy the objects to and from structures.

That's so useful that even cpp  provide us with a ## operator to build
new symbols.

(DEFMACRO DEFCLASS-AND-STRUCT (NAME SUPER-CLASSES ATTRIBUTES OPTIONS)
  (LET ((STRUCT-NAME (INTERN (FORMAT NIL "~A-STRUCT" NAME))))
    `(PROG1
         (DEFCLASS ,NAME ,SUPER-CLASSES ,ATTRIBUTES ,OPTIONS)
       (DEFSTRUCT ,STRUCT-NAME
         ,@(MAPCAR (LAMBDA (ATTRIBUTE)
                     (CONS
                      (CAR ATTRIBUTE)
                      (CONS (GETF (CDR ATTRIBUTE) :INITFORM NIL)
                            (IF (GETF (CDR ATTRIBUTE) :TYPE NIL)
                              NIL
                              (LIST :TYPE (GETF (CDR ATTRIBUTE) :TYPE))))))
                   ATTRIBUTES))
       (DEFMETHOD COPY-TO-STRUCT ((SELF ,NAME))
         (MAKE-STRUCT
          ',NAME
          ,@(MAPCAN (LAMBDA (ATTRIBUTE)
                      `(,(INTERN (STRING (CAR ATTRIBUTE)) "KEYWORD")
                        (COPY-TO-STRUCT (SLOT-VALUE SELF ',(CAR ATTRIBUTE)))))
                    ATTRIBUTES)))
       (DEFMETHOD COPY-FROM-STRUCT ((SELF ,NAME) (STRUCT ,STRUCT-NAME))
         ,@(MAPCAR
            (LAMBDA (ATTRIBUTE)
              `(SETF (SLOT-VALUE SELF ',(CAR ATTRIBUTE))
                     (,(INTERN (FORMAT NIL "~A-~A"
                                       STRUCT-NAME (CAR ATTRIBUTE))) STRUCT)))
            ATTRIBUTES)
         SELF)
       ))
  );;DEFCLASS-AND-STRUCT


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Neelakantan Krishnaswami
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbo2v27.q50.neelk@gs3106.sp.cs.cmu.edu>
In article <············@enyo.uwa.edu.au>, ·····@cs.uwa.edu.au wrote:
> In comp.lang.functional Erann Gat <··························@jpl.nasa.gov>
> wrote:
>:> I can't see why a LISP programmer would even want to write a macro.
>: That's because you are approaching this with a fundamentally flawed
>: assumption.  Macros are mainly not used to make the syntax prettier
>: (though they can be used for that).  They are mainly used to add features
>: to the language that cannot be added as functions.
> 
> Really? Turing-completeness and all that... I presume you mean
> "cannot so easily be added as functions", but even that would
> surprise me.  (Unless you mean cannot be added _to_Lisp_ as
> functions, because I don't know as much as I'd like to about Lisp's
> capabilities and limitations.)

You know Haskell. Think about the do-noatation for monads: it takes
what would be awkward, error-prone code (using >> and >>= manually)
and makes it pleasant and readable. Do-notation is basically a macro
(and can easily be expressed as such in Scheme or Lisp). Syntactic
convenience is very important; consider how many fewer programmers in
ML are willing to reach for a monadic solution, even when it would be
appropriate. Or for that matter, think how many fewer Java programmers
are willing to write a fold than in ML or Haskell, even when it would
be appropriate.


-- 
Neel Krishnaswami
·····@cs.cmu.edu
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <aeb7ff58.0310061405.e319775@posting.google.com>
·····@cs.uwa.edu.au wrote in message news:<············@enyo.uwa.edu.au>...
> In comp.lang.functional Erann Gat <··························@jpl.nasa.gov> wrote:
> :> I can't see why a LISP programmer would even want to write a macro.
> : That's because you are approaching this with a fundamentally flawed
> : assumption.  Macros are mainly not used to make the syntax prettier
> : (though they can be used for that).  They are mainly used to add features
> : to the language that cannot be added as functions.
> 
> Really? Turing-completeness and all that... I presume you mean "cannot
> so easily be added as functions", but even that would surprise me.
> (Unless you mean cannot be added _to_Lisp_ as functions, because I don't
> know as much as I'd like to about Lisp's capabilities and limitations.)

Two words: code duplication.

Yes, anything that can be done with macros can also be done with
functions, but if you do it with functions, you will end up with more
code, and that code will be duplicated in every single source location
in which that abstraction it utilized.

With a macro, the abstraction is defined once, and the source code
reflects that abstraction everywhere that abstraction is used
throughout your program. For large projects this could be hundreds of
source locations.

Without a macro, you have multiple points of maintenance. If your
abstraction changes, you have to edit scores or hundreds of source
locations. With a macro, you redefine a single form, in one source
location, and recompile the dependent code.

All turing complete languages are computationally equivalent. That
doesn't mean you'll see me programming by punching holes in a paper
tape any time soon though.

Finally, there is one thing that macros can do that ordinary functions
cannot do easily - change the language's rules for functional
evaluation. This can only be accomplished with functions if you're
willing to write a set of functions that defer evaluation, by, say
parsing input, massaging it appropriately, and then passing it to the
compiler. At that point, however, you've just written your own macro
system, and invoked Greenspun's 10th Law.
From: Matthias Blume
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m1d6d9njkr.fsf@tti5.uchicago.edu>
·······@mediaone.net (Raffael Cavallaro) writes:

> ·····@cs.uwa.edu.au wrote in message news:<············@enyo.uwa.edu.au>...
> > In comp.lang.functional Erann Gat <··························@jpl.nasa.gov> wrote:
> > :> I can't see why a LISP programmer would even want to write a macro.
> > : That's because you are approaching this with a fundamentally flawed
> > : assumption.  Macros are mainly not used to make the syntax prettier
> > : (though they can be used for that).  They are mainly used to add features
> > : to the language that cannot be added as functions.
> > 
> > Really? Turing-completeness and all that... I presume you mean "cannot
> > so easily be added as functions", but even that would surprise me.
> > (Unless you mean cannot be added _to_Lisp_ as functions, because I don't
> > know as much as I'd like to about Lisp's capabilities and limitations.)
> 
> Two words: code duplication.
> 
> Yes, anything that can be done with macros can also be done with
> functions, but if you do it with functions, you will end up with more
> code, and that code will be duplicated in every single source location
> in which that abstraction it utilized.

Three words and a hyphen: Higher-Order Functions.

Most of the things that macros can do can be done with HOFs with just
as little source code duplication as with macros.  (And with macros
only the source code does not get duplicated, the same not being true
for compiled code.  With HOFs even executable code duplication is
often avoided -- depending on compiler technology.)

I say "most" because there are some things that macros can do which
are difficult with HOFs -- but those things have to do with
compile-time calculations.  A good example that was given to me during
the course of a similar discussion here on netnews is that of a
parser-generator macro: it could check at compile time that the input
grammar is, e.g., LL(1).  With HOFs this check would have to happen at
runtime, or at link-time at the earliest.  (Some languages, e.g., SML
can do arbitrary calculations at what we normally call "link time".)

Many static guarantees can be obtained by relying on reasonably
powerful static type systems, but I know of none that is powerful
enough and practical as well as general at the same time which would
be able to check for LL(1)-ness.  That's why macros sometimes "beat"
HOFs.  For most things they don't.

> With a macro, the abstraction is defined once, and the source code
> reflects that abstraction everywhere that abstraction is used
> throughout your program. For large projects this could be hundreds of
> source locations.

Sure.  Same goes for HOFs.

> Without a macro, you have multiple points of maintenance. If your
> abstraction changes, you have to edit scores or hundreds of source
> locations. With a macro, you redefine a single form, in one source
> location, and recompile the dependent code.

All the same with HOFs.

> Finally, there is one thing that macros can do that ordinary functions
> cannot do easily - change the language's rules for functional
> evaluation.

Well, no, not really.  You can define new syntactic forms in terms of
old ones, and the evaluation rules end up being determined by those of
the old ones.  Again, with HOFs you can always get the same
effect -- at the expense of an extra lambda here and there in your
source code.

> This can only be accomplished with functions if you're
> willing to write a set of functions that defer evaluation, by, say
> parsing input, massaging it appropriately, and then passing it to the
> compiler. At that point, however, you've just written your own macro
> system, and invoked Greenspun's 10th Law.

This is false.  Writing your own macro expander is not necessary for
getting the effect.  The only thing that macros give you in this
regard is the ability to hide the lambda-suspensions.  To some people
this is more of a disadvantage than an advantage because, when not
done in a very carefully controlled manner, it ends up obscuring the
logic of the code.  (Yes, yes, yes, now someone will jump in an tell
me that it can make code less obscure by "canning" certain common
idioms.  True, but only when not overdone.)

Matthias
From: Eli Barzilay
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <skisn0ivq5.fsf@mojave.cs.cornell.edu>
Matthias Blume <····@my.address.elsewhere> writes:

> ·······@mediaone.net (Raffael Cavallaro) writes:
> 
> > Two words: code duplication.
> 
> Three words and a hyphen: Higher-Order Functions.

This covers most usages of macros for control structures, but not
all.  (For example, goto.)

But there is an additional word to add, no hyphens: Bindings.


> > This can only be accomplished with functions if you're willing to
> > write a set of functions that defer evaluation, by, say parsing
> > input, massaging it appropriately, and then passing it to the
> > compiler. At that point, however, you've just written your own
> > macro system, and invoked Greenspun's 10th Law.
> 
> This is false.  Writing your own macro expander is not necessary for
> getting the effect.  The only thing that macros give you in this
> regard is the ability to hide the lambda-suspensions.  To some
> people this is more of a disadvantage than an advantage because,
> when not done in a very carefully controlled manner, it ends up
> obscuring the logic of the code.  (Yes, yes, yes, now someone will
> jump in an tell me that it can make code less obscure by "canning"
> certain common idioms.  True, but only when not overdone.)

(This hits one of the major differences between Lisp and Scheme -- in
Lisp I'm not as happy to use HOFs because of the different syntax
(which is an indication of a different mindset, which leads to
performance being optimized for a certain style).  Scheme is much more
functional in this respect, for example -- using HOF versions of
with-... compared to Lisp where these are always macros.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F833A4F.4C78ADD7@setf.de>
Eli Barzilay wrote:
> 
> Matthias Blume <····@my.address.elsewhere> writes:
> 
> ...
> >
> > This is false.  Writing your own macro expander is not necessary for
> > getting the effect.  The only thing that macros give you in this
> > regard is the ability to hide the lambda-suspensions.  To some
> > people this is more of a disadvantage than an advantage because,
> > when not done in a very carefully controlled manner, it ends up
> > obscuring the logic of the code.  (Yes, yes, yes, now someone will
> > jump in an tell me that it can make code less obscure by "canning"
> > certain common idioms.  True, but only when not overdone.)
> 
> (This hits one of the major differences between Lisp and Scheme -- in
> Lisp I'm not as happy to use HOFs because of the different syntax

which difference differnt syntax?

> (which is an indication of a different mindset, which leads to
> performance being optimized for a certain style).  Scheme is much more
> functional in this respect, for example -- using HOF versions of
> with-... compared to Lisp where these are always macros.)

in practice, as a rule, a with- is available at least optionally also as a
call-with-. not just for convenience, but also for maintainability.

in the standard there are but twelve of these. should they be an impediment,
in most cases there is nothing preventing one from writing call-with-...
equivalents. many expand fairly directly to special forms, so they are even
trivial to reimplement if the "double-nesting" were distasteful. i am curious,
however, about the HOF equivalents for macros which expand primarily to
changes to the lexical environment. not everything has a ready equivalence to
lambda. for instance with-slots and with-accessors. what is the HOF equivalent
for something like

? (defclass c1 () ((s1 )))

#<STANDARD-CLASS C1>
? (defmethod c1-s1 ((instance c1))
  (with-slots (s1) instance
    (if (slot-boundp instance 's1)
      s1
      (setf s1 (get-universal-time)))))

#<STANDARD-METHOD C1-S1 (C1)>
? (defparameter *c1* (make-instance 'c1))

*C1*
? (describe *c1*)
#<C1 #x69D95C6>
Class: #<STANDARD-CLASS C1>
Wrapper: #<CCL::CLASS-WRAPPER C1 #x69D95A6>
Instance slots
S1: #<Unbound>
? (c1-s1 *c1*)
3274553173
? (describe *c1*)
#<C1 #x69D95C6>
Class: #<STANDARD-CLASS C1>
Wrapper: #<CCL::CLASS-WRAPPER C1 #x69D95A6>
Instance slots
S1: 3274553173
?
From: Eli Barzilay
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <skad8cith5.fsf@mojave.cs.cornell.edu>
james anderson <··············@setf.de> writes:

> Eli Barzilay wrote:
> > 
> > (This hits one of the major differences between Lisp and Scheme --
> > in Lisp I'm not as happy to use HOFs because of the different
> > syntax
> 
> which difference differnt syntax?

Huh?


> > (which is an indication of a different mindset, which leads to
> > performance being optimized for a certain style).  Scheme is much more
> > functional in this respect, for example -- using HOF versions of
> > with-... compared to Lisp where these are always macros.)
> 
> in practice, as a rule, a with- is available at least optionally also as a
> call-with-. not just for convenience, but also for maintainability.
> [...]

Yes, but I was talking about the difference approaches,  for example:

  (dolist (x foo)
    (bar x))

vs:

  (mapc #'bar foo)


> i am curious, however, about the HOF equivalents for macros which
> expand primarily to changes to the lexical environment. [...]

That was the point I made in the beginning.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F833E91.AE4BE353@setf.de>
Eli Barzilay wrote:
> 
> james anderson <··············@setf.de> writes:
> 
> > Eli Barzilay wrote:
> > >
> > > (This hits one of the major differences between Lisp and Scheme --
> > > in Lisp I'm not as happy to use HOFs because of the different
> > > syntax
> >
> > which different [] syntax?
> 
> Huh?

that is, what is different about the syntax for higher-order functions in lisp?

> 
> > > (which is an indication of a different mindset, which leads to
> > > performance being optimized for a certain style).  Scheme is much more
> > > functional in this respect, for example -- using HOF versions of
> > > with-... compared to Lisp where these are always macros.)
> >
> > in practice, as a rule, a with- is available at least optionally also as a
> > call-with-. not just for convenience, but also for maintainability.
> > [...]
> 
> Yes, but I was talking about the difference approaches,  for example:
> 
>   (dolist (x foo)
>     (bar x))
> 
> vs:
> 
>   (mapc #'bar foo)

are these not two examples of coding in common-lisp. how do they demonstrate
that "scheme is much more functional"?

> 
> > i am curious, however, about the HOF equivalents for macros which
> > expand primarily to changes to the lexical environment. [...]
> 
> That was the point I made in the beginning.

sorry, i missed that.
From: Eli Barzilay
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <sk4qykir6g.fsf@mojave.cs.cornell.edu>
james anderson <··············@setf.de> writes:

> Eli Barzilay wrote:
> > 
> > james anderson <··············@setf.de> writes:
> > 
> > > Eli Barzilay wrote:
> > > >
> > > > (This hits one of the major differences between Lisp and
> > > > Scheme -- in Lisp I'm not as happy to use HOFs because of the
> > > > different syntax
> > >
> > > which different [] syntax?
> > 
> > Huh?
> 
> that is, what is different about the syntax for higher-order
> functions in lisp?

funcall, function, #', the double namespace.


> > Yes, but I was talking about the difference approaches, for
> > example:
> > 
> >   (dolist (x foo)
> >     (bar x))
> > 
> > vs:
> > 
> >   (mapc #'bar foo)
> 
> are these not two examples of coding in common-lisp. how do they
> demonstrate that "scheme is much more functional"?

The first is very popular, the second is hardly known.  R5RS has
`for-each' which is exactly like `mapc', but no `dolist' equivalent.
In Scheme, this is not a problem, in Lisp, the syntax makes me worry
for the extra effort in creating a closure.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!
From: Paul F. Dietz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F835C86.3070201@dls.net>
Eli Barzilay wrote:

>>>  (dolist (x foo)
>>>    (bar x))
>>>
>>>vs:
>>>
>>>  (mapc #'bar foo)
>>
>>are these not two examples of coding in common-lisp. how do they
>>demonstrate that "scheme is much more functional"?
> 
> 
> The first is very popular, the second is hardly known.  R5RS has
> `for-each' which is exactly like `mapc', but no `dolist' equivalent.
> In Scheme, this is not a problem, in Lisp, the syntax makes me worry
> for the extra effort in creating a closure.


MAPC will typically compiler-macro-expand into the equivalent of
DOLIST, so the closure should be optimized away.

	Paul
From: Eli Barzilay
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <skvfr0h6qb.fsf@mojave.cs.cornell.edu>
"Paul F. Dietz" <·····@dls.net> writes:

> MAPC will typically compiler-macro-expand into the equivalent of
> DOLIST, so the closure should be optimized away.

I'll say this just one more time -- I made a point about *style*.  Of
course this is a very simple example, so in some cases it can be
optimized away to producing the same thing.  It's the style that is
different -- when I'm writing Lisp, I'll prefer using a built-in
iteration and not use some HOF, and in Scheme I don't care about it.

(Another indication is how common it is to have nested functions in
Scheme and in Lisp.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!
From: Paul F. Dietz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <LK-cnU5jO7hqZx6iXTWJkA@dls.net>
Eli Barzilay wrote:

> I'll say this just one more time -- I made a point about *style*.

You expressed a concern about efficiency.  If you do not wish your
statements to be interpreted as written, please write them differently.

	Paul
From: Eli Barzilay
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <skismzh15r.fsf@mojave.cs.cornell.edu>
"Paul F. Dietz" <·····@dls.net> writes:

> Eli Barzilay wrote:
> 
> > I'll say this just one more time -- I made a point about *style*.
> 
> You expressed a concern about efficiency.  If you do not wish your
> statements to be interpreted as written, please write them
> differently.

It does lead to efficiency issues, obviously not in that specific
example.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!
From: james anderson
Subject: *style* [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F83E12F.9E3E43DE@setf.de>
Eli Barzilay wrote:
> 
> "Paul F. Dietz" <·····@dls.net> writes:
> 
> > MAPC will typically compiler-macro-expand into the equivalent of
> > DOLIST, so the closure should be optimized away.
> 
> I'll say this just one more time -- I made a point about *style*.

then, i'll respond just one more time -- the suggested stylistic distinction
is spurious, as it was proposed on the basis that hof styles are "not a
problem" in scheme, but "make me worry" in lisp.

if one reflects on the meaning of "style", that is, a mode of expression which
is chosen to make a point, there is little point to be made by distinguishing
do* from map* on the basis of imputed costs of closure creation. the
distinctions which the stylistic variations where purported to express do not
necessarily hold. there are other distinctions for which the suggested
variations provide no adequate expression. thus the a.e.newman reference.

- what expression does the style suggest where the operator is to be provided
with multiple arguments?

- are the other means available to express the extent of the function object
not adequate?

- hasn't cl implementation practice advanced to the point where constancy
analysis mitigates the worry?

the remaining factors which come to mind - the costs of actual function
invocation and of non-local lexical reference, would bear experimental
analysis in a given particular implementation before serving as adequate bases
for stylistic criteria.

further, unless i misunderstood the intended meaning when i equated an absence
of worry with no cause for concern, then the characterization of the situation
with scheme was a revelation. if there have been advances in the standards for
scheme implementation to the extent that up/down-#' and constancy analysis can
now obviate a concern about the space performance of arbitrary hof expressions
which would otherwise be raised by the standard's stipulations as to the
indefinite extent of all objects, i would be grateful for links.

>    Of
> course this is a very simple example, so in some cases it can be
> optimized away to producing the same thing.  It's the style that is
> different -- when I'm writing Lisp, I'll prefer using a built-in
> iteration and not use some HOF, and in Scheme I don't care about it.
> 
> (Another indication is how common it is to have nested functions in
> Scheme and in Lisp.)

if that is written as intended, i don't understand what it was intended to indicate.
if it was intended to have been written as "and not in lisp", i suggest that
experience varies.

...
From: Eli Barzilay
Subject: Re: *style* [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <skekxnh0o6.fsf@mojave.cs.cornell.edu>
james anderson <··············@setf.de> writes:

> then, i'll respond just one more time -- the suggested stylistic
> distinction is spurious, as it was proposed on the basis that hof
> styles are "not a problem" in scheme, but "make me worry" in lisp.

The wording might not have been the best, but I think the intent
should be obvious.  If not, too bad.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F834B14.850D6FAC@setf.de>
Eli Barzilay wrote:
> 
> ...
> 
> > > Yes, but I was talking about the difference approaches, for
> > > example:
> > >
> > >   (dolist (x foo)
> > >     (bar x))
> > >
> > > vs:
> > >
> > >   (mapc #'bar foo)
> >
> > are these not two examples of coding in common-lisp. how do they
> > demonstrate that "scheme is much more functional"?
> 
> The first is very popular, the second is hardly known.

somehow i wonder if we're discussing the same language.

>    R5RS has
> `for-each' which is exactly like `mapc', but no `dolist' equivalent.
> In Scheme, this is not a problem, in Lisp, the syntax makes me worry
> for the extra effort in creating a closure.
> 

what me worry? about syntax?

? (defmacro Barzilay (type operator &rest lists)
  `(map ',type (function ,operator) ,@lists))
BARZILAY
? (BARZILAY vector evenp '(1 2 3 4))
#(NIL T NIL T)
? (defmacro Barzilac (operator &rest lists)
  `(mapc (function ,operator) ,@lists))
BARZILAC
? (Barzilac (lambda (x) (print x)) '(1 2 3 4))

1 
2 
3 
4 
(1 2 3 4)
? (defmacro Barzilar (operator &rest lists)
  `(mapcar (function ,operator) ,@lists))
BARZILAR
? (Barzilar + '(1 2 3 4) '(5 6 7 8))
(6 8 10 12)
? 

...
From: Eli Barzilay
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <skzngchapk.fsf@mojave.cs.cornell.edu>
james anderson <··············@setf.de> writes:

> Eli Barzilay wrote:
> > 
> > > > Yes, but I was talking about the difference approaches, for
> > > > example:
> > > >
> > > >   (dolist (x foo)
> > > >     (bar x))
> > > >
> > > > vs:
> > > >
> > > >   (mapc #'bar foo)
> > >
> > > are these not two examples of coding in common-lisp. how do they
> > > demonstrate that "scheme is much more functional"?
> > 
> > The first is very popular, the second is hardly known.
> 
> somehow i wonder if we're discussing the same language.

These are both Lisp examples.  The first is much more popular than the
second.  Scheme has an equivalent for the second, not for the first.

Conclusion: the first one is stylistically preferred in Lisp, the
(equivalent of the) second is stylistically preferred in Scheme.


> > R5RS has `for-each' which is exactly like `mapc', but no `dolist'
> > equivalent.  In Scheme, this is not a problem, in Lisp, the syntax
> > makes me worry for the extra effort in creating a closure.
> 
> what me worry? about syntax?
> [...]

You completely missed my point.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F835B3E.EAEE991@setf.de>
Eli Barzilay wrote:
> 
> james anderson <··············@setf.de> writes:
> 
> > Eli Barzilay wrote:
> > ...
> 
> > > R5RS has `for-each' which is exactly like `mapc', but no `dolist'
> > > equivalent.  In Scheme, this is not a problem, in Lisp, the syntax
> > > makes me worry for the extra effort in creating a closure.
> >
> > what me worry? about syntax?
> > [...]
> 
> You completely missed my point.

if the point was about something other than when and if a closure is created
and whether that differentiates lisp from scheme, then yes, i did.

...
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F82EF06.F3D7A10@setf.de>
Matthias Blume wrote:
> 
> ·······@mediaone.net (Raffael Cavallaro) writes:
> 
> ...
> > Two words: code duplication.
> ...
> 
> Three words and a hyphen: Higher-Order Functions.
> 
> Most of the things that macros can do can be done with HOFs with just
> as little source code duplication as with macros.  (And with macros
> only the source code does not get duplicated, the same not being true
> for compiled code.  With HOFs even executable code duplication is
> often avoided -- depending on compiler technology.)

is the no advantage to being able to do either - or both - as the occasion dictates?

i'd be interested to read examples of things which are better done with HOF
features which are not available in CL. sort of the flip-side to the example
of compile-time calculation and code generation. taking into account that
generic functions are, at least to some extent, the equivalent of value-domain macro-expansion.

?
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pan.2003.10.07.18.01.27.744508@knm.org.pl>
On Tue, 07 Oct 2003 18:54:41 +0200, james anderson wrote:

>> Three words and a hyphen: Higher-Order Functions.

> is the no advantage to being able to do either - or both - as the
> occasion dictates?

The main disadvantage of macros is that they either force the syntax
to look like Lisp, or the way to present code snippets to macros is
complicated (Template Haskell), or they are as limited as C preprocessor
(which can't examine parameters).

I find the Lisp syntax hardly readable when everything looks alike,
mostly words and parentheses, and when every level of nesting requires
parens. I understand that it's easier to work with by macros, but it's
harder to work with by humans like I.

I have yet to find out whether there can be a macro system I would accept,
and for now I prefer to improve the syntax of HOFs. Smalltalk and Ruby use
anonymous functions a lot (despite being imperative) because they are
aesthetic; in particular a nullary function looks just like a piece of
code in [] or {}. Python's lambda is more rare, perhaps because it looks
worse: a scientific word, body limited to a single expression. Named local
functions are not a sufficient building block for control structures either:
they can't assign to local variables of outer functions.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvpth8rcfh.fsf@famine.OCF.Berkeley.EDU>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:

> I find the Lisp syntax hardly readable when everything looks alike,
> mostly words and parentheses, and when every level of nesting requires
> parens. I understand that it's easier to work with by macros, but it's
> harder to work with by humans like I.

You find delimited words more difficult than symbols?  For literate
people who use alphabet-based languages, I find this highly suspect.
Maybe readers of only ideogram languages might have different
preferences, but we are writing in English here...

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f835157@news.sentex.net>
In article <···············@famine.ocf.berkeley.edu>,
	···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> 
>> I find the Lisp syntax hardly readable when everything looks alike,
>> mostly words and parentheses, and when every level of nesting requires
>> parens. I understand that it's easier to work with by macros, but it's
>> harder to work with by humans like I.
> 
> You find delimited words more difficult than symbols?  For literate
> people who use alphabet-based languages, I find this highly suspect.
> Maybe readers of only ideogram languages might have different
> preferences, but we are writing in English here...

well, there are a few occasions where symbols are preferrable.  just
imagine mathematics with words only

hs

-- 

ceterum censeo SCO esse delendam
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvk77gqmak.fsf@famine.OCF.Berkeley.EDU>
··@heaven.nirvananet (Hartmann Schaffer) writes:

> In article <···············@famine.ocf.berkeley.edu>,
> 	···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> > Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> > 
> >> I find the Lisp syntax hardly readable when everything looks alike,
> >> mostly words and parentheses, and when every level of nesting requires
> >> parens. I understand that it's easier to work with by macros, but it's
> >> harder to work with by humans like I.
> > 
> > You find delimited words more difficult than symbols?  For literate
> > people who use alphabet-based languages, I find this highly suspect.
> > Maybe readers of only ideogram languages might have different
> > preferences, but we are writing in English here...
> 
> well, there are a few occasions where symbols are preferrable.  just
> imagine mathematics with words only

Oh, certainly.  Unlike most languages, Lisp lets you use symbols for
your own names (which is easily abused, but not very often).  A bad
example:

  ;; Lets you swear in your source code, cartoonishly
  (define-symbol-macro $%^&!
    (error "Aw, $%^&!  Something went wrong..."))

  ;; An example use
  (defun foo (...)
    (cond
      ...
      (t $%^&!)))

And, although you generally use symbols from the KEYWORD package for
keyword arguments, you don't have to, and they don't have to be words:

  (defgeneric convert-object (object new-type)
    (:documentation "Like an extensible COERCE."))

  (defun convert (object &key ((-> to)))
    "Sugary"
    (convert-object object to))

  (defconstant -> '-> "More sugar")

  ;; Example usage
  (convert *thing* -> (class-of *other-thing*))

Of course, these are lame examples, but they show that Lisp *can*
incorporate little ascii-picture-symbols.  Good examples would
necessarily be very domain-dependant.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87smm3633h.fsf@thalassa.informatimago.com>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
>   (defconstant -> '-> "More sugar")
> 
>   ;; Example usage
>   (convert *thing* -> (class-of *other-thing*))
> 
> Of course, these are lame examples, but they show that Lisp *can*
> incorporate little ascii-picture-symbols.  Good examples would
> necessarily be very domain-dependant.

Have a look ad DrScheme. There,  you can use real images (gif, jgp) as
values. It  should not be  too difficult to  use them as  symbol names
too...

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8765j0akfk.fsf@thalassa.informatimago.com>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> The main disadvantage of macros is that they either force the syntax
> to look like Lisp, or the way to present code snippets to macros is
> complicated (Template Haskell), or they are as limited as C preprocessor
> (which can't examine parameters).
> 
> I find the Lisp syntax hardly readable when everything looks alike,
> mostly words and parentheses, and when every level of nesting requires
> parens. I understand that it's easier to work with by macros, but it's
> harder to work with by humans like I.

I don't understand what you're complaining about.

When you have macros such as loop that allow you to write stuff like:

(loop for  color in '(blue white red)
      with crosses = :crosses
      collect  (rgb color) into rgb-list
      maximize (blue-component color) into max-blue
      until (color-pleases-user color)
      finally return (vlues color rgb-list max-blue))

where are the parentheses at EVERY level you're complaining about?
where is the lisp-like syntax?


Lisp is  not commie-stuff,  nobody forces you  to program  your macros
following any hypothetical party line.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pan.2003.10.07.21.07.55.248006@knm.org.pl>
On Tue, 07 Oct 2003 21:59:11 +0200, Pascal Bourguignon wrote:

> When you have macros such as loop that allow you to write stuff like:
> 
> (loop for  color in '(blue white red)
[...]

Well, some people say the "loop" syntax is not very lispish - it's unusual
that it uses many words and few parentheses. It still uses only words and
parentheses, no other punctuation, and it introduces one pair of parentheses
for its one nesting level.

A richer alphabet is often more readable. Morse code can't be read as fast
as Latin alphabet because it uses too few different symbols. Japanese say
they won't abandon Kanji because it's more readable as soon as you know it -
you don't have to compose words from many small pieces which look alike
but each word is distinct. Of course *too* large alphabet requires long
learning and has technical difficulties, but Lisp expressions are too
little distinctive for my taste.

I know I can implement infix operators with Lisp macros, but I even don't
know how they feel because nobody uses them (do I have to explicitly open
infix region and explicitly escape from it to regular syntax?), and
arithmetic is not enough. All Lisp code I've read uses lots of parentheses
and they pile up at the end of each large subexpression so it's hard to
match them (an editor is not enough, it won't follow my eyes and won't
work with printed code).

Syntax is the thing I like the least in Lisp & Scheme.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87y8vw7imp.fsf@thalassa.informatimago.com>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:

> On Tue, 07 Oct 2003 21:59:11 +0200, Pascal Bourguignon wrote:
> 
> > When you have macros such as loop that allow you to write stuff like:
> > 
> > (loop for  color in '(blue white red)
> [...]
> 
> Well, some people say the "loop" syntax is not very lispish - it's unusual
> that it uses many words and few parentheses. It still uses only words and
> parentheses, no other punctuation, and it introduces one pair of parentheses
> for its one nesting level.

Yes.   The point is  that the  language is  rather agnostic  about any
topic, even about the syntax.   Personnaly I don't like much LOOP, but
I take it as an example by the language designers showing us that it's
even possioble to avoid parethensis if you don't want them.

 
> A richer alphabet is often more readable. Morse code can't be read as fast
> as Latin alphabet because it uses too few different symbols. Japanese say
> they won't abandon Kanji because it's more readable as soon as you know it -
> you don't have to compose words from many small pieces which look alike
> but each word is distinct. Of course *too* large alphabet requires long
> learning and has technical difficulties, but Lisp expressions are too
> little distinctive for my taste.

Well,  I would say  that kanji  is badly  designed, compared  to latin
alphabet.   The voyels  are composed  with consones  (with diacritical
marks) and  consones are  written following four  or five  groups with
additional diacritical  marks to  distinguish within the  groups. It's
more a phonetic code than a true alphabet.

 
> I know I can implement infix operators with Lisp macros, but I even don't
> know how they feel because nobody uses them (do I have to explicitly open
> infix region and explicitly escape from it to regular syntax?), and
> arithmetic is not enough. 

Most  probably, you  would write  a  macro named  WITH-INFIX and  thus
automatically scope the infix part:

    (with-infix  1 / x + 1 / ( x ^ 3 ) +  1 / ( x ^ 5 ) )

and if you write it well:
    
    (with-infix
      if a = b then format t "equal ~D~%" a ;  
        else format t "diff ~D /= ~D~%" a b ; endif ;
      for i = 1 to 10 ; print i ; next i )


> All Lisp code I've read uses lots of parentheses
> and they pile up at the end of each large subexpression so it's hard to
> match them (an editor is not enough, it won't follow my eyes and won't
> work with printed code).
> 
> Syntax is the thing I like the least in Lisp & Scheme.

I'll tell you the secret: yes  there are alot of parethesis. This is a
price  all  lispers  pay  for  greater benefits.   It  gives  us  such
advantages that we gladly pay the price.

Otherwise, I would say:

    1- don't pay so much attention to the parenthesis!

    2- if you have to and it's hard, then it means the code is badly
       structured (probably too big a function). Rewrite it, factorize.

    3- what do you mean  "printed"?  A double-click on any parenthesis
       selects the enclosed list so it's quite easy to  see what it encloses.



-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Tim Hochberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <zeIgb.15833$gi2.11865@fed1read01>
Pascal Bourguignon wrote:
> Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> 
> 
>>On Tue, 07 Oct 2003 21:59:11 +0200, Pascal Bourguignon wrote:
[SNIP]
>>A richer alphabet is often more readable. Morse code can't be read as fast
>>as Latin alphabet because it uses too few different symbols. Japanese say
>>they won't abandon Kanji because it's more readable as soon as you know it -
>>you don't have to compose words from many small pieces which look alike
>>but each word is distinct. Of course *too* large alphabet requires long
>>learning and has technical difficulties, but Lisp expressions are too
>>little distinctive for my taste.
> 
> 
> Well,  I would say  that kanji  is badly  designed, compared  to latin
> alphabet.   The voyels  are composed  with consones  (with diacritical
> marks) and  consones are  written following four  or five  groups with
> additional diacritical  marks to  distinguish within the  groups. It's
> more a phonetic code than a true alphabet.
[SNIP]

Admittedly, I found the above paragraph pretty hard to parse and my 
never stellar knowledge of Japanees has mostly evaporated over time, but 
I'm pretty sure you are talking about Hiragana (or Katakana), not Kanji. 
   Japaneese has three alphabets, which they mix and match in ordinary 
writing. Kanji aren't phonetic at all, they're ideograms, and can 
typically be read at least two completely different ways depending on 
the context, making reading Japanese extra confusing for the non fluent.

A random web search supplies this basic descripion of Hiragana, Katakana 
and Kanji:

http://www.kanjisite.com/html/wak/wak1.html

-tim
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87he2k778p.fsf@thalassa.informatimago.com>
Tim Hochberg <············@ieee.org> writes:

> Pascal Bourguignon wrote:
> > Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> > 
> >>On Tue, 07 Oct 2003 21:59:11 +0200, Pascal Bourguignon wrote:
> [SNIP]
> >>A richer alphabet is often more readable. Morse code can't be read as fast
> >>as Latin alphabet because it uses too few different symbols. Japanese say
> >>they won't abandon Kanji because it's more readable as soon as you know it -
> >>you don't have to compose words from many small pieces which look alike
> >>but each word is distinct. Of course *too* large alphabet requires long
> >>learning and has technical difficulties, but Lisp expressions are too
> >>little distinctive for my taste.
> > Well,  I would say  that kanji  is badly  designed, compared  to
> > latin
> > alphabet.   The voyels  are composed  with consones  (with diacritical
> > marks) and  consones are  written following four  or five  groups with
> > additional diacritical  marks to  distinguish within the  groups. It's
> > more a phonetic code than a true alphabet.
> [SNIP]
> 
> Admittedly, I found the above paragraph pretty hard to parse and my
> never stellar knowledge of Japanees has mostly evaporated over time,
> but I'm pretty sure you are talking about Hiragana (or Katakana), not
> Kanji.  Japaneese has three alphabets, which they mix and match in
> ordinary writing. Kanji aren't phonetic at all, they're ideograms, and
> can typically be read at least two completely different ways depending
> on the context, making reading Japanese extra confusing for the non
> fluent.

Absolutely.  My mistake,  sorry.  I wrote about katakana  and that was
not the subject.


> A random web search supplies this basic descripion of Hiragana,
> Katakana and Kanji:
> 
> http://www.kanjisite.com/html/wak/wak1.html
> 
> -tim
> 

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ekxo61iw.fsf@comcast.net>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Most  probably, you  would write  a  macro named  WITH-INFIX and  thus
> automatically scope the infix part:
>
>     (with-infix  1 / x + 1 / ( x ^ 3 ) +  1 / ( x ^ 5 ) )
>
> and if you write it well:
>     
>     (with-infix
>       if a = b then format t "equal ~D~%" a ;  
>         else format t "diff ~D /= ~D~%" a b ; endif ;
>       for i = 1 to 10 ; print i ; next i )

CGOL is an Algol-like syntax for MacLisp that was designed by Vaughn
Pratt.  I believe it has been ported to CL.

    ABSTRACT

            MACLISP programmers who feel comfortable with ALGOL-like
    notation, that is, an algebraic style in which one might write a
    matrix multiply routine as

            for i in 1 to n do
              for k in 1 to n do
                (ac := 0;
                 for j in 1 to n do
                    ac := ac + a(i,j)*b(j,k);
                 c(i,k) := ac)

    can now write LISP programs in just such a notation.  This notation is
    essentially transparent to the MACLISP system, and files containing
    CGOL code (possibly mixed in with standard code) can be read by the
    interpreter and compiled by the compiler just as though they were
    written in straight LISP notation. 


It has never caught on, though.


> I'll tell you the secret: yes  there are alot of parethesis. This is a
> price  all  lispers  pay  for  greater benefits.   It  gives  us  such
> advantages that we gladly pay the price.

Excerpts from real C header files:

#define FromHex(n) (((n) >= 'A') ? ((n) + 10 - 'A') : ((n) - '0'))
#define StreamFromFOURCC(fcc) ((WORD) ((FromHex(LOBYTE(LOWORD(fcc))) << 4) + (FromHex(HIBYTE(LOWORD(fcc))))))
#define ToHex(n) ((BYTE) (((n) > 9) ? ((n) - 10 + 'A') : ((n) + '0')))
#define MAKEAVICKID(tcc,stream)  MAKELONG((ToHex((stream) & 0x0f) << 8) | (ToHex(((stream) & 0xf0) >> 4)),tcc)

#define va_arg(AP, TYPE)      \
 (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
  *((TYPE *) (void *) ((char *) (AP)     \
         - ((sizeof (TYPE) < __va_rounded_size (char) \
      ? sizeof (TYPE) : __va_rounded_size (TYPE))))))

#define PLAUSIBLE_BLOCK_START_P(addr, offset)    \
((*((format_word *)       \
    (((char *) (addr)) + ((offset) - (sizeof (format_word)))))) == \
   ((BYTE_OFFSET_TO_OFFSET_WORD(offset))))
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87d6d87693.fsf@thalassa.informatimago.com>
·············@comcast.net writes:
> Excerpts from real C header files:
> 
> #define FromHex(n) (((n) >= 'A') ? ((n) + 10 - 'A') : ((n) - '0'))
> #define StreamFromFOURCC(fcc) ((WORD) ((FromHex(LOBYTE(LOWORD(fcc))) << 4) + (FromHex(HIBYTE(LOWORD(fcc))))))
> #define ToHex(n) ((BYTE) (((n) > 9) ? ((n) - 10 + 'A') : ((n) + '0')))
> #define MAKEAVICKID(tcc,stream)  MAKELONG((ToHex((stream) & 0x0f) << 8) | (ToHex(((stream) & 0xf0) >> 4)),tcc)
> 
> #define va_arg(AP, TYPE)      \
>  (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
>   *((TYPE *) (void *) ((char *) (AP)     \
>          - ((sizeof (TYPE) < __va_rounded_size (char) \
>       ? sizeof (TYPE) : __va_rounded_size (TYPE))))))
> 
> #define PLAUSIBLE_BLOCK_START_P(addr, offset)    \
> ((*((format_word *)       \
>     (((char *) (addr)) + ((offset) - (sizeof (format_word)))))) == \
>    ((BYTE_OFFSET_TO_OFFSET_WORD(offset))))


:-)


However, taking sources written by  the same programmer (me), at about
the same  period, I get  thrice or twice  as many parenthesis  in Lisp
than in C:

-------    -----    -----  ------------------------------------
(-paren    loc      (/lin  Language
-------    -----    -----  ------------------------------------
    160 /    627 =  0.255  COBOL sources.
   6697 /  18968 =  0.353  C  sources (.h + .c)
    327 /    825 =  0.396  Java sources.
   9071 /  18968 =  0.478  C  sources, counting both ( and {
     15 /     31 =  0.484  FORTRAN-IV (I've got only one toy program).
  15224 /  29990 =  0.508  Modula-2 sources (* comments! *).
  14754 /  13890 =  1.062  Lisp sources.
-------    -----    -----  ------------------------------------

That's not much more...




for f in *.{h,c,lisp} ; do printf "%6d " $( sed -e 's/[^(]//g'<$f|tr -d '\012'|wc -c ) ; wc $f ; done|awk '{p=$1;l=$2;w=$3;c=$4;n=$5;printf "%6d / %6d = %6.3f %s\n",p,l,p/l,n;pt+=p;lt+=l;}END{printf "%6d / %6d = %6.3f %s\n",pt,lt,pt/lt,"Total";}'


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Ng Pheng Siong
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm08d6$l6f$1@mawar.singnet.com.sg>
According to Pascal Bourguignon  <····@thalassa.informatimago.com>:
> Well,  I would say  that kanji  is badly  designed, compared  to latin
> alphabet.   The voyels  are composed  with consones  (with diacritical
> marks) and  consones are  written following four  or five  groups with
> additional diacritical  marks to  distinguish within the  groups. It's
> more a phonetic code than a true alphabet.

Kanji are ideograms borrowed from Chinese. Kanji literally means "Han
character". 

I think the diacritical marks you mention are pronunciation guides, much
like Hanyu Pinyin is a Mandarin pronunciation guide for Chinese.

In Hanyu Pinyin, Kanji (read as a Chinese word phrase) is rendered "han4
zi4". 

In Korean, Kanji is pronounced Hanja.

Same two-character word phrase, different pronunciations.


-- 
Ng Pheng Siong <····@netmemetic.com> 

http://firewall.rulemaker.net  -+- Manage Your Firewall Rulebase Changes
http://sandbox.rulemaker.net/ngps -+- Open Source Python Crypto & SSL
From: Bruce Lewis
Subject: algebra/prefix/infix (was: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <nm965izkgmh.fsf_-_@department-of-alchemy.mit.edu>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Most  probably, you  would write  a  macro named  WITH-INFIX and  thus
> automatically scope the infix part:
> 
>     (with-infix  1 / x + 1 / ( x ^ 3 ) +  1 / ( x ^ 5 ) )

How about a with-algebraic macro?  Someone mentioned that Python uses a
nice algebraic syntax.  That would obviously be different from the infix
syntax you illustrated.  With infix syntax, it takes some examination to
notice that the above expression is the sum of three fractions.  You
have to think about operator precedence and everything.  With algebraic
syntax you could see it at a glance:

  1       1       1
----- + ----- + -----
          3        5
x + 1    x        x


Of course, prefix notation would also make it obvious at a glance that
you have the sum of three fractions:

(+ (/ 1 (+ x 1))
   (/ 1 (expt x 3))
   (/ 1 (expt x 5)))

You're already pretty close to algebraic syntax once you upgrade from
infix to prefix notation.  But that actual algebraic syntax must be
really cool in Python.  Isn't there some math tool out there that also
does it?

When Python programmers put algebraic formulas in their code, does it
mess up the indentation at all?  I'm curious exactly how it works.
From: David Rush
Subject: OT: Japanese Orthography (was Re: Python syntax in Lisp and Scheme)
Date: 
Message-ID: <oprwpt6lv83seq94@news.nscp.aoltw.net>
On 08 Oct 2003 <····@thalassa.informatimago.com> wrote:

> Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
>> A richer alphabet is often more readable. Morse code can't be read as 
>> fast as Latin alphabet because it uses too few different symbols. 
>> Japanese say they won't abandon Kanji because it's more readable
>> as soon as you know it -

Rather like Lispers ;)

>> you don't have to compose words from many small pieces which look alike
>> but each word is distinct.

Very -ish. Kanji is pictographic and the Japanese borrowed their usage
from China several times over the course of a thousand years so from
what a westerner might call reading POV, it's a mess. Having learned
to read Kanji; however, I have to say that the leverage you get from
the pictograms is amazing. I found myself quite able to navigate myself
to (and through) government offices whose name I didn't even begin to 
know,but whose function was clear from the kanji on the door.

>> Of course *too* large alphabet requires long
>> learning and has technical difficulties,

Indeed Japanese children spend most of gradeschool learning the first 2000
or so Kanji. By the time you finish university it can be necessary to know
up to 10,000 (or so my wife tells me).

>> but Lisp expressions are too
>> little distinctive for my taste.

I'll grant that Lisp is rough in vanilla VI, but who uses that anymore? 
Syntax coloring and auto-indenting make it virtually identical to Python.
I would go so far as to say that I *read* lisp via indentation.

> Well,  I would say  that kanji  is badly  designed, compared  to latin
> alphabet.   The voyels  are composed  with consones  (with diacritical
> marks) and  consones are  written following four  or five  groups with
> additional diacritical  marks to  distinguish within the  groups. It's
> more a phonetic code than a true alphabet.

Sorry, but that's all any alphabet is. The Kana are particularly aptly 
suited to the Japanese language which is phonetically *very* simple. The 
Kana encode the basic syllables - *all* of them. English/Latin is a 
disaster by comparison.

All of which goes to show something like: languages make sense in the 
context
where they are used - otherwise they wouldn't be used...

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsy8vvejag.fsf@black132.ex.ac.uk>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Well,  I would say  that kanji  is badly  designed, compared  to latin
> alphabet.   The voyels  are composed  with consones  (with diacritical
> marks) and  consones are  written following four  or five  groups with
> additional diacritical  marks to  distinguish within the  groups. It's
> more a phonetic code than a true alphabet.

Huh? You seem to be confused (BTW French is misleading here: it's vowels and
consonants in English). *Kanji* are not phonetic, you seem to be talking about
*kana*. And the blanket claim that Japanese spelling in kana is badly designed
compared to say, English orthography seems really rather dubious to me.

'as
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvd6d7r23b.fsf@famine.OCF.Berkeley.EDU>
Alexander Schmolck <··········@gmx.net> writes:

> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
> > The voyels  are composed  with consones
>
> And the blanket claim that Japanese spelling in kana is badly
> designed compared to say, English orthography seems really rather
> dubious to me.

And you can tell by his phrasing that he was straining against writing
that in English ;-)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Erik Max Francis
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F847014.C79A9E61@alcyone.com>
Alexander Schmolck wrote:

> Huh? You seem to be confused (BTW French is misleading here: it's
> vowels and
> consonants in English). *Kanji* are not phonetic, you seem to be
> talking about
> *kana*. And the blanket claim that Japanese spelling in kana is badly
> designed
> compared to say, English orthography seems really rather dubious to
> me.

Yes, indeed.  Kana is a far more efficient alphabet -- in terms of
graphemes mapping to the same sounds consistently -- than English.  Of
course, its orthography fits the Japanese language, not English, so kana
is not nearly as effective for writing English words (of course, the
Japanese happily do it).

But if someone is writing Japanese in kana (rather than kanji), it is
far easier to accurately read back what is written based only on the
kana.  The exceptions are some transformations done for brevity, usually
at the end of a sentence (desu ~= "dess"; "shita" ~= "shta"), and the
grammatical particles which for historical reasons are written different
than they're pronounced.

I saw a figure quoted for the efficiency (in that grapheme-phoneme
consistency mapping I mentioned earlier) of kana that put it well above
95%.  I can't fathom how low English's efficiency would be.

-- 
   Erik Max Francis && ···@alcyone.com && http://www.alcyone.com/max/
 __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/  \ That's what I'm about / Holding out / Holding out for my baby
\__/  Sandra St. Victor
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87zngb4h77.fsf@thalassa.informatimago.com>
Alexander Schmolck <··········@gmx.net> writes:

> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
> > Well,  I would say  that kanji  is badly  designed, compared  to latin
> > alphabet.   The voyels  are composed  with consones  (with diacritical
> > marks) and  consones are  written following four  or five  groups with
> > additional diacritical  marks to  distinguish within the  groups. It's
> > more a phonetic code than a true alphabet.
> 
> Huh? You seem to be confused (BTW French is misleading here: it's vowels and
> consonants in English). *Kanji* are not phonetic, you seem to be talking about
> *kana*. 

Yes, I was. Thank you.


> And the blanket claim that Japanese spelling in kana is badly designed
> compared to say, English orthography seems really rather dubious to me.
> 
> 'as

I was criticising the graphical aspect on a discrimination stand-point.

For example, the difference between the latin glyphs for "ka" and "ga"
is bigger than that between the corresponding kana glyphs.

But it does not matter since the topic was kanji...


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwqr8fj13seq94@news.nscp.aoltw.net>
On 08 Oct 2003 22:17:48 +0200, Pascal Bourguignon
> Alexander Schmolck <··········@gmx.net> writes:
>> And the blanket claim that Japanese spelling in kana is badly designed
>> compared to say, English orthography seems really rather dubious to me.
> I was criticising the graphical aspect on a discrimination stand-point.
>
> For example, the difference between the latin glyphs for "ka" and "ga"
> is bigger than that between the corresponding kana glyphs.

But the actual pronunciation difference (consonantal vocalization) is far
closer to the graphical difference in kana.

> But it does not matter since the topic was kanji...

But Kanji are not, and no-one has ever even remotely claimed that Kanji
are phonetic. In fact their main advantage is that they are *not* phonetic.
They were made that way by the Chinese so that all parts of the empire
could communicate even though they spoke widely varying dialects.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsekxne2n5.fsf@black132.ex.ac.uk>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Alexander Schmolck <··········@gmx.net> writes:
> I was criticising the graphical aspect on a discrimination stand-point.
> 
> For example, the difference between the latin glyphs for "ka" and "ga"
> is bigger than that between the corresponding kana glyphs.

Hear, hear: a lisper arguing for trading off simplicity, extensibility[1] and
regularity for discriminatability :)

Maybe someone more proficient in Japanese might want to correct me, but I
really suspect it isn't worth it, actually. I don't think the heightened
discrimnatibility is needed that much and in fact would often even be
detrimental because a certain semantic compound often changes from
unvoiced to voiced (or from "big" to "little" TSU) in a fairly regular manner
in compound words (e.g. TETSU
(iron); $BE4!($F$D(B and HAN $BHD!($O$s(B(plate, inter alia) -> 
TEPPAN, $BE4HD!((B $B$F$C$Q$s(B'iron plate/teppan cooking'; 
there is no TETSUHAN to confuse it with, AFAIK, so the fact that the
similarity between compound and parts is retained in the kana (unlike the
romanji transliteration) is likely to be rather desirable).

'as

[hmm, never tried embedding japanese characters in usenet posting, hope it
works :|]



[1] yep, I mean it: katakana have actually be straighforwardly extended
    relatively recently to provide better transliterations for (mainly
    English) loan words.
From: Matthias
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <36whe2kt879.fsf@chagall.ti.uni-mannheim.de>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:

> All Lisp code I've read uses lots of parentheses
> and they pile up at the end of each large subexpression so it's hard to
> match them (an editor is not enough, it won't follow my eyes and won't
> work with printed code).

The paranthesis argument.  Are there really no new things under the sun? ;-)

Well, in Lisp as in most other languages (esp. Python) you read source
code by indentation, not by matching parentheses.  That is why some
Lispers are a bit intolerant against non-standard indentation.  They
use it (mentally) to parse the language.  The parenthesis really are a
personal-taste-only issue.
From: Dirk Thierbach
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <jtbb51-562.ln1@ID-7776.user.dfncis.de>
james anderson <··············@setf.de> wrote:
> Matthias Blume wrote:

>> Most of the things that macros can do can be done with HOFs with just
>> as little source code duplication as with macros.  (And with macros
>> only the source code does not get duplicated, the same not being true
>> for compiled code.  With HOFs even executable code duplication is
>> often avoided -- depending on compiler technology.)

> is the no advantage to being able to do either - or both - as the
> occasion dictates?

I can't parse this sentence, but of course you can also use HOFs in Lisp
(all flavours). The interesting part is that most Lisp'ers don't seem
to use them, or even to know that you can use them, and use macros instead.

The only real advantage of macros over HOFs is that macros are guaranteed
to to executed at compile time. A good optimizing compiler (like GHC
for Haskell) might actually also evaluate some expressions including
HOFs at compile time, but you have no control over that. 

> i'd be interested to read examples of things which are better done
> with HOF features which are not available in CL.

HOFs can of course be used directly in CL, and you can use macros to
do everything one could use HOFs for (if you really want).

The advantage of HOFs over macros is simplicity: You don't need additional
language constructs (which may be different even for different Lisp
dialects, say), and other tools (like type checking) are available for
free; and the programmer doesn't need to learn an additional concept.

- Dirk
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F8342FF.787E4132@setf.de>
Dirk Thierbach wrote:
> 
> james anderson <··············@setf.de> wrote:
> > Matthias Blume wrote:
> 
> >> Most of the things that macros can do can be done with HOFs with just
> >> as little source code duplication as with macros.  (And with macros
> >> only the source code does not get duplicated, the same not being true
> >> for compiled code.  With HOFs even executable code duplication is
> >> often avoided -- depending on compiler technology.)
> 
> > is the no advantage to being able to do either - or both - as the
> > occasion dictates?
> 
> I can't parse this sentence,

sorry:
> > is the[re] no advantage to being able to do either - or both - as the
> > occasion dictates?


>    but of course you can also use HOFs in Lisp
> (all flavours). The interesting part is that most Lisp'ers don't seem
> to use them, or even to know that you can use them, and use macros instead.
> 

while the first assertion might well be born out by a statistical analysis of,
for example, open-source code, i'm curious how one reaches the second conclusion.

> The only real advantage of macros over HOFs is that macros are guaranteed
> to to executed at compile time. A good optimizing compiler (like GHC
> for Haskell) might actually also evaluate some expressions including
> HOFs at compile time, but you have no control over that.
> 
> > i'd be interested to read examples of things which are better done
> > with HOF features which are not available in CL.
> 
> HOFs can of course be used directly in CL, and you can use macros to
> do everything one could use HOFs for (if you really want).

that's a disappointment.

> 
> The advantage of HOFs over macros is simplicity: You don't need additional
> language constructs

when did common-lisp macros become an "additional language construct"?

>     (which may be different even for different Lisp
> dialects, say), and other tools (like type checking) are available for
> free; and the programmer doesn't need to learn an additional concept.

doesn't that last phrase contradict the previous one?

i do admit to infrequent direct use of higher-order functions. one reason is
that there is little advantage to articulating the creation of functions which
have dynamic extent only, so in my use, most hof's are manifest through a
macro interface. it's the same distaste i have about inner and anonymous java
classes. the other reason is that when i moved from scheme to lisp, in the
process of porting the code which i carried over, it occurred to me that much
of what i was using higher-order functions for could be expressed more clearly
with abstract classes and appropriately defined generic function method combinations.

...
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <n0cc62h1.fsf@comcast.net>
james anderson <··············@setf.de> writes:

>> 
>> The advantage of HOFs over macros is simplicity: You don't need additional
>> language constructs
>
> when did common-lisp macros become an "additional language construct"?

That's what macros do:  they add new language constructs.

I think that many Scheme students inadvertantly get taught `macros = evil'.

> the other reason is that when i moved from scheme to lisp, in the
> process of porting the code which i carried over, it occurred to me that much
> of what i was using higher-order functions for could be expressed more clearly
> with abstract classes and appropriately defined generic function method combinations.

I also think that many Scheme students are mislead and inadvertantly
taught that one should avoid everything but LAMBDA.
From: Dirk Thierbach
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <un3d51-be1.ln1@ID-7776.user.dfncis.de>
james anderson <··············@setf.de> wrote:

>> > is the[re] no advantage to being able to do either - or both - as the
>> > occasion dictates?

Of course it's good to be able to do either. And Lisp macros are a 
powerful tool, and it's good to have it when you need it. But it's 
somewhat annoying to frequently read grossly exaggerated claims like
"lots of things you can do with Lisp macros are impossible to do in
any other language" when you can do a good part of these things even in
Lisp without macros.

>> The interesting part is that most Lisp'ers don't seem
>> to use them, or even to know that you can use them, and use macros instead.

> while the first assertion might well be born out by a statistical
> analysis of, for example, open-source code, i'm curious how one
> reaches the second conclusion.

I don't have statistical evidence, this is just my personal
impression.  On the one hand, there are the above claims, on the other
hand, I see code that would (IMHO) much more simple and elegant with
HOFs, but instead imperative assignment is used, or macros. So I then
I have the impression that the programmer doesn't really know how to
use HOFs, otherwise he would have used them. Maybe that's wrong and
they all do that on purpose, or because they don't like HOFs (like you
seem to do), but somehow this is difficult to imagine.

>> The advantage of HOFs over macros is simplicity: You don't need additional
>> language constructs

> when did common-lisp macros become an "additional language construct"?

It's "additional" in the sense that you can write programs without it,
and that different Lisp dialects use a different syntax and semantics 
for macros. HOFs on the other hand are pure lambda calculus, and every
functional language has them.

>>     (which may be different even for different Lisp
>> dialects, say), and other tools (like type checking) are available for
>> free; and the programmer doesn't need to learn an additional concept.

> doesn't that last phrase contradict the previous one?

I don't see any contradiction; maybe you can be more explicit?

> i do admit to infrequent direct use of higher-order functions. one
> reason is that there is little advantage to articulating the
> creation of functions which have dynamic extent only,

Why? The whole point (or one of them) of functional languages is that
functions are first class, and you can easily use them (and you
frequently do) in 'map', 'fold', or more complicated HOFs. It's simple,
elegant, reusable, type-safe, and avoids unecessary state. A definition
like

  sum = foldr (+) 0

in Haskell is a lot better than doing an explicit loop. If you don't
use HOFs at all, then IMHO you're not doing proper functional
programming.

> so in my use, most hof's are manifest through a macro
> interface. it's the same distaste i have about inner and anonymous
> java classes.

I don't like inner and anonymous classes either: They're just a clumsy
substitute for anonymous functions, and they have too much syntactic 
garbage associated with them.

> the other reason is that when i moved from scheme to lisp, in the
> process of porting the code which i carried over, it occurred to me
> that much of what i was using higher-order functions for could be
> expressed more clearly with abstract classes and appropriately
> defined generic function method combinations.

Sometimes it is more convenient to use other forms of parametrization
(like classes). Sometimes HOFs are more natural. It really depends on
the concrete example. And of course 'classes' or similar language
features are independent from macros, and many languages provide them,
even if they don't have macros.

- Dirk
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <gYXgb.13$KR3.2021@typhoon.nyu.edu>
Dirk Thierbach wrote:

> james anderson <··············@setf.de> wrote:
> 
>>Matthias Blume wrote:
> 
> 
>>>Most of the things that macros can do can be done with HOFs with just
>>>as little source code duplication as with macros.  (And with macros
>>>only the source code does not get duplicated, the same not being true
>>>for compiled code.  With HOFs even executable code duplication is
>>>often avoided -- depending on compiler technology.)
> 
> 
>>is the no advantage to being able to do either - or both - as the
>>occasion dictates?
> 
> 
> I can't parse this sentence, but of course you can also use HOFs in Lisp
> (all flavours). The interesting part is that most Lisp'ers don't seem
> to use them, or even to know that you can use them, and use macros instead.
> 
> The only real advantage of macros over HOFs is that macros are guaranteed
> to to executed at compile time. A good optimizing compiler (like GHC
> for Haskell) might actually also evaluate some expressions including
> HOFs at compile time, but you have no control over that. 
> 
> 
>>i'd be interested to read examples of things which are better done
>>with HOF features which are not available in CL.
> 
> 
> HOFs can of course be used directly in CL, and you can use macros to
> do everything one could use HOFs for (if you really want).
> 
> The advantage of HOFs over macros is simplicity:

As R^nRS shows, simplicity leads to language specs without useful things 
(like records/struct) in them.

You want to make things simple, not any simpler (was it Einstein who 
said that?)

> You don't need additional
> language constructs (which may be different even for different Lisp
> dialects, say), 

As we well know, there is now one dominant Lisp, which is Common by 
name.  (No.  ELisp does not count as you do (require 'cl) in your .emacs 
file)  This argument is moot.

> and other tools (like type checking) are available for
> free;

Yes.  Type Checking is in CMUCL/SBCL.

> and the programmer doesn't need to learn an additional concept.

The programmer needs to learn to use the tool at its best.  If your tool 
is limited you just have to learn less.

Cheers
--
Marco
From: Andreas Rossberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F83FA7C.4030400@ps.uni-sb.de>
Dirk Thierbach wrote:
> 
> you can use macros to
> do everything one could use HOFs for (if you really want).

Really? What about arbitrary recursion?

-- 
Andreas Rossberg, ········@ps.uni-sb.de

"Computer games don't affect kids; I mean if Pac Man affected us
  as kids, we would all be running around in darkened rooms, munching
  magic pills, and listening to repetitive electronic music."
  - Kristian Wilson, Nintendo Inc.
From: Dirk Thierbach
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <5mfd51-lu3.ln1@ID-7776.user.dfncis.de>
Andreas Rossberg <········@ps.uni-sb.de> wrote:
> Dirk Thierbach wrote:

>> you can use macros to do everything one could use HOFs for (if you
>> really want).

I should have added: As long as it should execute at compile time, of
course.

> Really? What about arbitrary recursion?

I don't see the problem. Maybe you have an example? I am sure the
Lisp'ers here can come up with a macro solution for it.

- Dirk
From: Andreas Rossberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F854DCC.1030900@ps.uni-sb.de>
Dirk Thierbach wrote:
> 
>>>you can use macros to do everything one could use HOFs for (if you
>>>really want).
> 
> I should have added: As long as it should execute at compile time, of
> course.
> 
>>Really? What about arbitrary recursion?
> 
> I don't see the problem. Maybe you have an example? I am sure the
> Lisp'ers here can come up with a macro solution for it.

I'm not terribly familiar with the details of Lisp macros but since 
recursion can easily lead to non-termination you certainly need tight 
restrictions on recursion among macros in order to ensure termination of 
macro substitution, don't you? Or at least some ad-hoc depth limitation.

	- Andreas

-- 
Andreas Rossberg, ········@ps.uni-sb.de

"Computer games don't affect kids; I mean if Pac Man affected us
  as kids, we would all be running around in darkened rooms, munching
  magic pills, and listening to repetitive electronic music."
  - Kristian Wilson, Nintendo Inc.
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcv7k3eqnn5.fsf@famine.OCF.Berkeley.EDU>
Andreas Rossberg <········@ps.uni-sb.de> writes:

> Dirk Thierbach wrote:
> > 
> >>>you can use macros to do everything one could use HOFs for (if you
> >>>really want).
> > 
> > I should have added: As long as it should execute at compile time, of
> > course.
> > 
> >>Really? What about arbitrary recursion?
> > 
> > I don't see the problem. Maybe you have an example? I am sure the
> > Lisp'ers here can come up with a macro solution for it.
> 
> I'm not terribly familiar with the details of Lisp macros but since 
> recursion can easily lead to non-termination you certainly need tight 
> restrictions on recursion among macros in order to ensure termination of 
> macro substitution, don't you? Or at least some ad-hoc depth limitation.

I'm not terribly familiar with the details of Python's iteration constructs
but since iteration can easily lead to non-termination you certainly need tight
restrictions on ...

In some cases, recursive macros and functions are easier to get right
(avoid infinite recursion) than their iterative counterparts.
Careless coders will always find a way to code themselves into
infinite loops.  The easy way to avoid infinite recursion is:

  (cond
   ((===> base case <===) ...)
   ((===> another base case? <===) ...)
   ((...) recursive call)
   ((...) recursive call)
   ...
   (t recursive call))

Most of the time, it's easy to ensure that all recursive calls "move
up" the cond tree.  Times when you can't do that (or not easily), you
should be writing iterative code, or you're just doing something
inherently difficult.

> "Computer games don't affect kids; I mean if Pac Man affected us
>   as kids, we would all be running around in darkened rooms, munching
>   magic pills, and listening to repetitive electronic music."
>   - Kristian Wilson, Nintendo Inc.

(That's a great sig!)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Raymond Wiker
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <868ynuinby.fsf@raw.grenland.fast.no>
Andreas Rossberg <········@ps.uni-sb.de> writes:

> Dirk Thierbach wrote:
>>
>>>>you can use macros to do everything one could use HOFs for (if you
>>>>really want).
>> I should have added: As long as it should execute at compile time, of
>> course.
>>
>>>Really? What about arbitrary recursion?
>> I don't see the problem. Maybe you have an example? I am sure the
>> Lisp'ers here can come up with a macro solution for it.
>
> I'm not terribly familiar with the details of Lisp macros but since
> recursion can easily lead to non-termination you certainly need tight
> restrictions on recursion among macros in order to ensure termination
> of macro substitution, don't you? Or at least some ad-hoc depth
> limitation.

        Same as with function calls, you mean?

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Andreas Rossberg
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F85649A.5090605@ps.uni-sb.de>
Raymond Wiker wrote:
>>
>>I'm not terribly familiar with the details of Lisp macros but since
>>recursion can easily lead to non-termination you certainly need tight
>>restrictions on recursion among macros in order to ensure termination
>>of macro substitution, don't you? Or at least some ad-hoc depth
>>limitation.
> 
>         Same as with function calls, you mean?

In functional languages you at least have no limitation whatsoever on 
the depth of tail calls. Is the same true for macros?

Apart from that, can you have higher-order macros? With mutual recursion 
between a macro and its argument? That is, can you write a fixpoint 
operator on macros?

I'm not saying that any of this would be overly useful. Just trying to 
refute Dirk's rather general statement about macros subsuming HOF's.

	- Andreas

-- 
Andreas Rossberg, ········@ps.uni-sb.de

"Computer games don't affect kids; I mean if Pac Man affected us
  as kids, we would all be running around in darkened rooms, munching
  magic pills, and listening to repetitive electronic music."
  - Kristian Wilson, Nintendo Inc.
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ad8anszd.fsf@ccs.neu.edu>
Andreas Rossberg <········@ps.uni-sb.de> writes:

> Apart from that, can you have higher-order macros? With mutual
> recursion between a macro and its argument? That is, can you write a
> fixpoint operator on macros?

Yes, you can.  This occurs when you call MACROEXPAND as part of
computing the expansion of the macro.
From: james anderson
Subject: higher-order macros [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F8587C9.8C0F3313@setf.de>
Andreas Rossberg wrote:
> 
> Raymond Wiker wrote:
> >>
> >>I'm not terribly familiar with the details of Lisp macros but since
> >>recursion can easily lead to non-termination you certainly need tight
> >>restrictions on recursion among macros in order to ensure termination
> >>of macro substitution, don't you? Or at least some ad-hoc depth
> >>limitation.
> >
> >         Same as with function calls, you mean?
> 
> In functional languages you at least have no limitation whatsoever on
> the depth of tail calls. Is the same true for macros?

any macro which cannot be implemented as a single quasiquoted form is likely
to be implemented by calling a function which computes the expansion. the only
difference between a macro function and any "normal" defined function is that
the former is not necessarily any symbol's function value. an auxiliary
function will be a function like any other function: anonymous, defined,
available in some given lexical context only. whatever. there are no intrinsic
restrictions on the computation which it performs. it need only admit to the
reality, that the environment is that of the compiler. eg, definitions which
are being compiled in the given unit "exist" if so specified only.

i am curious whether the availability of tail call elimination can have any
effect on the space performance of a function which is, in general, being
called to compute expressions for inclusion in a larger form. my intuition
says it would not matter.

> 
> Apart from that, can one have higher-order macros? With mutual recursion
> between a macro and its argument?

what would that mean? a macro-proper's argument is generally an s-expression,
and the macro function proper is not bound to a symbol and not necessarily
directly funcallable, but i suppose one could come up with use cases for
mutual recursion among the auxiliary functions.

the generated expressions, on the other hand, often exhibit mutual references.
in this regard, one might want, for example to look at j.schmidt's meta
implementation.[1] perhaps, in some sense, the mutual references which it
generates could be considered "higher-order", but that doesn't feel right.

there's also the issue, that there is nothing which prevents a macro function
from interpreting some aspects of the argument expression as instructions for
operations to be performed at compile-time. eg. constant folding. depending on
how the macro might establish constancy, i'm not sure what "order" that is.

>    That is, can you write a fixpoint
> operator on macros?

why one would ever think of doing that is beyond me, but given the standard y
operator definition [0],

? (DEFUN Y (F)
   (   (LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) H)))
     #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL (FUNCALL F (FUNCALL G  G)) 
H)))))

Y

should one feel compelled to do so, one might resort to something like

? (defmacro print* (&rest forms)
   `(progn ,@(funcall (y #'(lambda (fn)
                             #'(lambda (forms)
                                 (unless (null forms)
                                   (cons `(print ,(first forms))
                                         (funcall fn (rest forms)))))))
                      forms)))

PRINT*
? (macroexpand '(print* (list 1 2) "asdf" 'q))
(PROGN (PRINT (LIST 1 2)) (PRINT "asdf") (PRINT 'Q))
T
? (print* (list 1 2) "asdf" 'q)

(1 2) 
"asdf" 
Q 
Q
? 

> 
> I'm not saying that any of this would be overly useful. Just trying to
> refute Dirk's rather general statement about macros subsuming HOF's.
> 

hmm... i never thought of it that way.


[0] http://www.nhplace.com/kent/Papers/Technical-Issues.html
[1] http://www.cliki.net/Meta
From: ····@pobox.com
Subject: Re: higher-order macros [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7eb8ac3e.0310091452.593479bf@posting.google.com>
Macros generating macros and macros that take other macros as
arguments are quite common in Scheme. CPS-macros in particular are
higher-order macros as they take macro-continuations. Macro-lambda and
macro-apply (in syntax-rules) are further examples of higher-order
macros. Macros are closely related to multi-stage computations. In
MetaOCaml, code is just a regular value. You can write regular OCaml
functions that take, e.g., an argument of a type (char code) and
returns a value of (int->int code). These functions can be
higher-order.

Syntax-rule-level ??!lambda and ??!apply:
http://pobox.com/~oleg/ftp/Scheme/macros.html

Haskell functions as CL/Scheme macros:
http://pobox.com/~oleg/ftp/Scheme/lazy-macro-computation.txt

http://www.metaocaml.org/
From: james anderson
Subject: Re: higher-order macros [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F866C35.B7DB8217@setf.de>
·····@pobox.com" wrote:
> 
> Macros generating macros and macros that take other macros as
> arguments are quite common in Scheme
> ...
> 
> Syntax-rule-level ??!lambda and ??!apply:
> http://pobox.com/~oleg/ftp/Scheme/macros.html
> 

interesting, but to contrast that with the referenced meta implementation, the
form of the macro argument matters:

  hof                         hom
  apply op form               macro-expand (cons op form) or form
                              (either immediately or relegated to the compiler)

  fixed-point functions       fixed-point forms


are there examples where these little beasties are used in production?

...
From: Michael Sperber
Subject: Re: higher-order macros [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <y9l4qygde25.fsf@informatik.uni-tuebingen.de>
>>>>> "james" == james anderson <··············@setf.de> writes:

james> are there examples where these little beasties are used in production?

If you mean Oleg's little beasties, then the answer is yes, and in
mission-critical, million-dollar-stake applications at that.

-- 
Cheers =8-} Mike
Friede, V�lkerverst�ndigung und �berhaupt blabla
From: james anderson
Subject: Re: higher-order macros [Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F871AEA.3BEEA0F6@setf.de>
Michael Sperber wrote:
> 
> >>>>> "james" == james anderson <··············@setf.de> writes:
> 
> james> are there examples where these little beasties are used in production?
> 
> If you mean Oleg's little beasties, then the answer is yes, and in
> mission-critical, million-dollar-stake applications at that.

is one at liberty to give anything more than a rhetorical answer?

i would be interested to observe how they express themselves in the large.

> 
> --
> Cheers =8-} Mike
> Friede, V�lkerverst�ndigung und �berhaupt blabla
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm3pjv$tsc$1@f1node01.rhrz.uni-bonn.de>
Andreas Rossberg wrote:
> Dirk Thierbach wrote:
> 
>>
>>>> you can use macros to do everything one could use HOFs for (if you
>>>> really want).
>>
>>
>> I should have added: As long as it should execute at compile time, of
>> course.
>>
>>> Really? What about arbitrary recursion?
>>
>>
>> I don't see the problem. Maybe you have an example? I am sure the
>> Lisp'ers here can come up with a macro solution for it.
> 
> 
> I'm not terribly familiar with the details of Lisp macros but since 
> recursion can easily lead to non-termination you certainly need tight 
> restrictions on recursion among macros in order to ensure termination of 
> macro substitution, don't you? Or at least some ad-hoc depth limitation.

The Lisp mindset is not to solve problems that you don't have.

If your code has a bug then you need to debug it. Lisp development 
environments provide excellent debugging capabilities out of the box. 
Don't guess how hard it is when you don't have the experience yet.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  Römerstr. 164, D-53117 Bonn (Germany)
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <9o_gb.14$KR3.2113@typhoon.nyu.edu>
Andreas Rossberg wrote:
> Dirk Thierbach wrote:
> 
>>
>> you can use macros to
>> do everything one could use HOFs for (if you really want).
> 
> 
> Really? What about arbitrary recursion?

When you need arbitrary recursion you use HOF.  When macro are more 
appropriate you use them.  If you don't have both you are out of luck.

Cheers
--
Marco
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <raffaelcavallaro-222CEA.23193812102003@netnews.attbi.com>
In article <··············@tti5.uchicago.edu>,
 Matthias Blume <····@my.address.elsewhere> wrote:

> Most of the things that macros can do can be done with HOFs with just
> as little source code duplication as with macros.

Most, but not all. From <http://okmij.org/ftp/papers/Macros-talk.pdf>

"One sometimes hears that higher-order functions (and
related non-strictness) make macros unnecessary. For
example, In Haskell, 'if' is a regular function. However,
every language with more syntax than lambda-calculus
has phrases that are not expressions. Examples of such
second-class forms are: type, module, fixity and other
declarations; binding forms; statements. Only macros
can expand into a second-class object. The result of a
function is limited to an expression or a value."


> (And with macros
> only the source code does not get duplicated, the same not being true
> for compiled code.  With HOFs even executable code duplication is
> often avoided -- depending on compiler technology.)

So you're willing here to trade code size for readability. The pro-macro 
camp (myself included) find that macros make source code easier to read 
and write than the equivalent HOF solution. We're willing to trade that 
ease of use for a little compiled code size, especially when this means 
you can write your code in what amounts to a domain specific language.


> > This can only be accomplished with functions if you're
> > willing to write a set of functions that defer evaluation, by, say
> > parsing input, massaging it appropriately, and then passing it to the
> > compiler. At that point, however, you've just written your own macro
> > system, and invoked Greenspun's 10th Law.
> 
> This is false.  Writing your own macro expander is not necessary for
> getting the effect.  The only thing that macros give you in this
> regard is the ability to hide the lambda-suspensions.

But this hiding of the lambda-suspensions is the whole point. Why look 
at how the code works unless you have to? Why not work in a syntax, a 
domain specific language, that matches the problem? Put the complexity 
into one place (the macro) and make the rest of the code easier to 
write, and clearer to read.

For me, macros are about making the code one writes match the problem 
one is thinking about. HOFs seem to me to be about looking cleverly 
functional, not making the code look like the problem domain.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pan.2003.10.13.11.11.45.541879@knm.org.pl>
On Mon, 13 Oct 2003 03:19:11 +0000, Raffael Cavallaro wrote:

> Most, but not all. From <http://okmij.org/ftp/papers/Macros-talk.pdf>
> 
> "One sometimes hears that higher-order functions (and
> related non-strictness) make macros unnecessary. For
> example, In Haskell, 'if' is a regular function.

It's not. It could easily be a regular function which would look like
'if condition branch1 branch2' and behave exactly the same (arguments
would often have to be parenthesized), but it's a keyword with the syntax
'if condition then branch1 else branch2' (condition and branches don't
have to be parenthesized because of 'then' and 'else' delimiters).
OTOH && and || are regular functions.

> So you're willing here to trade code size for readability. The pro-macro 
> camp (myself included) find that macros make source code easier to read 
> and write than the equivalent HOF solution. We're willing to trade that 
> ease of use for a little compiled code size, especially when this means 
> you can write your code in what amounts to a domain specific language.

Note that Lisp and Scheme have a quite unpleasant anonymous function
syntax, which induces a stronger tension to macros than in e.g. Ruby or
Haskell.

In Haskell one often passes around monadic actions instead of anonymous
nullary functions, so it's not only the lambda syntax. Putting such action
in a function argument doesn't make it run. Laziness also reduces the
number of anonymous functions. Partial application doesn't require lambda,
binary operators can be partially applied on either argument. The 'do'
notation and list comprehensions are another case where other languages
would use anonymous functions. Yes, they are built in the language rather
than library features - but with all these things only few anonymous
functions remain and thus they are not so scary.

I happen to be in the other camp. Macros indeed make it easier to embed a
domain-specific language, OTOH they require the rest of the syntax to be
more regular than pretty (so they can examine code) and they make the
language and its implementations complicated. Just a tradeoff...

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <raffaelcavallaro-0CE62B.17311413102003@netnews.attbi.com>
In article <······························@knm.org.pl>,
 Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:

> Note that Lisp and Scheme have a quite unpleasant anonymous function
> syntax, which induces a stronger tension to macros than in e.g. Ruby or
> Haskell.

Actually, I think that any anonymous function syntax is undesirable. I 
think code is inerently more readable when functions are named, 
preferably in a descriptive fashion.

I think it is the mark of functional cleverness that people's code is 
filled with anonymous functions. These show you how the code is doing 
what it does, not what it is doing.

Macros, and named functions, focus on what, not how. HOFs and anonymous 
functions focus on how, not what. How is an implementation detail. What 
is a public interface, and a building block of domain specific languages.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8yno1dvi.fsf@comcast.net>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> In article <······························@knm.org.pl>,
>  Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:
>
>> Note that Lisp and Scheme have a quite unpleasant anonymous function
>> syntax, which induces a stronger tension to macros than in e.g. Ruby or
>> Haskell.
>
> Actually, I think that any anonymous function syntax is undesirable. I 
> think code is inerently more readable when functions are named, 
> preferably in a descriptive fashion.

So it'd be even *more* readable if every subexpression were named as
well.  Just write your code in A-normal form.

> I think it is the mark of functional cleverness that people's code is 
> filled with anonymous functions. These show you how the code is doing 
> what it does, not what it is doing.

I disagree.  This:

  (map 'list (lambda (x) (+ x offset)) some-list)

is clearer than this:

  (flet ((add-offset (x) (+ x offset)))
    (map 'list #'add-offset some-list))
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <q-KdncVZlO2AgxGiU-KYgw@comcast.com>
<·············@comcast.net> wrote in message
·················@comcast.net...
> I disagree.  This:
>
>   (map 'list (lambda (x) (+ x offset)) some-list)
>
> is clearer than this:
>
>   (flet ((add-offset (x) (+ x offset)))
>     (map 'list #'add-offset some-list))

I agree for this example (and for the Python equivalent).  But if the
function definition is several lines, then I prefer to have it defined
first so that the map remains a mind-bite-sized chunk.

TJR
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f8c2752@news.sentex.net>
In article <······················@comcast.com>,
	"Terry Reedy" <·······@udel.edu> writes:
> 
> <·············@comcast.net> wrote in message
> ·················@comcast.net...
>> I disagree.  This:
>>
>>   (map 'list (lambda (x) (+ x offset)) some-list)
>>
>> is clearer than this:
>>
>>   (flet ((add-offset (x) (+ x offset)))
>>     (map 'list #'add-offset some-list))
> 
> I agree for this example (and for the Python equivalent).  But if the
> function definition is several lines, then I prefer to have it defined
> first so that the map remains a mind-bite-sized chunk.

i agree with your evaluation of what is preferrablem but i think you
would be surprised how clear the amove construct can look when
properly indented (something a decent editor would do automatically)

hs

-- 

ceterum censeo SCO esse delendam
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <raffaelcavallaro-583E78.11332714102003@netnews.attbi.com>
In article <············@comcast.net>, ·············@comcast.net wrote:

> (flet ((add-offset (x) (+ x offset)))
>     (map 'list #'add-offset some-list))

But flet is just lambda in drag. I mean real, named functions, with 
defun. Then the code becomes:

(add-offset the-list)

instead of either of theversions you gave. The implementation details of 
add-offset are elswere, to be consulted only when needed. They don't 
interrupt the flow of the code, or the reader's understanding of what it 
does. If you need that optimization, you can always throw in (declaim 
(inline 'add-offset)) before add-offset's definition(s).

I guess I'm arguing that the low level implementation details should not 
be inlined by the programmer, but by the compiler. To my eye, anonymous 
functions look like programmer inlining.
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <y8vnhkcy.fsf@ccs.neu.edu>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> In article <············@comcast.net>, ·············@comcast.net wrote:
>
>> (flet ((add-offset (x) (+ x offset)))
>>     (map 'list #'add-offset some-list))
>
> But flet is just lambda in drag. I mean real, named functions, with 
> defun. Then the code becomes:
>
> (add-offset the-list)

I'm assuming that offset is lexically bound somewhere outside
the let expression so that I have to capture it with an in-place
FLET or LAMBDA.  If we had an external add-offset then I'd have
to do something like

   (add-offset offset some-list)

The problem with this is that you've essentially outlawed MAP.

   (map 'list (make-adder offset) some-list)

The problem with this is that MAKE-ADDER is no less a lambda in drag,
and it isn't even local.
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <raffaelcavallaro-7579F1.18291714102003@netnews.attbi.com>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> 
wrote:

> The problem with this is that you've essentially outlawed MAP.
> 
>    (map 'list (make-adder offset) some-list)
> 
> The problem with this is that MAKE-ADDER is no less a lambda in drag,
> and it isn't even local.

I think you misunderstand me. I haven't outlawed map. I've simply asked 
that it be used in a _named_ function or macro that expresses _what_ is 
being done, not _how_. For example:

(defgeneric add-offset (some-sequence some-offset))

(defmethod add-offset ((some-list list) some-offset)
   (map 'list #'(lambda (x) (+ x some-offset)) some-list))

(defmethod add-offset ((some-vector vector) some-offset)
   (map 'vector #'(lambda (x) (+ x some-offset)) some-vector))


And the client code looks like your example:

(add-offset my-list current-offset)  or

(add-offset my-vector vector-offset)  etc.

Also see my reply to Thant Tessman entitled "Express What, not How."
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ismr5rme.fsf@comcast.net>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> 
> wrote:
>
>> The problem with this is that you've essentially outlawed MAP.
>> 
>>    (map 'list (make-adder offset) some-list)
>> 
>> The problem with this is that MAKE-ADDER is no less a lambda in drag,
>> and it isn't even local.
>
> I think you misunderstand me. I haven't outlawed map. I've simply asked 
> that it be used in a _named_ function or macro that expresses _what_ is 
> being done, not _how_. For example:
>
> (defgeneric add-offset (some-sequence some-offset))
>
> (defmethod add-offset ((some-list list) some-offset)
>    (map 'list #'(lambda (x) (+ x some-offset)) some-list))
>
> (defmethod add-offset ((some-vector vector) some-offset)
>    (map 'vector #'(lambda (x) (+ x some-offset)) some-vector))
>
> And the client code looks like your example:

I don't see MAP anywhere here.  Sure it's in the implementation,
but you've outlawed it at the `client' site.

>
> (add-offset my-list current-offset)  or
>
> (add-offset my-vector vector-offset)  etc.
>
> Also see my reply to Thant Tessman entitled "Express What, not How."

I agree with your sentiment of `what' not `how', but I think that
(lambda (x) (+ x offset))  is simply a convoluted name for 
`that function that adds offset'.
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <raffaelcavallaro-6459F1.20515214102003@netnews.attbi.com>
In article <············@comcast.net>, ·············@comcast.net wrote:

> I don't see MAP anywhere here.  Sure it's in the implementation,
> but you've outlawed it at the `client' site.

I've "outlawed it at the `client' site" because I don't really need to 
know that the functionality of add-offset is implemented using MAP at 
the client site. At the client site, this is just unecessary additional 
information. All unnecessary additional information reduces clarity.

Moreover, as I'm sure you're aware, should we ever decide to implement 
add-offset's functionality with something other than MAP, the loci of 
change are far fewer with named functions/macros.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ptgz47nn.fsf@comcast.net>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> In article <············@comcast.net>, ·············@comcast.net wrote:
>
>> I don't see MAP anywhere here.  Sure it's in the implementation,
>> but you've outlawed it at the `client' site.
>
> I've "outlawed it at the `client' site" because I don't really need to 
> know that the functionality of add-offset is implemented using MAP at 
> the client site. At the client site, this is just unecessary additional 
> information. All unnecessary additional information reduces clarity.

I disagree.  (add-offset offset foo) doesn't tell me that this is
a function from `list of numbers' to `list of numbers'.  I'd have
to go hunt down ADD-OFFSET to determine that.

The (map 'list (lambda (x) (+ x offset)) foo) tells me that the
resulting expression is a list of numbers of the same length as
foo.

> Moreover, as I'm sure you're aware, should we ever decide to implement 
> add-offset's functionality with something other than MAP, the loci of 
> change are far fewer with named functions/macros.

Yes.  I think the benefit of abstraction at this point is marginal,
though.
From: Raffael Cavallaro
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <raffaelcavallaro-44BD31.21254014102003@netnews.attbi.com>
I guess what I'm saying here is that anonymous functions should only be 
used to express _unique_ functionality. If they express somthing that is 
used more than once (such as your add-offset example) then that should 
be named. They shouldn't be used as a form of programmer inlining.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <he2b46ko.fsf@comcast.net>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> I guess what I'm saying here is that anonymous functions should only be 
> used to express _unique_ functionality. If they express somthing that is 
> used more than once (such as your add-offset example) then that should 
> be named. They shouldn't be used as a form of programmer inlining.

I pretty much agree with you here.
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f8c268b@news.sentex.net>
In article <······································@netnews.attbi.com>,
	Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:
> In article <············@comcast.net>, ·············@comcast.net wrote:
> 
>> (flet ((add-offset (x) (+ x offset)))
>>     (map 'list #'add-offset some-list))
> 
> But flet is just lambda in drag. I mean real, named functions, with 
> defun. Then the code becomes:
> 
> (add-offset the-list)
> 
> instead of either of theversions you gave.

the version he gave has the advantage that it doesn't clutter up the
namespace of the environment.  with

(map (lambda (x) (+ x offset)) the-list)

you have everything that is relevant in the immediate neighborhood of
the statement.  with a separate defun you have to search the program
to see what the function does.  i agree that for lengthy functions
defining it separately and just writing the name is preferrable.

> ...
> I guess I'm arguing that the low level implementation details should not 
> be inlined by the programmer, but by the compiler. To my eye, anonymous 
> functions look like programmer inlining.

i would call this a misconception

hs

-- 

ceterum censeo SCO esse delendam
From: Thant Tessman
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmh6p4$7b2$1@terabinaries.xmission.com>
Raffael Cavallaro wrote:

> [...] Actually, I think that any anonymous function syntax is undesirable. I 
> think code is inerently more readable when functions are named, 
> preferably in a descriptive fashion. [...]

Before the invention of higher-level languages like Fortran, the 
programmer was burdened with the task of naming every intermediate value 
in the calculation of an expression. A programmer accustomed to the 
functional style finds the need in non-FP languages to name every 
function analogously awkward.

-thant

-- 
America goes not abroad in search of monsters to destroy. She is
the well-wisher of the freedom and independence of all. She is
the champion and vindicator only of her own. -- John Quincy Adams
From: Dave Benjamin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnboo8n4.n1i.ramen@lackingtalent.com>
In article <············@terabinaries.xmission.com>, Thant Tessman wrote:
>
> Before the invention of higher-level languages like Fortran, the 
> programmer was burdened with the task of naming every intermediate value 
> in the calculation of an expression. A programmer accustomed to the 
> functional style finds the need in non-FP languages to name every 
> function analogously awkward.

Well put, Thant. Thank you.

-- 
.:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g   l i f e   o u t   o f   t h e   c o n t a i n e r :
From: Raffael Cavallaro
Subject: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-D3CEF4.18102214102003@netnews.attbi.com>
In article <············@terabinaries.xmission.com>,
 Thant Tessman <·····@acm.org> wrote:

> A programmer accustomed to the 
> functional style finds the need in non-FP languages to name every 
> function analogously awkward.

No one is talking about need, but about clarity of exposition.

It is perfectly possible to program functionally in lisp, as I'm sure 
you know. It just makes code less readable to use _anonymous_ functions. 
Code is no less functional when the functions are named.

A theme of this whole thread is the difference between writing _what_ 
something does, and _how_ it does it. The higher up the ladder of 
abstraction we go, the more we want to express _what_ is being done. We 
leave the _how_ defined elsewhere, to be consulted only as needed.

Anonymous functions force the _how_ to be interleaved with the _what_, 
breaking up the clarity of the _what_. Named functions (and macros) 
allow the high level abstractions to be expressed in terms of _what_ is 
happening, without unnecessary reference to _how_.

Anonymous functions force the reader to deal with _how_ precisely 
because there is no descriptive name that expresses _what_ the funtion 
does. This is an inappropriate conflation of two distinct purposes, that 
can and should be separated in source code.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Express What, not How.
Date: 
Message-ID: <pan.2003.10.14.23.19.11.733879@knm.org.pl>
On Tue, 14 Oct 2003 22:09:44 +0000, Raffael Cavallaro wrote:

> A theme of this whole thread is the difference between writing _what_ 
> something does, and _how_ it does it. The higher up the ladder of 
> abstraction we go, the more we want to express _what_ is being done. We 
> leave the _how_ defined elsewhere, to be consulted only as needed.

Sometimes a function is so simple that its body is more clear than any
name. A name is an extra level of indirection. You must follow it to be
100% sure what the function means, or to understand what does it really
mean that it does what it's named after. The code also gets longer - not
only more verbose but the structure of the code gets more complex with
more interdependent parts. When you have lots of short functions, it's
harder to find them. There are many names to invent for the writer and
many names to rememner for a reader. Function headers are administrative
stuff, it's harder to find real code among abstractions being introduced
and used.

Why do you insist on naming *functions*? You could equally well say that
every list should be named, so you would see its purpose rather than its
contents. Perhaps every number should be named, so you can see what it
represents rather than its value. You could say that each statement of
a compound statement should be moved to a separate function, so you can
see what it does by its name, not how it does it by its contents. It's
all equally absurd.

A program should balance named and unnamed objects. Both are useful,
there is a continuum between cases where one or the other is more clear
and it's subjective in border cases, but there is place for unnamed
functions - they are not that special. Most high level languages have
anonymous functions for a reason.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-7597B0.20420614102003@netnews.attbi.com>
In article <······························@knm.org.pl>,
 Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:


> Sometimes a function is so simple that its body is more clear than any
> name. A name is an extra level of indirection. You must follow it to be
> 100% sure what the function means, or to understand what does it really
> mean that it does what it's named after.

Your argument is based on the assumption that whenever people express 
_what_ a function does, they do so badly, with an inappropriate name.

We should choose our mode of expression based on how things work when 
used correctly, not based on what might happen when used foolishly. We 
don't write novels based on how they might be misread by the 
semi-litterate.

Anonymous functions add no clarity except to our understaning of 
_implementation_, i.e., _how_ not _what_. Higher level abstractions 
should express _what_. Implementation details should remain separate, 
both for clarity of exposition, and for maintanence and change of 
implementation.

> The code also gets longer 

No, it gets shorter, because you don't repeat your use of the same 
abstraction over and over. You define it once, then reference it by name 
everywhere you use it.

> - not
> only more verbose but the structure of the code gets more complex with
> more interdependent parts.

No, there are _fewer_ interdependent parts, because the parts that 
correspond to the anonymous function bodies are _completely gone_ from 
the main exposition of what is happening. These formerly anonymous 
function bodies are now elswhere, where they will only be consulted when 
it is necessary to modify them.

You seem to take the view that client code can't trust the interfaces it 
uses, that you have to see how things are implemented to make sure they 
do what they represent to do.

This is a very counterproductive attitude. Code should provide high 
level abstractions, and clients of this code should be able to tell what 
it does just by looking at the interface, and maybe a line of 
documentation. It shouldn't be necessary to understand the internals of 
code one uses just to use it. And it certainly isn't necessary to 
include the internals of code one uses where one is using it (i.e., 
anonymous functions). That's what named functions and macros are for. 
Inlining should be done by compilers, not programmers.

Anonymous functions are a form of unnecessary information overload. If I 
don't need to see how something works right here, in this particular 
context, then don't put its implementation here. Just refer to it by 
name.

> When you have lots of short functions, it's
> harder to find them. There are many names to invent for the writer and
> many names to rememner for a reader.

Which is why names should be descriptive. Then, there's little to 
remember. I don't need to remember what add-offset does, nor look up 
it's definition, to understand its use in some client code. Anonymous 
functions are sometimes used as a crutch by those who can't be bothered 
to take the time to attend to the social and communicative aspects of 
programming. Ditto for overly long function bodies. How to express 
intent to human readers is just as important as getting the compiler to 
do what you want. These same programmers seem enamored of 
crack-smokingly short and cryptic identifier and function names, as if 
typing 10 characters instead of 3 is the real bottleneck in modern 
software development. (Don't these people know how to touch type?)



> Function headers are administrative
> stuff, it's harder to find real code among abstractions being introduced
> and used.


Seemingly to you, the only "real code" is low level implementation. In 
any non-trivial software, however, the "real code" is the interplay of 
high level abstractions. At each level, we craft a _what_ from some less 
abstract _how_, and the _what_ we have just defined, is, in turn used as 
part of the _how_ for an even higher level of abstraction or 
functionality.


> Why do you insist on naming *functions*? You could equally well say that
> every list should be named, so you would see its purpose rather than its
> contents.

I think this concept is called variable bindings ;^)


> Perhaps every number should be named, so you can see what it
> represents rather than its value.

Actually, they are _already_ named. The numerals we use _are_ names, not 
numbers themselves. I'm surprised you aren't advocating the use of 
Church Numerals for all numerical calculation.

> You could say that each statement of
> a compound statement should be moved to a separate function, so you can
> see what it does by its name, not how it does it by its contents. It's
> all equally absurd.

In the Smalltalk community the rule of thumb is that if a method body 
gets to be more than a few lines, you've failed to break it down into 
smaller abstractions (i.e., methods).

> A program should balance named and unnamed objects. Both are useful,
> there is a continuum between cases where one or the other is more clear
> and it's subjective in border cases, but there is place for unnamed
> functions - they are not that special. Most high level languages have
> anonymous functions for a reason.

Yes, but they should live inside the bodies of named functions. Not lie 
exposed in the middle of higher level abstractions. Please also see my 
reply to Joe Marshall/Prunesquallor a few posts up in this thread.
From: Ken Shan
Subject: Re: Express What, not How.
Date: 
Message-ID: <tmpu51-n3q.ln1@proper.ptq.dyndns.org>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote in article <······································@netnews.attbi.com> in comp.lang.functional:
> In article <······························@knm.org.pl>,
>  Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:
> > Why do you insist on naming *functions*? You could equally well say that
> > every list should be named, so you would see its purpose rather than its
> > contents.
> I think this concept is called variable bindings ;^)

Yes, but what Marcin is talking about outlawing anonymous variables, so
for example you can't write

    amount_due = sum(item_prices) * (1 + tax_rate)

in his hypothetical programming language down the slippery slope (or is
it up the slippery slope?), but must write

    subtotal = sum(item_prices)
    tax_multiplier = 1 + tax_rate
    amount_due = subtotal * tax_multiplier

just as programmers did before FORTRAN.

I would go one step further and point out that even in the code above,
there are still unnamed things whose functionality is possibly unclear.
These things are source code locations to which computations return,
aka continuations.  For instance, what is the purpose of executing this
code above?  The purpose is not to go through a bunch of arithmetic
operations for fun, but to compute the amount due.

    def compute_amount_due:
	subtotal = sum(item_prices)
	tax_multiplier = 1 + tax_rate
	amount_due = subtotal * tax_multiplier

There, clearer already.  But what is the purpose of having the subtotal?
It is to add the tax to get the amount due.

    def compute_amount_due:
	sum(item_prices, add_tax_for_amount_due)

    def add_tax_for_amount_due(subtotal):
	tax_multiplier = 1 + tax_rate
	amount_due = subtotal * tax_multiplier

What is the purpose of computing the tax_multiplier?  To multiply with
the subtotal in order to get the amount due.  (I assume a Python-ish
syntax with partial function application (currying) here.)

    def add_tax_for_amount_due(subtotal):
	add(1, tax_rate, subtotal_and_tax_multiplier_to_amount_due(subtotal))

    def subtotal_and_tax_multiplier_to_amount_due(subtotal, tax_multiplier):
	amount_due = subtotal * tax_multiplier

But what's the purpose of having the amount due at all?  Maybe it is to
print a bill:

    def subtotal_and_tax_multiplier_to_amount_due(subtotal, tax_multiplier):
	multiply(subtotal, tax_multiplier, print_bill_with_amount_due)

    def print_bill_with_amount_due(amount_due):
	...

> > Perhaps every number should be named, so you can see what it
> > represents rather than its value.
> Actually, they are _already_ named. The numerals we use _are_ names, not 
> numbers themselves. I'm surprised you aren't advocating the use of 
> Church Numerals for all numerical calculation.

Functions are _already_ named as well.  The lambda expressions we use
_are_ names, not functions themselves.

> > You could say that each statement of
> > a compound statement should be moved to a separate function, so you can
> > see what it does by its name, not how it does it by its contents. It's
> > all equally absurd.
> 
> In the Smalltalk community the rule of thumb is that if a method body 
> gets to be more than a few lines, you've failed to break it down into 
> smaller abstractions (i.e., methods).

So perhaps we should have the programming language outlaw anonymous
functions that are more than 4 lines long...

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"The first rule of politics: The ballots don't make the vote. The count
makes the vote." -- Boss Tweed in Gangs of New York
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-30C16C.09424315102003@netnews.attbi.com>
In article <······························@knm.org.pl>,
 Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:

> You contradict yourself. First you say that "any anonymous function syntax
> is undesirable", and they you accept anonymous functions in the middle of
> higher level abstractions.

and
In article <··············@proper.ptq.dyndns.org>,
 Ken Shan <···@digitas.harvard.edu> wrote:

> So perhaps we should have the programming language outlaw anonymous
> functions that are more than 4 lines long...


I thought it was obvious that I was not advocating eliminating anonymous 
functions entirely, since I said they should be used inside named 
function bodes.

To be completely clear, I'm advocating only using anonymous functions 
when two conditions are met:

1. When the functionality provided is _unique_. If that which the 
anonymous function is performing is also done elsewhere, especially if 
it is done in several different places throughout the code, then that 
anonymous function should be recast as a descriptively named function or 
macro.

2. If it is necessary to show, at that _particular_ source location, 
_how_ a piece of functionality is provided. If the reader doesn't need 
to know _how_ things are implemented in that _particular_ source 
location, we should use a descriptively named function or macro instead.

I find that many programmers overestimate the "uniqueness" of their 
anonymous functions. They tend to repeat the same anonymous function 
idiom in many places. Rather than come up with a descriptive name for 
_what_ they are doing, they clutter a higher level abstraction with low 
level details about _how_ they are doing it. These should be recast as 
descriptively named functions or macros. 

Many programmers use anonymous functions in places where it is simply 
not necessary to know _how_ things are being implemented. In general, we 
shouldn't provide the readers of our code with information about its 
implementation that isn't necessary to know in the current context. 
Doing so obscures the current intent, and sprinkles identical 
functionality, which may need to be modified later, in many locations 
throughout the program.

To use the example that started this sub-thread, when I'm reading that a 
list or a vector has an offset added to each element, I don't need to 
know that the add-offset functionality is implemented by means of map. 
That piece of information can more safely, and more clearly, reside in a 
separate named function, add-offset, which may (or may not) use map to 
provide the add-offset functionality. This is especially true, as is 
often the case, if add-offset's functionality is used in many locations 
throughout the program. We get clearer client code, and easier 
maintenance/change if that bit of repeated functionality is isolated in 
a single, descriptively named, function or macro. Then, in that 
_particular_ source location, (defmethod add-offset...), we _do_ need to 
show _how_ add-offset is implemented. So we use anonymous function 
syntax there, as needed, in this case, with map and lambda.
From: MetalOne
Subject: Re: Express What, not How.
Date: 
Message-ID: <92c59a2c.0310151005.37701b8c@posting.google.com>
Raffael Cavallaro 

I don't know why but I feel like trying to summarize.

I initially thought your position was that lambdas should never be
used.  I believe that Brian McNamara and Ken Shan presented powerful
arguments in support of lambda.  Your position now appears to have
changed to state that lambdas are ok to use, but their use should be
restricted.  One point would appear to desire avoiding duplicate
lambdas.  This makes sense.  Duplication of this sort is often found
in "if statment" conditional tests also.  The next point would be to
name the function if a good name can be found.  I believe that
sometimes the code is clearer than a name.  Mathematical notation was
invented because natural language is imprecise.  Sometimes a name is
better than the code.  The name gives a good idea of the "how" and
perhaps you can defer looking at the "how".  Sometimes I think using
code in combination with a comment is better.  A comment can say a
little more than a name, and the code gives the precision.  So as
Marcin said, it is a balancing act to create readable code.

I would like to say that I have found this entire thread very
comforting.  I have been programming for 18 years now.  For the most
part, when I read other peoples code I see nothing but 300+ line
functions.  I have come to feel like most programmer's have no idea
what they are doing.  But when you're writing small functions and
everybody else is writing 300+ line functions you begin to wonder if
it is you that is doing something wrong.  It is nice to see that other
people actually do think about how to write and structure good code.
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-0938BA.15224215102003@netnews.attbi.com>
In article <····························@posting.google.com>,
 ···@iteris.com (MetalOne) wrote:

> Raffael Cavallaro 
> 
> I don't know why but I feel like trying to summarize.

Nice summary.

> Your position now appears to have
> changed to state that lambdas are ok to use, but their use should be
> restricted.

First, let me say that I'm not delusional enough to think that a few 
Usenet posts by me are going to change the way anyone codes. I do find 
Usenet most useful for clarifying my own thinking, however. Nothing 
forces you to be precise more than having to defend, amplify, and 
clarify your ideas in the light of other peoples comments. If that means 
that my stated position appears to have changed, then fine. The whole 
point of discussion is for people come away from it with a clearer idea 
of what both they and others really mean to say. If one's ideas are 
never modified in the slightest by discussion, then one isn't really 
listening. I would say that my position is the same - I still have the 
same tastes in source code style. However, I think that this back and 
forth has made my views much more precise (I'm pretty sure that I've 
never written up 2 explicit criteria for the appropriate use of 
anonymous functions before, for example).That increased precision is a 
good thing.

> But when you're writing small functions and
> everybody else is writing 300+ line functions you begin to wonder if
> it is you that is doing something wrong.  It is nice to see that other
> people actually do think about how to write and structure good code.

You should dowload squeak (the open source Smalltalk implementation) and 
browse the code The squeak browser, like most Smalltalk code browsers, 
is quite nice. Realizing that the entire functionality of such a complex 
dynamic environment is composed of an interconnected set of thousands of 
methods, few of them more than a dozen lines in lenght, can be a kind of 
revelation if one hasn't seen a whole system written in that style.
From: Darius
Subject: Re: Express What, not How.
Date: 
Message-ID: <9d140b81.0310151301.4b811dfa@posting.google.com>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote in message news:<······································@netnews.attbi.com>...

> I thought it was obvious that I was not advocating eliminating anonymous 
> functions entirely, since I said they should be used inside named 
> function bodes.
>
> To be completely clear, I'm advocating only using anonymous functions 
> when two conditions are met:
> 
> 1. When the functionality provided is _unique_. If that which the 
> anonymous function is performing is also done elsewhere, especially if 
> it is done in several different places throughout the code, then that 
> anonymous function should be recast as a descriptively named function or 
> macro.
> 
> 2. If it is necessary to show, at that _particular_ source location, 
> _how_ a piece of functionality is provided. If the reader doesn't need 
> to know _how_ things are implemented in that _particular_ source 
> location, we should use a descriptively named function or macro instead.

The reason people are attacking your posts is because the above has
NOTHING to do with anonymous functions.  This advice should be
followed independent of anonymous functions.

1. When the functionality provided is _unique_. If that which the 
code is performing is also done elsewhere, especially if 
it is done in several different places throughout the code, then that 
code should be recast as a descriptively named function or 
macro.

2. If it is necessary to show, at that _particular_ source location, 
_how_ a piece of functionality is provided. If the reader doesn't need
to know _how_ things are implemented in that _particular_ source 
location, we should use a descriptively named function or macro
instead.

Further in response to 2, limiting the use of anonymous functions to
only named functions that are showing how things are implemented
doesn't limit them at all!    You are virtually always in a named
function and you are always showing how to implement something. 2 is a
null statement.  Nevertheless, what (I presume) you were intending
(something along the lines of 'create and use abstraction barriers'
again has nothing to do with anonymous functions or at least no
special attachment to them.

Finally, all this advice (generalized to include all code) is a)
obvious to anyone who has been programming for more than half a day,
and b) quite standard software engineering advice.  The reason why
your position is being extended beyond your intent is simply because
people presumed from your statements of the obvious and focus on
anonymous functions that you were attempting to state something other
than the obvious.  To end this post, I feel I should bring special
attention to the fact that people over 1.98 meters should be wary of
dangerous things.
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-05B536.22511215102003@netnews.attbi.com>
In article <····························@posting.google.com>,
 ·······@hotpop.com (Darius) wrote:

> The reason people are attacking your posts is because the above has
> NOTHING to do with anonymous functions.  This advice should be
> followed independent of anonymous functions.

You're misreading those who have argued against me. They seem to think 
that this advice should _not_ be followed in the case of anonymous 
functions. I.e., the anonymous function camp seem to think that 
anonymous functions are such a wonderfully expressive tool that they are 
more clear than _actual desriptive function names_.

I agree with you; this advice should be followed, period (well, it is 
_my_ advice, after all). But advocates of a particular functional style 
think it is perfectly alright to use the same unnamed functional idiom 
over and over throughout source code, because functional abstractions 
are so wonderfully expressive. They think it is just fine to expose the 
implementation details in code locations where it is completely 
unnecessary to know the implementation specifics. 

How else can this be construed?

In article <······························@knm.org.pl>,
 Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:

> A name is an extra level of indirection. You must follow it to be
> 100% sure what the function means, or to understand what does it really
> mean that it does what it's named after. The code also gets longer - not
> only more verbose but the structure of the code gets more complex with
> more interdependent parts. When you have lots of short functions, it's
> harder to find them. There are many names to invent for the writer and
> many names to rememner for a reader. Function headers are administrative
> stuff, it's harder to find real code among abstractions being introduced
> and used.

In other words, don't use names _at all_ if you can avoid them. Just 
long, rambling tracts of code filled with anonymous functions. After 
all, you'd just have to go look at the named function bodes anyway, just 
to be _sure_ they did what they said they were doing. (I wonder if he 
disassembles OS calls too, you know, just to be sure).

Really I personally think they are often just enamored of their own 
functional l33tness, but you'll always have a hard time convincing 
programmers that their unstated preference is to write something so 
dense that only they and others equally gifted in code decipherment can 
grasp it. Many programmers take it badly when you tell them that their 
job should be much more about communicating intent to other human beings 
than about being extremely clever. As a result of this clever agenda, an 
unmaintainably large proportion of the code that has ever been written 
is way too clever for its own good.
From: ··········@ii.uib.no
Subject: Re: Express What, not How.
Date: 
Message-ID: <eg7k35mpgu.fsf@vipe.ii.uib.no>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> You're misreading those who have argued against me. They seem to think 
> that this advice should _not_ be followed in the case of anonymous 
> functions. I.e., the anonymous function camp seem to think that 
> anonymous functions are such a wonderfully expressive tool that they are 
> more clear than _actual desriptive function names_.

Anonymous functions *can* be more clear than any name.  Either because
they are short and simple, because it is hard to come up with a good
name, and/or becuase they are ambigous.

Say I want to attach an index to elements of a list.  I could write

        integers = [1..]
        attach_index ls = zip integers ls

or just

        attach_index ls = zip [1..] ls

Whether you want to give an explicit name to the list of integers is
not given.  If the indexed list is local, it is better to use the
definition directly; I don't want to look up the definition of
integers (perhaps in a different module) to check whether it is [1..]
or [0..].  

> They think it is just fine to expose the implementation details in
> code locations where it is completely unnecessary to know the
> implementation specifics.

All code exposes implementation details on some level of abstraction.
You seem to argue that an anonymous function is on a lower level of
abstraction?

> In article <······························@knm.org.pl>,
>  Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:
> 
>> A name is an extra level of indirection. You must follow it to be
>> 100% sure what the function means, or to understand what does it really
>> mean that it does what it's named after. 

Obviously true, no?

>> The code also gets longer - not only more verbose but the structure
>> of the code gets more complex with more interdependent parts.

Code gets longer if you disallow anonymous functions, but of course,
it also gets (a lot) longer if you disallow named functions.  As
Marcin said in the posting, there should be a balance.

>> When you have lots of short functions, it's harder to find
>> them. There are many names to invent for the writer and many names
>> to rememner for a reader.

Surely this is true?  Has anybody seen code where all names were
descriptive and unabmigous, yet short and concise?

>> Function headers are administrative stuff, it's harder to find real
>> code among abstractions being introduced and used.

> In other words, don't use names _at all_ if you can avoid them. Just 
> long, rambling tracts of code filled with anonymous functions. 

I don't read it like that at all.  Just that naming everything has its
cost, a cost you often don't want to pay.  If you program
imperatively, a function is often a largish chunk of code, and it
often makes sense to name it.  If you program in a functional style,
small functions are composed and combined endlessly, and naming them
would be like naming all intermediate results in an expression, as
somebody illustrated.  

It's not just lambda, but function composition, partial applications,
and so on.  If I do 

        map (f x) ls

should I name the partially applied (f x)?  I.e. is

        map (4 +) ls 

worse than

        let add_4 = (4 +) in map add_4 ls

?  And should add_4 be globally defined somewhere?  How about 

module PartialAdders where

        add_0 = (0 +)
        add_1 = (1 +)
        :       :

        import PartialAdders(add_4)
        :
        ... map add_4 ls...

I hope you agree that naming has a very real cost, and in this case,
just reduces readability, maintainabilty and efficiency.

> After all, you'd just have to go look at the named function bodes
> anyway, just to be _sure_ they did what they said they were doing.

The ability to do this, is of course important.

> (I wonder if he disassembles OS calls too, you know, just to be sure).

Presumably, the language will be well defined on some level.  Some
people have needed to do that, though.

> Really I personally think they are often just enamored of their own 
> functional l33tness,

Well, sure.  But it IS better :-)

> but you'll always have a hard time convincing programmers that their
> unstated preference is to write something so dense that only they
> and others equally gifted in code decipherment can grasp it.

The argument is one of code clarity, more than anything.  Every
language or style has the geeks who obfuscate things with excessive
cleverness.  That isn't the point here.  At least not my point.

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
From: Luke Gorrie
Subject: Re: Express What, not How.
Date: 
Message-ID: <lhad81igl6.fsf@dodo.bluetail.com>
··········@ii.uib.no writes:

> Anonymous functions *can* be more clear than any name.  Either because
> they are short and simple, because it is hard to come up with a good
> name, and/or becuase they are ambigous.
> 
> Say I want to attach an index to elements of a list.  I could write
> 
>         integers = [1..]
>         attach_index ls = zip integers ls
> 
> or just
> 
>         attach_index ls = zip [1..] ls

If we're arguing to eliminate names that don't say very much, then

  attach_index = zip [1..]

> Whether you want to give an explicit name to the list of integers is
> not given.  If the indexed list is local, it is better to use the
> definition directly; I don't want to look up the definition of
> integers (perhaps in a different module) to check whether it is [1..]
> or [0..].  

And for the exact same reason you might like to just write "zip [1..]"
instead of using a separate "attach_index" function.

Cheers,
Luke
From: Vis Mike
Subject: Re: Express What, not How.
Date: 
Message-ID: <bmpgs9$fif$1@bob.news.rcn.net>
"Luke Gorrie" <····@bluetail.com> wrote in message
···················@dodo.bluetail.com...
> ··········@ii.uib.no writes:
>
> > Anonymous functions *can* be more clear than any name.  Either because
> > they are short and simple, because it is hard to come up with a good
> > name, and/or becuase they are ambigous.
> >
> > Say I want to attach an index to elements of a list.  I could write
> >
> >         integers = [1..]
> >         attach_index ls = zip integers ls
> >
> > or just
> >
> >         attach_index ls = zip [1..] ls
>
> If we're arguing to eliminate names that don't say very much, then
>
>   attach_index = zip [1..]

I think dynamic scoping within blocks really trims down on duplication and
make the code easier to read.  For example:

employees sort: [ | a b | a date < b date ]

A lot of typing for a simple concept:

employees sort: [ < data ]

I'm not against too much typing to be clear, but rather too much typping
that makes the concept unclear.

-- Mike

> > Whether you want to give an explicit name to the list of integers is
> > not given.  If the indexed list is local, it is better to use the
> > definition directly; I don't want to look up the definition of
> > integers (perhaps in a different module) to check whether it is [1..]
> > or [0..].
>
> And for the exact same reason you might like to just write "zip [1..]"
> instead of using a separate "attach_index" function.
>
> Cheers,
> Luke
>
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-0A732C.15064816102003@netnews.attbi.com>
In article <··············@vipe.ii.uib.no>, ··········@ii.uib.no wrote:

> Anonymous functions *can* be more clear than any name.

This belief is grounded in a desire to keep the program's language close 
to the programming language, rather than moving the program's language 
toward the problem domain. This resistance is, I suppose, understanable. 
After all, the programmer's expertise is the language of the programming 
language, not the language of the problem domain. It is, at least at 
first, easier for him to talk in the language that he knows than one 
that is new to him. Nevertheless, this is exactly what he must do if he 
is to write clear code. The reason we see 300 line function bodies is 
that many programmers resist expressing the solution in the language of 
the problem domain, preferring instead to write in an idiom that they 
already understand, the programming language.

The higher level abstractions of a complex piece of software will, of 
necessity, be concepts in the problem domain. These concepts, 
representing both entities, and the relationship and interactions among 
different entities, will almost certainly already have well established 
names in the problem domain. For those that do not, the programmer 
should take the time to find apt descriptions of these entities or 
interactions _in_the_language_of_the_problem_domain_. These problem 
domain names are the appropriate units of the language that the software 
should be written in. Named functions and macros are the appropriate 
labels for the programmer's software definitions of the concepts of the 
problem domain, not anonymous functions.

Unless the problem domain is functional programming itself, the language 
that the program is written in should consist of names taken from the 
problem domain, not anonymous functional interactions.

At some low level of abstraction, when building the functionality of the 
named functions and macros that correspond to the concepts of the 
problem domain, the programmer will, of course, need to specify 
implementation. These implementations will, where appropriate, use 
anonymous functions.

However, once we get above this lower level of abstraction, we will be 
dealing with concepts from the problem domain, which _have_names_. These 
names from the problem domain, not anonymous functions, and not the 
keywords/built-ins of the computer language,  should be the language the 
program is written in.

Moreover, even at the lower levels of abstraction, we will be passing 
through other well explored problem domains, such as arithmetic, string 
mainipulation, etc. These domains _also_ have preexisting named 
concepts, which can and should be used by the programmer. Most decent 
languages have built-in functions or keywords or operators for some of 
these things. For others, the programmer can and should take the time to 
define named functions and macros for arithmetic, string manipulation, 
etc. operations that correspond to concepts in each of these problem 
domains.

This stands in direct opposition to those who think that software should 
seek to _avoid_ names whenever possible. I, on the other hand find this 
simple equation is true:

Names = Clarity
(specifically, names taken from the problem domain)

Some posters here have replied that this is just "obvious," and true 
independent of the issue of anonymous functions. But the two issues are 
_of_necessity_ related, because you cannot have both names and anonymity.

It seems as if some here believe that names = tedium, or names = 
prolixity, or names = exra work. But disdaining this work of finding 
appropriate, descriptive, names from the problem domain, is a recipe for 
obfuscated code. Worse, it is a recipe for failed software projects. The 
failure to find good names from the problem domain indicates a failure 
to properly understand the problem domain in its own terms. Failure to 
understand the problem domain in its own terms means that the program's 
design is almost certainly fatally flawed.

Again, this will be decried as "obvious." However, what should be 
obvious is that we cannot have both names, and anonymity.
From: ··········@ii.uib.no
Subject: Re: Express What, not How.
Date: 
Message-ID: <egfzhtx9tu.fsf@vipe.ii.uib.no>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> In article <··············@vipe.ii.uib.no>, ··········@ii.uib.no wrote:

>> Anonymous functions *can* be more clear than any name.

> This belief is grounded in a desire to keep the program's language close 
> to the programming language, rather than moving the program's language 

So, does that mean you disagree?

> This stands in direct opposition to those who think that software should 
> seek to _avoid_ names whenever possible. 

As far as I can tell, nobody holds this position.

> I, on the other hand find this  simple equation is true:

> Names = Clarity
> (specifically, names taken from the problem domain)

Sure, to some extent.  More names isn't always more clarity, though.
And compactness, locality and simplicity also adds to clarity.

> Some posters here have replied that this is just "obvious," and true 
> independent of the issue of anonymous functions. But the two issues are 
> _of_necessity_ related, because you cannot have both names and anonymity.

You can have, as has been pointed out, a *balance*, naming the
important things (be they functions, data types, or values) while
leaving less important things unnamed. 

I and others have come up with simple examples that we feel show that
anonymous functions improve clarity.  Your posts are more dogmatic,
which would be fine, except that I apparently fail to interpret your
position correctly.  

So, do you agree or not that anonymous functions can improve clarity
in some cases?

If not, are you also against anonymous values of other kinds
(intermediate arithmetic results, say; or types)?

Do you agree with the specific cases posted to this thread?  
If not, could you point out why?

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-833BEE.20381716102003@netnews.attbi.com>
In article <··············@vipe.ii.uib.no>, ··········@ii.uib.no wrote:

> So, do you agree or not that anonymous functions can improve clarity
> in some cases?

Of course. However, those cases tend to be low level abstractions 
precisely because were talking about _anonymous_ functions, not 
functional abstractions in general. Their anonymity itself prevents them 
from improving the clarity of high level abstractions.

In other words, the higher the level of abstraction, the more we are 
talking in the language of the problem domain. The language of the 
problem domain has a vocabulary with _names_ for entities and their 
interactions. Anonymous functions, by definition _have_no_names_, so 
they can't possibly be isomorphic with the language of the problem 
domain. If an anonymous function _does_ accomplish something identical 
to a named entity or interaction in the problem domain, then you should 
give your anonymous function _that_name_ from the problem domain. Now, 
of course, it is a named function or macro, not an anonymous function 
anymore.

The language of the problem domain, and anonymous functions, are, 
_of_necessity_, mutually exclusive, because the domain experts use 
_names_, not anonymous functions, when they talk about their domain of 
expertise.
From: Brian McNamara!
Subject: Re: Express What, not How.
Date: 
Message-ID: <bmnl9e$e8g$1@news-int.gatech.edu>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> once said:
>In other words, the higher the level of abstraction, the more we are 
>talking in the language of the problem domain. The language of the 
>problem domain has a vocabulary with _names_ for entities and their 
>interactions. Anonymous functions, by definition _have_no_names_, so 
>they can't possibly be isomorphic with the language of the problem 
>domain. If an anonymous function _does_ accomplish something identical 
>to a named entity or interaction in the problem domain, then you should 
>give your anonymous function _that_name_ from the problem domain. Now, 
>of course, it is a named function or macro, not an anonymous function 
>anymore.

I still disagree.  Below is an example where I still think it's best to
use anonymous functions, despite the fact that both (1) it's at a high
level of abstraction and (2) it maps exactly to the problem domain.

Here's the example.  You've got some command-line application that
processes some binary files.  The details aren't important.  You can
run the program like this:

   % prog foo bar baz
      # processes data files foo, bar, and baz, and then
      # saves binary results in foo.sav, bar.sav, and baz.sav

or like this

   % prog -p foo
      # processes data files (in this case, just "foo")
      # and prints human-readable results to the screen

Hopefully you get the basic idea for the application.


Now, I can imagine the program being structured something like this.
(I'm using Haskell, which is the FPL I know best, but it's not my native
tongue, so apologies if I screw up minor details.)

   processFile :: String -> IO Info
   -- process data file named by string, return Info data structure
   
   printInfo :: Info -> IO ()
   -- print Info in human-readable form to stdout
   
   saveInfo :: Info -> String -> IO ()
   -- save Info (in binary) to file named by String

Now, somewhere in or near the main() function (that is, at the very
highest level of abstraction for this program), I can imagine seeing
code like this:
   
   -- assume these vars:
   fileList  :: [String]  -- names of files to process
   wantPrint :: Bool      -- whether user specified '-p' option
   ...
   let forEachFilename op = mapM op fileList
   in if wantPrint
      then forEachFilename \fn -> do info <- processFile fn
                                     printInfo info
      else forEachFilename \fn -> do info <- processFile fn
                                     saveInfo info (fn++".sav")

Note the two anonymous functions:

   \fn -> do info <- processFile fn
             printInfo info
and
   \fn -> do info <- processFile fn
             saveInfo info (fn++".sav")

Note that they map exactly to ideas from the problem domain (actually,
to the very user interface of this program).  Now, you want me to make
these separate named functions?  What ought I call them?  Perhaps
"processFileAndPrint" and "processFileAndSave"?  Or perhaps we should
use the name as it's known in the user interface, and name them
"doItWithTheDashPeeOption" and "doItWithoutTheDashPeeOption"?

I think that such a strategy would be silly, especially if there is
more than one command-line option, each of which slightly alters the
program's overall behavior.  I think that the anonymous functions do a
good job of succinctly specifying the behavior for each option.


I have enjoyed this discussion because it's forced me to think about
what rules I apply when making coding choices (such as whether-or-not to
use an anonymous function).  I've found it's surprisingly difficult to
come up with succinct, precise, hard-and-fast rules which capture how I
choose to write code.  You have an advantage here: even if we disagree
about what the "best" style is, you can at least describe the rules for
your style, whereas I cannot easily do the same for mine.

-- 
 Brian M. McNamara   ······@acm.org  :  I am a parsing fool!
   ** Reduce - Reuse - Recycle **    :  (Where's my medication? ;) )
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-A274C3.01435717102003@netnews.attbi.com>
In article <············@news-int.gatech.edu>,
 ·······@prism.gatech.edu (Brian McNamara!) wrote:


[snip]
>   \fn -> do info <- processFile fn
>              printInfo info
> and
>    \fn -> do info <- processFile fn
>              saveInfo info (fn++".sav")

[snip]

> What ought I call them?  Perhaps
> "processFileAndPrint" and "processFileAndSave"?

Yup. Next question. Only someone who hasn't taken a break from coding 
for a long time could think that:

\fn -> do info <- processFile fn
               printInfo info

is clearer or easier to understand than:

ProcessFileAndPrint


Even more so in lisp:

process-file-and-print
From: Alan Gauld
Subject: Re: Express What, not How.
Date: 
Message-ID: <3f8f0bca.425450585@news.blueyonder.co.uk>
On Thu, 16 Oct 2003 19:06:00 GMT, Raffael Cavallaro
<················@junk.mail.me.not.mac.com> wrote:
> is to write clear code. The reason we see 300 line function bodies is 
> that many programmers resist expressing the solution in the language of 
> the problem domain, preferring instead to write in an idiom that they 
> already understand, the programming language.

Do you have any objective evidence to suggest that this is true?
What proprtion exactly is due to this? The reason I ask is that
most of the long functions I have seen have been products of the
algorithm being implemented. If an algorithm takes 300 lines to
express it should be expressed as 300 lines. I have *never* seen
a long function that is the result of a programmer avoiding using
user vocabulary!

Equally I see no evidence whatsoever to suggest that users
express requirements in short chunks - usually the opposite, we
get presented with long complex prose describing a convoluted
business process and the programmer has to split that into its
natural chunks during analysis!

If anyone has done any research to connect long functions with 
ignoring of user language I'm unaware of it and would be most
interested in seeing it.

> The higher level abstractions of a complex piece of software will, of 
> necessity, be concepts in the problem domain. 

Not necessarily(*), but I would agree that usually they are, but
at the lower levels the solution space may bear no resemblance to
the problem domain at all!

(*) For example where the solution architecture is based on a
mathematical technique which would be impractical in a manual
business process but is entirely practical using computing power.
As a somewhat dated example - the processes used in computer
crytography for example being entirely different to those used in
manual cryptrography. There will be some concepts in common 
but many will be entirely novel.

> interactions _in_the_language_of_the_problem_domain_. These problem 
> domain names are the appropriate units of the language that the software 
> should be written in. Named functions and macros are the appropriate 
> labels for the programmer's software definitions of the concepts of the 
> problem domain, not anonymous functions.

In the general case I agree completely but a blanket statement
that it is always true is absurd. There are many cases when a
programmer is dealing with issues that simply don't arise in the
human scenario. Anonymous functions are often used in 
scenarios where a name is meaningless. Even in business processes
it is not unusual to find processes with names like JDI(Just Do
It) or DWN (Do Whatever's Necessary) to deal with extraordinary
scenarios. (Although ironically these are rarely the ones which
require anonymous funtions in code!)

> At some low level of abstraction, when building the functionality of the 
> ...
> implementation. These implementations will, where appropriate, use 
> anonymous functions.

Ah, we do agree at this level. So your point only applies to
"high level" functions. The issue then becomes one of deciding at
what point the solution and problem domains separate.

> However, once we get above this lower level of abstraction, we will be 
> dealing with concepts from the problem domain, which _have_names_. 

Usually, but not always. Or often highly generic names which are
best implemented using higher order programming techniques
involving anonymous names.

> This stands in direct opposition to those who think that software should 
> seek to _avoid_ names whenever possible. I, on the other hand find this 
> simple equation is true:
> 
> Names = Clarity

Again, in general I agree. But if the name is f and it is only
used for as long as it takes to convey a single use function into
the argument list of another function then I find the naming to
be of little or no value.

> Some posters here have replied that this is just "obvious," and true 
> independent of the issue of anonymous functions. But the two issues are 
> _of_necessity_ related, because you cannot have both names and anonymity.

I'm not sure I agree there. It happens in the real world all the
time. (Consider Internet Chat Rooms! Many users there desire
anonymity while using a name which may not be their identity.
Indeed they achieve anonynimty through their false identity!)

> prolixity, or names = exra work. But disdaining this work of finding 
> appropriate, descriptive, names from the problem domain, is a recipe for 
> obfuscated code. 

I agree that good names are a good thing and time should be spent
considering appropriate ones but...

> Worse, it is a recipe for failed software projects. 

Bad naming is rarely if ever the reason for failed projects. It
may contribute by slowing down testing or integration and thus
causing estimate failure (the most comon reason for failed
projects) but naming alone is not enough to cause a failure IMHO.

> failure to find good names from the problem domain indicates a failure 
> to properly understand the problem domain in its own terms. Failure to 
> understand the problem domain in its own terms means that the program's 
> design is almost certainly fatally flawed.

Insofar as the problem domain is reflected in the solution space
I agree. Certainly a programmer who does not understand the
vocabulary of his end user is unlikely to create good solutions.

Naming is important where a name aids understanding. If a name is
just there as a marker it serves no purpose. I agree that this
rarely happens at a high level in the design but I think it
happens at a higher level that you suggest. Not often, but often
enough to prevent blanket assertions being made.

Alan G.

Author of the Learn to Program website
http://www.freenetpages.co.uk/hp/alan.gauld
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-C8FCC1.20554216102003@netnews.attbi.com>
In article <··················@news.blueyonder.co.uk>,
 ··········@btinternet.com (Alan Gauld) wrote:

> In the general case I agree completely but a blanket statement
> that it is always true is absurd. There are many cases when a
> programmer is dealing with issues that simply don't arise in the
> human scenario. Anonymous functions are often used in 
> scenarios where a name is meaningless.

And in those cases, anonymous functions are perfectly appropriate.

However, when dealing with the existing abstractions of the problem 
domain, named functions and macros are superior. I contend that a great 
deal more code should be dealing with the existing abstractions of the 
problem domain than is currently the norm. (Part of this is premature 
optimization - Programmers are reluctant to break code into smaller 
named units for fear that the additional code and function calls will be 
more computationally costly.) Remember that mathematics, string 
manipulation, network protocols, etc., are all well understood problem 
domains with _preexisting_named_abstractions_. These named abstractions 
are what we should be thinking and programming in, not the primitives of 
whatever language we happen to be using, nor even in anonymous 
functional abstractions.

In addition, even if the programmer finds some novel way, only possible 
in a machine implementation, to express a solution, our ability to think 
clearly about that process is greatly aided by giving it a _name_. E.g., 
it is much easier to think about different sorting methods (bubble sort, 
quicksort, etc.) by refering to them by name, than it is to have to look 
at an implementation of them every time we wish to refer to them.

Naming is a fundamental step in building abstraction. Anonymous 
functions, keep us trapped at the level of abstraction at which they are 
defined. If we wish to reuse them, we must reiterate them, because we 
can't simply refer to them by name. Why not simply name them, and use 
the names? This is, after all, how people have been communicating 
abstractions since the dawn of spoken language.
From: Alex Shinn
Subject: Re: Express What, not How.
Date: 
Message-ID: <87ekxciphd.wl@strelka.synthcode.com>
At Fri, 17 Oct 2003 00:54:53 GMT, Raffael Cavallaro wrote:

> Naming is a fundamental step in building abstraction. [...] This is,
> after all, how people have been communicating abstractions since the
> dawn of spoken language.

Language may have begun with proper names, but these are by definition
*not* abstract.  Abstraction comes from being able to combine different
linguistic elements to build more complex ideas without needing to give
them names.  We use adjectives and adverbs to modify existing words
without needing to come up with new words, and build further with noun
clauses and prepositions.  So you can both "run quickly" and "swim
quickly," which is analogous to a higher order function (quickly)
working on two existing functions (run and swim).  You could give
specific names to either of these but indiscriminately naming puts a
burden on the memory.  In this case, the further modified function "run
quickly over a short distance" is a common enough concept that it does
get its own name "sprint," but there is no equivalent for when those two
modifiers are applied to "swim."  It may be fun to suggest that "swint"
be used, but I don't think anyone would argue that would make the
language more clear, quite the contrary it would make the spoken
language unwieldy.

Naming is of course important, but we'd have a very difficult time
communicating if we had to name everything we wanted to talk about.  You
need to choose a good balance of what deserves a name.

And don't name the farm animals, it only makes it harder when you eat
them :)

-- 
Alex
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-20C5F3.01461917102003@netnews.attbi.com>
In article <·············@strelka.synthcode.com>,
 Alex Shinn <····@synthcode.com> wrote:

> We use adjectives and adverbs to modify existing words
> without needing to come up with new words, and build further with noun
> clauses and prepositions.  So you can both "run quickly" and "swim
> quickly," which is analogous to a higher order function (quickly)
> working on two existing functions (run and swim).

I think you miss the point - "quickly" is itself a _name_ for an 
abstract modifier. If this is the analog of a higher order function, it 
is a _named_ higher order function, not an anonymous one.

We don't say "he ran (large distance covered/unit time)" or "he swam 
(large distance covered/unit time)." Instead, we give this abstraction, 
(large distance covered/unit time) a name, "quickly."

I am most definitely _not_ arguing against the use of higher order 
functions when appropriate. When dealing with concepts of the problem 
domain though, those higher order functions should probably have 
_names_. And when it is not possible to cast these HOFs in a _syntax_ 
that fits the usage of the problem domain, these named HOFs will 
naturally find their way into macros ;^)

One could conceive of a loose ranking of modes of expression and levels 
of abstraction. From lowest (least abstract) to highest:

language primitives
anonymous functions
named functions  and higher order anonymous functions
     (a tie here because naming is inherently more abstract
     than anonymity, and HOFs are of course more abstract
     than ordinary functions)
named higher order functions
macros
From: Alex Shinn
Subject: Re: Express What, not How.
Date: 
Message-ID: <87ad80iets.wl@strelka.synthcode.com>
At Fri, 17 Oct 2003 05:45:29 GMT, Raffael Cavallaro wrote:
> 
> In article <·············@strelka.synthcode.com>,
>  Alex Shinn <····@synthcode.com> wrote:
> 
> > We use adjectives and adverbs to modify existing words
> > without needing to come up with new words, and build further with noun
> > clauses and prepositions.  So you can both "run quickly" and "swim
> > quickly," which is analogous to a higher order function (quickly)
> > working on two existing functions (run and swim).
> 
> I think you miss the point - "quickly" is itself a _name_ for an 
> abstract modifier. If this is the analog of a higher order function, it 
> is a _named_ higher order function, not an anonymous one.

I was making the analogy that verbs are functions (any functions).
"run" is thus a function of one argument (the person running).
"quickly" is as we both say an HOF which acts on run.  My point is the
result of applying the HOF gives us "run quickly" which is itself a
function, and an anonymous one at that because "run quickly" is not a
name but a visible application of an HOF.  It's exactly equivalent to

  (memoize run)

whereas the named version would require you to define externally

  (define run-memoized (memoize run))

a technique which quickly begins to clutter your language with names
like "swint."

-- 
Alex
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-8AE926.08290617102003@netnews.attbi.com>
In article <·············@strelka.synthcode.com>,
 Alex Shinn <····@synthcode.com> wrote:
> My point is the
> result of applying the HOF gives us "run quickly" which is itself a
> function, and an anonymous one at that because "run quickly" is not a
> name but a visible application of an HOF. 


I have no problem with a HOF, as long as the HOF corresponds to 
something in the language of the problem domain. But it doesn't here. I 
think it is telling that your example is taken from the problem domain 
of computer science (memoization of functions), not that of the domain.


>  It's exactly equivalent to
> 
>   (memoize run)

If we were writing a program that simulated people running and swimming, 
it's very doubtful that "quickly" would mean "memoize." "Quickly" would 
mean, "with-increased-framerate," or something similar. (Note that 
with-increased-framerate would almost certainly be a macro).

In domains outside of functional programming and mathematics, the 
concepts of the problem domain don't usually map to applicable HOFs. 
People fall in love with HOFs because they are great tools for lower 
level implementation. But I don't think they usually map well to the 
concepts of problem domains other than mathematics and computer science. 
Named functions and macros let us capture the power of HOFs inside a 
vocabulary _and_ syntax that matches the problem domain.
From: Alex Shinn
Subject: Re: Express What, not How.
Date: 
Message-ID: <877k30ishg.wl@strelka.synthcode.com>
At Fri, 17 Oct 2003 12:28:14 GMT, Raffael Cavallaro wrote:
> 
> I have no problem with a HOF, as long as the HOF corresponds to 
> something in the language of the problem domain. But it doesn't here. I 
> think it is telling that your example is taken from the problem domain 
> of computer science (memoization of functions), not that of the domain.

Actually, my problem domain more often than not *is* computer science,
but you could also stick strictly to human language or whatever suits
your fancy.

> If we were writing a program that simulated people running and swimming, 
> it's very doubtful that "quickly" would mean "memoize." "Quickly" would 
> mean, "with-increased-framerate," or something similar.

I don't see how a framerate is less computer-specific than memoization.
If you want to stay close to the original human language then it would
simply mean the act of running faster than usual.

> (Note that with-increased-framerate would almost certainly be a
> macro).

Not necessarily.  In Scheme with- forms are almost never macros, and are
almost always passed anonymous functions as arguments.

> In domains outside of functional programming and mathematics, the 
> concepts of the problem domain don't usually map to applicable HOFs.
> People fall in love with HOFs because they are great tools for lower
> level implementation. But I don't think they usually map well to the
> concepts of problem domains other than mathematics and computer science.
> Named functions and macros let us capture the power of HOFs inside a
> vocabulary _and_ syntax that matches the problem domain.

You're switching to macros and HOFs when we were talking about anonymous
functions.  If you are seriously arguing against the use of HOFs in
general then I think you have a lot to learn.  Learn a Lisp (Scheme is
nice and clean) or one of the more functional languages like Haskell.
If you brought macros into the discussion with the idea that any direct
application of an anonymous function should be hidden with a macro then
I question whether your goal is really to achieve more legible code or
is just some irrational bias against anonymous functions?

If you want to program in logic as close to the problem domain as
possible, try a logic programming language like Prolog or CLIPS.  You
may be disappointed because even in these languages you have to refer to
low-level details at times.  Also you will find that an extremely useful
feature is not only anonymous functions but anonymous facts and rules.
If you want to wait until you can program explicitly in the
highest-level human language then I think you may be even more
disappointed.  Firstly because as already mentioned human language makes
heavy use of anonymous functions and unnamed concepts in general.  When
possible we combine existing ideas and use their compound forms directly
in speech without giving them a new name.  Secondly because human
language is not well suited to exact specifications, which is why when
we try to nail down rules as specifically as possible we end up with
language like legalese.

If you want to tell computers what to do in natural human language,
trusting them to learn what you mean when you're ambiguous (through a
process of correcting them when they guess wrong) then that is an
admirable dream.  But it's not programming.

-- 
Alex
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-4BD510.23274231102003@netnews.attbi.com>
In article <·············@strelka.synthcode.com>,
 Alex Shinn <····@synthcode.com> wrote:

> If you are seriously arguing against the use of HOFs in
> general then I think you have a lot to learn.

No, I'm not arguing against HOFs in general. I'm arguing against the 
repeated use of the _same_ anonymous function throughout code. These 
should clearly be named funtions instead. 

But I've apparently touched a nerve, because so many FPers seem to 
equate eschewing repetition of the same anonymous functional idoim in 
numerous places throughout ones code, with an attack on HOF use itself.
From: Ken Shan
Subject: Re: Express What, not How.
Date: 
Message-ID: <t76661-316.ln1@proper.ptq.dyndns.org>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote in article <······································@netnews.attbi.com> in comp.lang.functional:
> I think you miss the point - "quickly" is itself a _name_ for an 
> abstract modifier. If this is the analog of a higher order function, it 
> is a _named_ higher order function, not an anonymous one.

In what sense are "lambda" and "apply" not names?

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-8AEE3E.21031117102003@netnews.attbi.com>
In article <··············@proper.ptq.dyndns.org>,
 Ken Shan <···@digitas.harvard.edu> wrote:

> In what sense are "lambda" and "apply" not names?

Not names from the problem domain, unless the problem domain is 
functional programming.
From: Ken Shan
Subject: Re: Express What, not How.
Date: 
Message-ID: <bmq7mh$q75$1@news.fas.harvard.edu>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote in article <······································@netnews.attbi.com> in comp.lang.functional:
> In article <··············@proper.ptq.dyndns.org>,
>  Ken Shan <···@digitas.harvard.edu> wrote:
> > In what sense are "lambda" and "apply" not names?
> Not names from the problem domain, unless the problem domain is 
> functional programming.

But in the style of programming that you advocate, as I understand
it, one does not need to give a name to function application from the
problem domain before using it.

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <aeb7ff58.0310182111.6df0b5ab@posting.google.com>
Ken Shan <···@digitas.harvard.edu> wrote in message news:<············@news.fas.harvard.edu>...

> But in the style of programming that you advocate, as I understand
> it, one does not need to give a name to function application from the
> problem domain before using it.

No, one doesn't, as long as that function application is the one place
where the implementation of that bit of functionality needs to be
expressed.

However, if one is using that bit of functionality elsewhere, then it
only constitutes information overload to re-express the implementation
of that functionality yet again in that location. In such a case, that
function application should be named in the one place it is necessary
to express its implementation, and the named version used elsewhere.

Again, it comes down to uniqueness and necessity of exposition. If it
is only going to be expressed once, and there is no loss of clarity,
then use an anonymous function. In this sense anonymous functions are
no different than using the built-ins or primitives of the language.
If this is  the place where this bit of functionality needs to be
defined, then, by all means, use anonymous functions to express that
implementation if it is easier.

But if that is not the one and only place where that bit of
functionality is used, then name it. If that is not the one and only
place where that functionality needs to be defined, then don't repeat
the implementation in a half dozen places. Implement it once, name it,
and use the name elsewhere.
From: Ken Shan
Subject: Re: Express What, not How.
Date: 
Message-ID: <bmulki$8rg$1@news.fas.harvard.edu>
Raffael Cavallaro <·······@mediaone.net> wrote in article <····························@posting.google.com> in comp.lang.functional:
> Ken Shan <···@digitas.harvard.edu> wrote in message news:<············@news.fas.harvard.edu>...
> > But in the style of programming that you advocate, as I understand
> > it, one does not need to give a name to function application from the
> > problem domain before using it.
> No, one doesn't, as long as that function application is the one place
> where the implementation of that bit of functionality needs to be
> expressed.

The implementation of function application is definitely something
that doesn't need to be expressed in the vast majority of programs.
Moreover, function application is used in many places, far from just
one place.  So according to you, I need to find a name for function
application, and not just any name -- it needs to be a name from the
problem domain.  But what is a name for function application from the
cash register problem domain?

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <aeb7ff58.0310191822.726f6b16@posting.google.com>
Ken Shan <···@digitas.harvard.edu> wrote in message news:<············@news.fas.harvard.edu>...

> So according to you, I need to find a name for function
> application, and not just any name -- it needs to be a name from the
> problem domain.

From the problem domain _at_that_level_. If, at that level, we're
dealing with array bounds checking (assuming, for the moment that
we're using a language that doesn't have that built in), then function
names like check-index, report-invalid-index-error, etc. are names
from the problem domain at that level.

The problem I see with the use of the typical anonymous functional
style is twofold:

1. The same functional idiom is repeated, but not abstracted (i.e.,
not named). This leads to unnecessary "programmer inlining," that is,
writing out the implementation everywhere it is used, rather than
naming it once, and using the name everywhere else.

2. The anonymous functional idioms map well to domains such as
arithmetic, mathematics, and functional programming itself. These same
idioms don't map so well to other domains. The more abstract the
program becomes (that is, the closer it moves to the problem domain,
and the farther it moves from the low level arithmetic and functional
abstractions) the less the anonymous functional idioms will correspond
to the existing concepts and vocabulary of the problem domain.
From: Ken Shan
Subject: Re: Express What, not How.
Date: 
Message-ID: <521c61-o2i.ln1@proper.ptq.dyndns.org>
Raffael Cavallaro <·······@mediaone.net> wrote in article <····························@posting.google.com> in comp.lang.functional:
> Ken Shan <···@digitas.harvard.edu> wrote in message news:<············@news.fas.harvard.edu>...
> > So according to you, I need to find a name for function
> > application, and not just any name -- it needs to be a name from the
> > problem domain.
> From the problem domain _at_that_level_. If, at that level, we're
> dealing with array bounds checking (assuming, for the moment that
> we're using a language that doesn't have that built in), then function
> names like check-index, report-invalid-index-error, etc. are names
> from the problem domain at that level.

I'm not sure if I understand your notion of problem-domain levels.  For
instance, in a preceding example

    amount_due = sum(item_prices) * (1 + tax_rate)

is the problem domain possibly "functions and their arguments", or is
the problem domain possibly "customer billing"?  If the former, would
you rewrite the above expression with names in the problem domain, as in

    amount_due = apply(*, apply(sum, item_prices), apply(+, 1, tax_rate)

or

    amount_due = apply(apply, *,
	apply(apply, sum, item_prices),
	apply(apply, +, 1, tax_rate))

or

    amount_due = apply(apply, apply, *,
	apply(apply, apply, sum, item_prices),
	apply(apply, apply, +, 1, tax_rate))

(when do I stop?)?  If the latter, how would you recommend that I
(re)write the code... certainly, since the use of function application
is so pervasive in the above code, a human-readable name in the problem
domain is in order?

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-07C37F.14454123102003@netnews.attbi.com>
In article <··············@proper.ptq.dyndns.org>,
 Ken Shan <···@digitas.harvard.edu> wrote:

> I'm not sure if I understand your notion of problem-domain levels.  For
> instance, in a preceding example
> 
>     amount_due = sum(item_prices) * (1 + tax_rate)
> 
> is the problem domain possibly "functions and their arguments", or is
> the problem domain possibly "customer billing"?

How about simple arithmetic, which is built into most computer languages.

However, if you do this often enough in your code (i.e., compute a 
total, then add the tax), you migh want to have a named function, say 
"total-with-tax," instead of just reimplimenting it every time you use 
it. It's simply a matter of how much of what you're doing is specific to 
the larger problem, how much is just arithmetic, using built-ins, and, 
probably most importantly, how often you'll be repeting yourself in 
exactly the same way.



[snip]
> (when do I stop?)?

When you reach the built-ins of the language, of course. No need to 
define a method called "add" in a language that has + as a built in 
function (unless you're going to overload addition to do something that 
the built-in function doesn't do yet.)

But the very telling larger picture issue is that there is such a 
reluctance to name bits of code that are going to be used more than once.
From: David Rush
Subject: Re: Express What, not How.
Date: 
Message-ID: <oprxcymd2n3seq94@news.nscp.aoltw.net>
I've just about decided to killfile this whole thread, but I can't
let this one go by. Two unsubstantiated assertions do not make a bad 
programming practice, no matter how hard you try.

On 19 Oct 2003 19:22:04 -0700, Raffael Cavallaro <·······@mediaone.net> 
wrote:

> The problem I see with the use of the typical anonymous functional
> style is twofold:

How much programming have *you* done with anonymous functions? Or is this 
complaint based on your esthetic reactions to a series of contrived 
examples in usenet posts?

> 1. The same functional idiom is repeated, but not abstracted (i.e.,
> not named). This leads to unnecessary "programmer inlining," that is,
> writing out the implementation everywhere it is used, rather than
> naming it once, and using the name everywhere else.

Not by this heavy user of anonymous functions. In fact one of the main
uses I have for anonymous functions is to *avoid* code duplication by
parameterizing over entire categories of functions.

Cut & Paste programming is bad practice in any language. IME, functional
programmers do it *less* often than those from other communities.

> 2. The anonymous functional idioms map well to domains such as
> arithmetic, mathematics, and functional programming itself. These same
> idioms don't map so well to other domains. The more abstract the
> program becomes (that is, the closer it moves to the problem domain,
> and the farther it moves from the low level arithmetic and functional
> abstractions) the less the anonymous functional idioms will correspond
> to the existing concepts and vocabulary of the problem domain.

Again, I disagree heartily. I use HO&AFs to enable greater levels of
abstraction since they allow me to abstract *outer* components of
functions while I pass in the site-specific portions. Control-structure- 
like
functions are only a fairly trivial example of this kind of thing, but
I have in a mail-processing application 2 functions IF-FROM-LINE (used in 
mbox file processing) and RFC822-COLLAPSE-HEADER (used in RFC822 header
processing) which both implement algorithms which are parameterized
by functions. This is vaguely similiar in spirit to the visitor pattern
from OO land, but much more flexible. Both of these functions are used
in multiple contexts where the anonymous functions contextualize the
operations performed under specific conditions in their implemented
algorithms. These operations have (so far) been strictly one-off animals.
In the event that I ever feel a need to re-use one of them I will simply
lift the anonymous function from its original source location, give it
a top-level name et voila - instant reuse.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-171FDB.19201220102003@netnews.attbi.com>
In article <················@news.nscp.aoltw.net>,
 David Rush <·····@aol.net> wrote:

> I have in a mail-processing application 2 functions IF-FROM-LINE (used in 
> mbox file processing) and RFC822-COLLAPSE-HEADER (used in RFC822 header
> processing) which both implement algorithms which are parameterized
> by functions. This is vaguely similiar in spirit to the visitor pattern
> from OO land, but much more flexible. Both of these functions are used
> in multiple contexts where the anonymous functions contextualize the
> operations performed under specific conditions in their implemented
> algorithms. These operations have (so far) been strictly one-off animals.

I think you are in violent agreement with me.

I wrote:
> > The problem I see with the use of
> >  the typical anonymous functional
                       ^^^^^^^^^
> > style is twofold:


1. If-from-line is a _named_ function, not an anonymous function. My 
only objection was to _anonymous_ functions replacing named 
abstractions, not to functional programming itself.

> In the event that I ever feel a need to re-use one of them I will simply
> lift the anonymous function from its original source location, give it
> a top-level name et voila - instant reuse.

2. Which is precisely what I suggested in all of my previous posts. 
I.e., if the anonymous function is used more than once, name it, and use 
the name.
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-14660F.01322017102003@netnews.attbi.com>
In article <·············@strelka.synthcode.com>,
 Alex Shinn <····@synthcode.com> wrote:

> We use adjectives and adverbs to modify existing words
> without needing to come up with new words, and build further with noun
> clauses and prepositions.  So you can both "run quickly" and "swim
> quickly," which is analogous to a higher order function (quickly)
> working on two existing functions (run and swim).

I think you miss the point - "quickly" is itself a _name_ for an 
abstract modifier. If this is the analog of a higher order function, it 
is a _named_ higher order function, not an anonymous one.

We don't say "he ran (large distance covered/unit time)" or "he swam 
(large distance covered/unit time)." Instead, we give this abstraction, 
(large distance covered/unit time) a name, "quickly."

I am most definitely _not_ arguing against the use of higher order 
functions when appropriate. When dealing with concepts of the problem 
domain though, those higher order functions should probably have 
_names_. And when it is not possible to cast these HOFs in a _syntax_ 
that fits the usage of the problem domain, these named HOFs will 
naturally find their way into macros ;^)

One could conceive of a loose ranking of modes of expression and levels 
of abstraction. From lowest (least abstract) to highest:

language primitives
anonymous functions
named functions  and higher order anonymous functions
     (a tie here because naming is inherently more abstract
     than anonymity, and HOFs are of course more abstract
     than ordinary functions)
named higher order functions
macros
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-7F10F1.01453517102003@netnews.attbi.com>
In article <·············@strelka.synthcode.com>,
 Alex Shinn <····@synthcode.com> wrote:

> We use adjectives and adverbs to modify existing words
> without needing to come up with new words, and build further with noun
> clauses and prepositions.  So you can both "run quickly" and "swim
> quickly," which is analogous to a higher order function (quickly)
> working on two existing functions (run and swim).

I think you miss the point - "quickly" is itself a _name_ for an 
abstract modifier. If this is the analog of a higher order function, it 
is a _named_ higher order function, not an anonymous one.

We don't say "he ran (large distance covered/unit time)" or "he swam 
(large distance covered/unit time)." Instead, we give this abstraction, 
(large distance covered/unit time) a name, "quickly."

I am most definitely _not_ arguing against the use of higher order 
functions when appropriate. When dealing with concepts of the problem 
domain though, those higher order functions should probably have 
_names_. And when it is not possible to cast these HOFs in a _syntax_ 
that fits the usage of the problem domain, these named HOFs will 
naturally find their way into macros ;^)

One could conceive of a loose ranking of modes of expression and levels 
of abstraction. From lowest (least abstract) to highest:

language primitives
anonymous functions
named functions  and higher order anonymous functions
     (a tie here because naming is inherently more abstract
     than anonymity, and HOFs are of course more abstract
     than ordinary functions)
named higher order functions
macros
From: Christian Szegedy
Subject: Re: Express What, not How.
Date: 
Message-ID: <bmjnle$olc$1@f1node01.rhrz.uni-bonn.de>
Raffael Cavallaro wrote:

>
> 2. If it is necessary to show, at that _particular_ source location, 
> _how_ a piece of functionality is provided. If the reader doesn't need 
> to know _how_ things are implemented in that _particular_ source 
> location, we should use a descriptively named function or macro instead.
> 
> I find that many programmers overestimate the "uniqueness" of their 
> anonymous functions. They tend to repeat the same anonymous function 
> idiom in many places. Rather than come up with a descriptive name for 
> _what_ they are doing, they clutter a higher level abstraction with low 
> level details about _how_ they are doing it. These should be recast as 
> descriptively named functions or macros. 
>

In functional languages, a lot of higher order functions are used for
iterating over some container datastructure. E.g. map,iter,foldl,zip,...

A lambda expression parameter of such functions plays the
same role as a body of a "while" or "for" loop in C.
Do you think that your criterions should be applied to blocks
of codes in C also?
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-12D627.15120515102003@netnews.attbi.com>
In article <············@f1node01.rhrz.uni-bonn.de>,
 Christian Szegedy <·······@nospam.or.uni-bonn.de> wrote:

> In functional languages, a lot of higher order functions are used for
> iterating over some container datastructure. E.g. map,iter,foldl,zip,...


As long as the same idiom is not used over and over again, in the same 
way, this is fine. Once you find that you are repeating the same idiom, 
I think it's time to name that idiom descriptively, and make it a named 
function or macro.

> 
> A lambda expression parameter of such functions plays the
> same role as a body of a "while" or "for" loop in C.
> Do you think that your criterions should be applied to blocks
> of codes in C also?

The problem with C is that it lacks a true macro system (as opposed to a 
simple token substitution system). This means that there will be cases 
where there is a frequently used idiom that could be abstracted in a 
lisp macro, but not in a C macro.

But, insofar as it is possible to abstract out repetition and unecessary 
implementation detail, it should be done in any language that supports 
named functions. Better still if the language supports macros for those 
cases that would require them.
From: Hartmann Schaffer
Subject: Re: Express What, not How.
Date: 
Message-ID: <3f8e1312@news.sentex.net>
In article <······································@netnews.attbi.com>,
	Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:
> ...
> To use the example that started this sub-thread, when I'm reading that a 
> list or a vector has an offset added to each element, I don't need to 
> know that the add-offset functionality is implemented by means of map. 

could this be the source of of the disagreement?  it seems to me that
most people see his somewhat differently:  map is an abstraction that
specifies that you want to apply a certain operation to each element
of a collection, with adding the offset being the desired operation.
frankly, i have some problems making sense of what you are trying to
say here

> ...

hs

-- 

ceterum censeo SCO esse delendam
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <raffaelcavallaro-45D8C8.08044117102003@netnews.attbi.com>
In article <········@news.sentex.net>,
 ··@heaven.nirvananet (Hartmann Schaffer) wrote:

>  map is an abstraction that
> specifies that you want to apply a certain operation to each element
> of a collection, with adding the offset being the desired operation.

Sorry to reply so late - I didn't see this post.

In the context in which the offsets are added, it isn't necessary to 
know that the offsets are added using map, as opposed, for example, to 
an interative construct, such as loop. Since we don't need to know _how_ 
the adding of offsets is done at every location in the source where we 
might want to add an offset to the elements of a list or vector, we 
should _name_ this bit of functionality. This is an even bigger win 
should we ever decide to switch from map to loop, or do, or dolist, etc. 
Then we write a single change, not one for every time we use this bit of 
functionality.
From: Raffael Cavallaro
Subject: Re: Express What, not How.
Date: 
Message-ID: <aeb7ff58.0310182113.1df99f8e@posting.google.com>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote in message news:<······································@netnews.attbi.com>...


> In the context in which the offsets are added, it isn't necessary to 
> know that the offsets are added using map, as opposed, for example, to 
> an interative construct, such as loop.

Sorry for the typo - that should be "iterative" of course.
From: Brian McNamara!
Subject: Re: Express What, not How.
Date: 
Message-ID: <bmicpp$ifk$1@news-int2.gatech.edu>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> once said:
> Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:
>> Sometimes a function is so simple that its body is more clear than any
>> name. A name is an extra level of indirection. You must follow it to be
>> 100% sure what the function means, or to understand what does it really
>> mean that it does what it's named after.
>
>Your argument is based on the assumption that whenever people express 
>_what_ a function does, they do so badly, with an inappropriate name.
...
>Anonymous functions add no clarity except to our understaning of 
>_implementation_, i.e., _how_ not _what_. Higher level abstractions 
>should express _what_. Implementation details should remain separate, 
>both for clarity of exposition, and for maintanence and change of 
>implementation.

I am in total agreement with Marcin.  What you (Raffael) say here
sounds simply like dogma, rather than practical advice for constructing
software.

As a short practical example of what I'm saying, consider code like

   -- I am translating this from another language; apologies if I have
   -- screwed up any of the Haskell details
   nat :: Parser Int
   nat = do {c <- digit; return charToInt c} 
         `chainl1` (return \x y -> 10*x+y)

The code here parses natural numbers; it does do by parsing individual
digit characters, translating the digit characters into the
corresponding integers, and then combining the digit-integers into the
overall number.

If I understand you correctly, you would insist I write something like

   nat :: Parser Int
   nat = do {c <- digit; return charToInt c}
         `chainl1` combineDigits
            where combineDigits = return \x y -> 10*x+y

In my opinion, the code here is worse than the original.
"combineDigits" (or whatever we might choose to name it) is a one-time
function.  It is not going to be reused (it's local to "nat"; moving it
to a more-top-level scope would just cause more problems finding a good
name for it).

Introducing a name for this function does nothing more than clutter the
code.  The name provides no extra understanding.  Of course the
function is "combining digits"!  If the programmer is using chainl1, he
already knows that

   chainl1 :: Parser a -> Parser (a->a->a) -> Parser a
   -- parses a series of items separated by left-associative operators
   -- which are used to combine those items

and he can infer "combining digits" just by seeing the call to chainl1
and inspecting its left argument.


>Anonymous functions are a form of unnecessary information overload. If I 
>don't need to see how something works right here, in this particular 
>context, then don't put its implementation here. Just refer to it by 
>name.

There are more functional abstractions than there are reasonable names.

Forcing programmers to name every abstraction they'll ever encounter is
tantamount to forcing them to memorizing a huge vocabulary of names for
these abstractions.  Perhaps you can remember the precise meanings of 
ten-thousand function names off the top of your head.  I, on the other
hand, can probably recall only a hundred or so.  Thus, I must write,
e.g.

   zipWith (\x y -> (x+y,x-y)) list1 list2

rather than

   zipWith makePairOfSumAndDifference list1 list2

By only naming the most reusable abstractions (and, ideally, selecting
a set which are mostly orthogonal to one another), we provide a "core
vocabulary" which captures the essential basis of the domain.  Lambda
then takes us the rest of the way.  In my opinion, a core vocabulary of
named functions plus lambda is better than a separate name for every
abstraction.  In natural language, such a scheme would be considered
double-plus-un-good, but in programming, I think it lends itself to the
simplest and most precise specifications.


I agree with your one of your overall theses, which is that we should
focus on the "what" rather than the "how".  Where our opinions diverge,
however, is that I think sometimes the best way to communicate an
abstraction is to show the "how" inline, rather than creating a new
name in an attempt to capture the "what".

-- 
 Brian M. McNamara   ······@acm.org  :  I am a parsing fool!
   ** Reduce - Reuse - Recycle **    :  (Where's my medication? ;) )
From: Vijay L
Subject: Re: Express What, not How.
Date: 
Message-ID: <1eaf81aa.0310150100.4b7fba6a@posting.google.com>
·······@prism.gatech.edu (Brian McNamara!) wrote in message news:<············@news-int2.gatech.edu>...
> 
> I am in total agreement with Marcin.  What you (Raffael) say here
> sounds simply like dogma, rather than practical advice for constructing
> software.
> 
> As a short practical example of what I'm saying, consider code like
 
[snip]

> If I understand you correctly, 

It appears you don't.

[snip] 

> 
> In my opinion, the code here is worse than the original.

I agree.

[big snip]

You're taking things to a huge extreme to prove your point.  Obviously
Raffael, being a programmer himself isn't suggesting that each and
every calculation/operation be put in a named function.  The best
benchmark, is, I guess, the programmer himself.  When programming, if
you find some portion of code that /you/ feel won't be understand when
you're rereading it or, you took a chunk out of a function to debug it
and at that point had to give it a name as another function etc etc;
/then/ keep that portion aside as a named function.  It reduces the
burden on the person reading the original function that has been
shortened and, _gives him the choice_ to read this other function that
has been abstracted in that code.
 
Cheers,
Vijay

All future commitments are optimistic.
From: Albert Lai
Subject: Re: Express What, not How.
Date: 
Message-ID: <4u65ir2eya.fsf@vex.net>
·······@prism.gatech.edu (Brian McNamara!) writes:

> I agree with your one of your overall theses, which is that we should
> focus on the "what" rather than the "how".  Where our opinions diverge,
> however, is that I think sometimes the best way to communicate an
> abstraction is to show the "how" inline, rather than creating a new
> name in an attempt to capture the "what".

There are also times when "what" and "how" are literally the same,
which is when the "what" is a very trivial task.

It is a very slippery slope to insist coding styles in the name of abstraction:
- every value must have a name
- every function or procedure must be christened
- everything must be put in a class or object (I call this OOP - object
  obfuscation pomposity)
- every line of code must be commented

There is an adverse social effect (since social effect was mentioned)
whenever an abstraction mechanism like the above ones is doctrinized.
Programmers will begin devaluing the mechanism.  If you insist on
comments, they start writing silly comments; if you insist on naming
things, they start giving silly names; and if you insist on classes,
well, they start putting everything into one single class and making
all members static and public.  They start seeing the abstraction
mechanism as a bother and stop seeing its potential benefits.

It is when you allow some freedom of not using a mechanism that the
the mechanism becomes valuable.  (The political parallel: some people
like to stay in their countries precisely because their laws permit
them to leave.  Once you remove that freedom, people begin to smuggle
themselves out.)

Now no one is suggesting to make all functions anonymous, all code
unstructured, and all aspects uncommented.  Nothing of that sort!  In
practice we give names to all non-trivial functions.  Someone asserted
that we should judge a mode of expression for what it does when put in
good use, not what it could do when abused.  That person should not
argue against anonymous functions by noting all the gory details of
implementation it might expose in the wrong hands.

And now I would like to sidetrack a bit and give an unrelated example
of Brian's point that sometimes "what" without "how" is completely
unclear.

I have an abstract data type to present you.  This exercise is to test
how well you understand the "what" presentation, so the names of the
operations will not give you a clue.  They are meaningful names though
- meaningful to me, a Cantonese speaker.  (Just to show you how
meaningless the whole notion of "meaningful names" is.)  But I will
present you "what" it does without mentioning "how".

It is a functional (immutable) abstract data type, so most operations
take an existing instance as a parameter and return a new instance.
The name of the abstract data type is LiDui.

Hung  : LiDui
MoYun : LiDui -> Bool
PaiDui: (LiDui,Object) -> LiDui
DuiTau: LiDui -> Object
LeiDui: LiDui -> LiDui

MoYun(Hung) is true.
For any LiDui d:
  If MoYun(d) is true, we have LeiDui(PaiDui(d,o))=d and DuiTau(PaiDui(d,o))=o.
  If MoYun(d) is false, we have LeiDui(PaiDui(d,o))=PaiDui(LeiDui(d),o).

That's it.

I have never seen any first-year CS class present this abstract data
type this way.  All presentations either show a simple pseudocode
implementation, or appeal to a mental model derived from a real life
experience, which is still a kind of simple pseudocode implementation,
except it is in real life terms instead of CS terms.
From: David Eppstein
Subject: Re: Express What, not How.
Date: 
Message-ID: <eppstein-798393.00155115102003@news.service.uci.edu>
In article <··············@vex.net>, Albert Lai <······@vex.net> wrote:

> It is a functional (immutable) abstract data type, so most operations
> take an existing instance as a parameter and return a new instance.
> The name of the abstract data type is LiDui.
> 
> Hung  : LiDui
> MoYun : LiDui -> Bool
> PaiDui: (LiDui,Object) -> LiDui
> DuiTau: LiDui -> Object
> LeiDui: LiDui -> LiDui
> 
> MoYun(Hung) is true.
> For any LiDui d:
>   If MoYun(d) is true, we have LeiDui(PaiDui(d,o))=d and 
>   DuiTau(PaiDui(d,o))=o.
>   If MoYun(d) is false, we have LeiDui(PaiDui(d,o))=PaiDui(LeiDui(d),o).
> 
> That's it.

You sure you don't need a little more?  This seems to fit both stacks 
(MoYun always = True) and queues (MoYun true only for Hung).

That's one trouble with axiomatic definitions -- it's hard to be sure 
you've expressed all of the behavior you intend to specify.
Another is that they can be difficult to understand.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Albert Lai
Subject: Re: Express What, not How.
Date: 
Message-ID: <4uzng33sfu.fsf@vex.net>
Albert Lai <······@vex.net> writes:

> Hung  : LiDui
> MoYun : LiDui -> Bool
> PaiDui: (LiDui,Object) -> LiDui
> DuiTau: LiDui -> Object
> LeiDui: LiDui -> LiDui
> 
> MoYun(Hung) is true.
> For any LiDui d:
>   If MoYun(d) is true, we have LeiDui(PaiDui(d,o))=d and DuiTau(PaiDui(d,o))=o.
>   If MoYun(d) is false, we have LeiDui(PaiDui(d,o))=PaiDui(LeiDui(d),o).
> 
> That's it.

I knew I forgot something.

If MoYun(d) is false, we have LeiDui(PaiDui(d,o))=PaiDui(LeiDui(d),o)
and DuiTau(PaiDui(d,o))=DuiTau(d).

MoYun(PaiDui(d,o)) is false.
From: james anderson
Subject: Re: Express What, not How.
Date: 
Message-ID: <3F8D0580.A3704C86@setf.de>
"Brian McNamara!" wrote:
> 
> Raffael Cavallaro <················@junk.mail.me.not.mac.com> once said:
> > Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:
> >> Sometimes a function is so simple that its body is more clear than any
> >> name. A name is an extra level of indirection. You must follow it to be
> >> 100% sure what the function means, or to understand what does it really
> >> mean that it does what it's named after.
> >
> >Your argument is based on the assumption that whenever people express
> >_what_ a function does, they do so badly, with an inappropriate name.
> ...
> 
> If I understand you correctly, you would insist I write something like
> 
>    nat :: Parser Int
>    nat = do {c <- digit; return charToInt c}
>          `chainl1` combineDigits
>             where combineDigits = return \x y -> 10*x+y

when i read r.cavallaro's note, i saw no proscriptions. upon rereading it i
observe a value judgement and several characterizations. perhaps the reader
somehow misinterpreted them as pre/proscriptions. pehaps if the term "force"
were replaced with "require" the b.mcnamara would agree that there is no
contraction between them and his post in reply.

...
> 
> By only naming the most reusable abstractions (and, ideally, selecting
> a set which are mostly orthogonal to one another), we provide a "core
> vocabulary" which captures the essential basis of the domain.  Lambda
> then takes us the rest of the way.  In my opinion, a core vocabulary of
> named functions plus lambda is better than a separate name for every
> abstraction.  In natural language, such a scheme would be considered
> double-plus-un-good, but in programming, I think it lends itself to the
> simplest and most precise specifications.

what is the utility in overstating cavallaro's argument, in order to set up a
straw argument which reaches a conclusion quite in keeping with the original?
perhaps, yes ther is some utility in reiterating that extreme
pre/proscriptions in either direction are counterproductive. but, that in no
way weakens his argument.

> 
> I agree with your one of your overall theses, which is that we should
> focus on the "what" rather than the "how".  Where our opinions diverge,
> however, is that I think sometimes the best way to communicate an
> abstraction is to show the "how" inline, rather than creating a new
> name in an attempt to capture the "what".
>
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Express What, not How.
Date: 
Message-ID: <pan.2003.10.15.08.18.41.116193@knm.org.pl>
On Wed, 15 Oct 2003 00:41:28 +0000, Raffael Cavallaro wrote:

> Your argument is based on the assumption that whenever people express 
> _what_ a function does, they do so badly, with an inappropriate name.

Sometimes there is no name which is more clear than the definition.

A random example from OCaml source:
   if List.exists (fun q -> q.pat_loc = p.pat_loc) ps2 then ...

Would you write it like this? Please fill the appropriate <name>:
   let <name> q = q.pat_loc = p.pat_loc in
   if List.exists <name> ps2 then ...

Note that the function must be written here because it uses p which is
local, unless p was moved to its parameters and partially applied here
(this technique works for OCaml because of curring, it won't work for Lisp
or Scheme).

>> The code also gets longer 
> 
> No, it gets shorter, because you don't repeat your use of the same 
> abstraction over and over.

If it's used only once then the code is longer - see above.

>> When you have lots of short functions, it's harder to find them. There
>> are many names to invent for the writer and many names to rememner for
>> a reader.
> 
> Which is why names should be descriptive.

Great, many long names :-)

>> Why do you insist on naming *functions*? You could equally well say
>> that every list should be named, so you would see its purpose rather
>> than its contents.
> 
> I think this concept is called variable bindings ;^)

I don't say I don't use variables. I say I don't use variables for *every*
subexpression. And sure I do use named functions, but not every function
deserves to be named.

> In the Smalltalk community the rule of thumb is that if a method body
> gets to be more than a few lines, you've failed to break it down into
> smaller abstractions (i.e., methods).

Hmm, Smalltalk blocks are anonymous functions. Do you reject Smalltalk
blocks too? :-)

> Yes, but they should live inside the bodies of named functions. Not lie
> exposed in the middle of higher level abstractions. Please also see my
> reply to Joe Marshall/Prunesquallor a few posts up in this thread.

You contradict yourself. First you say that "any anonymous function syntax
is undesirable", and they you accept anonymous functions in the middle of
higher level abstractions.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: james anderson
Subject: Re: Express What, not How.
Date: 
Message-ID: <3F8C89EA.9DFF093C@setf.de>
Marcin 'Qrczak' Kowalczyk wrote:
> 
> On Tue, 14 Oct 2003 22:09:44 +0000, Raffael Cavallaro wrote:
> 
> > A theme of this whole thread is the difference between writing _what_
> > something does, and _how_ it does it. The higher up the ladder of
> > abstraction we go, the more we want to express _what_ is being done. We
> > leave the _how_ defined elsewhere, to be consulted only as needed.
> 
> Sometimes a function is so simple that its body is more clear than any
> name. ... Function headers are administrative
> stuff, it's harder to find real code among abstractions being introduced
> and used.
> 
> Why do you insist on naming *functions*? ... It's
> all equally absurd.

years and years ago, perchance, the same person who introduced me to
referential transparency also went to great lengths to acquaint me with the
benefits of internal define.

> 
> A program should balance named and unnamed objects. Both are useful,
> there is a continuum between cases where one or the other is more clear
> and it's subjective in border cases, but there is place for unnamed
> functions - they are not that special. Most high level languages have
> anonymous functions for a reason.
> 

please post the longest lambda calculus definition which you would like to
point to as an exemplar of coding clarity - an exercise, publication,
production code, whatever. i'm just wondering if you're serious about all of this.

...
From: ·············@comcast.net
Subject: Re: Express What, not How.
Date: 
Message-ID: <vfqr47s8.fsf@comcast.net>
james anderson <··············@setf.de> writes:


> please post the longest lambda calculus definition which you would like to
> point to as an exemplar of coding clarity - an exercise, publication,
> production code, whatever. i'm just wondering if you're serious about all of this.

I would, but it is huge.

The thing is, the LAMBDA at the beginning is immaterial to the functioning
of the code, it is simply there to `thunkify' the body and can essentially
be ignored.
From: james anderson
Subject: Re: Express What, not How.
Date: 
Message-ID: <3F8CA3C1.D013F4F4@setf.de>
·············@comcast.net wrote:
> 
> james anderson <··············@setf.de> writes:
> 
> > please post the longest lambda calculus definition which you would like to
> > point to as an exemplar of coding clarity - an exercise, publication,
> > production code, whatever. i'm just wondering if you're serious about all of this.
> 
> I would, but it is huge.
> 
> The thing is, the LAMBDA at the beginning is immaterial to the functioning
> of the code, it is simply there to `thunkify' the body and can essentially
> be ignored.

well, if there are none in the body, then it will not help to understand the
criteria which the forgoing message proposed.
From: Adrian Hey
Subject: Re: Express What, not How.
Date: 
Message-ID: <bmip95$527$1$8302bc10@news.demon.co.uk>
james anderson wrote:
 
> Marcin 'Qrczak' Kowalczyk wrote:
>> Most high level languages have anonymous functions for a reason.
>> 
> 
> i'm just wondering if you're serious about all of this.

I think Marcin is serious, and any Haskeller would agree I suspect.

A good example from Haskell would be the use of lambda abstractions
as the second argument of the monadic >>= operator. Supplying names
for all those abstractions would be really awkward and yield highly
unreadable code IMO.

For those that don't like all those lambdas, Haskell's imperative style
"do" expressions can be used instead, but only for monads. There are
still occassions where explicit lambda's are an easier and clearer
alternative than defining named functions.

Regards
--
Adrian Hey
From: james anderson
Subject: Re: Express What, not How.
Date: 
Message-ID: <3F8CFA94.55458D4A@setf.de>
Adrian Hey wrote:
> 
> james anderson wrote:
> 
> > Marcin 'Qrczak' Kowalczyk wrote:
> >> Most high level languages have anonymous functions for a reason.
> >>
> >
> > i'm just wondering if you're serious about all of this.
> 
> I think Marcin is serious, and any Haskeller would agree I suspect.
> 

i have no argument with the utility of lambda abstractions.
i am trying only to understand the implications of an argument which, at least
as stated, rather unequivocally deprecates bindings.
the position which was proposed in the forgoing post was rather extreme.
i enquired to see of m.kowalczyk might offer some practical examples from
which it might be possible to learn something.

> A good example from Haskell would be the use of lambda abstractions
> as the second argument of the monadic >>= operator. Supplying names
> for all those abstractions would be really awkward and yield highly
> unreadable code IMO.

yes, i am good friends with lambda abstractions. we get along well and respect
each other. i am, however, neither married to one, nor an initiate in a sect
which deems it a transgression to utter the name of another deity.

...
From: ··········@ii.uib.no
Subject: Re: Express What, not How.
Date: 
Message-ID: <egd6cyu3ol.fsf@vipe.ii.uib.no>
james anderson <··············@setf.de> writes:

> i have no argument with the utility of lambda abstractions.  i am
> trying only to understand the implications of an argument which, at
> least as stated, rather unequivocally deprecates bindings.  the
> position which was proposed in the forgoing post was rather extreme.

You mean this position?

| A program should balance named and unnamed objects. Both are useful,
| there is a continuum between cases where one or the other is more clear

I have a hard time interpreting this as extremist.  Perhaps you should
re-read what you are replying to?

I'm rather baffled that anybody would argue against this, to me too,
it is perfectly natural to use anonymous functions in exression,
whether manifest as a lamda expressions, compositions of functions,
combinators or partial applications (are there more?).

To me, this is the same argument as that against excessive comments,
overly verbose identifiers or annotations (like Hungarian notation) -
if the code is short and clear enough, it only detracts from
readability, and, at worst, becomes misleading or wrong.  If the code
isn't clear enough, it should be rewritten.

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
From: james anderson
Subject: Re: Express What, not How.
Date: 
Message-ID: <3F8D381B.31FD01D@setf.de>
··········@ii.uib.no wrote:
> 
> james anderson <··············@setf.de> writes:
> 
> > i have no argument with the utility of lambda abstractions.  i am
> > trying only to understand the implications of an argument which, at
> > least as stated, rather unequivocally deprecates bindings.  the
> > position which was proposed in the forgoing post was rather extreme.
> 
> You mean this position?
> 
> | A program should balance named and unnamed objects. Both are useful,
> | there is a continuum between cases where one or the other is more clear
> 

no i did not mean that position.

> I have a hard time interpreting this as extremist.  Perhaps you should
> re-read what you are replying to?

i did. i also read the post he purported to be replying to. and observed that
there is no need to overstate some elses position in order to, in the end,
make the same point.

the last paragraph, which you site above, stand in strange contrast to the
remainder of the post.

> 
> I'm rather baffled that anybody would argue against this,

i'm rather baffled that anybody would think i did. i did not argue against
that last paragraph, but against the rhetoric in the preceeding text.

>    to me too,
> it is perfectly natural to use anonymous functions in exression,
> whether manifest as a lamda expressions, compositions of functions,
> combinators or partial applications (are there more?).
> 
> To me, this is the same argument as that against excessive comments,
> overly verbose identifiers or annotations (like Hungarian notation) -
> if the code is short and clear enough, it only detracts from
> readability, and, at worst, becomes misleading or wrong.  If the code
> isn't clear enough, it should be rewritten.

...
From: ··········@ii.uib.no
Subject: Re: Express What, not How.
Date: 
Message-ID: <egwub65ivc.fsf@vipe.ii.uib.no>
james anderson <··············@setf.de> writes:

> the last paragraph, which you site above, stand in strange contrast to the
> remainder of the post.

Well, the post he replied to, contained:

| No one is talking about need [to name functions], but about clarity
| of exposition. 

| It is perfectly possible to program functionally in lisp, as I'm sure 
| you know. It just makes code less readable to use _anonymous_ functions. 

I interpreted this rather as a blanket statement, and one I happen to
disagree with.   Perhaps Raffael meant that anonymous functions *can*
make code less readable *sometimes*, which we all seem to agree on so
vehemently? 

A bit later, you say in <·················@setf.de>

| i am trying only to understand the implications of an argument
| which, at least as stated, rather unequivocally deprecates bindings.

-- a point of view I don't quite see where you picked up.  It is
certainly not one I've seen advocated seriously by anybody.  And, as
you say:

> there is no need to overstate some elses position in order to, in the end,
> make the same point.

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
From: james anderson
Subject: Re: Express What, not How.
Date: 
Message-ID: <3F8DBF75.6CFF7A0F@setf.de>
··········@ii.uib.no wrote:
> 
> james anderson <··············@setf.de> writes:
> 
> > the last paragraph, which you site above, stand in strange contrast to the
> > remainder of the post.
> 
> Well, the post he replied to, contained:
> 
> | No one is talking about need [to name functions], but about clarity
> | of exposition.
> 
> | It is perfectly possible to program functionally in lisp, as I'm sure
> | you know. It just makes code less readable to use _anonymous_ functions.
> 
> I interpreted this rather as a blanket statement, and one I happen to
> disagree with.

i suggest that the interpretation is not reasonable in the context of the
remainder of that message. i do not quote it here, and will spare one the
explication, but suggest, as one has done for me, that the interested reader
reexamine the text in question for their own edification.

>      Perhaps Raffael meant that anonymous functions *can*
> make code less readable *sometimes*, which we all seem to agree on so
> vehemently?

that is the reasonable interpretation of his position, expecially in light of
his later posts, but also given the original text.

> 
> A bit later, you say in <·················@setf.de>
> 
> | i am trying only to understand the implications of an argument
> | which, at least as stated, rather unequivocally deprecates bindings.

to cite the most inexplicable paragraph from the post to which i was
referring, there is a passage

"Why do you insist on naming *functions*? You could equally well say that
every list should be named, so you would see its purpose rather than its
contents. Perhaps every number should be named, so you can see what it
represents rather than its value. You could say that each statement of
a compound statement should be moved to a separate function, so you can
see what it does by its name, not how it does it by its contents. It's
all equally absurd."

which proceeds from an unfounded attribution through equally unfounded
suppositions, to an absurd conclusion. 
> 
> -- a point of view I don't quite see where you picked up.  It is
> certainly not one I've seen advocated seriously by anybody.  And, as
> you say:
> 
> > there is no need to overstate some elses position in order to, in the end,
> > make the same point.

given the rhetorical quality of the paragraph which i cite above, one might
suppose that the reader overlooked it.

...
From: Hartmann Schaffer
Subject: Re: Express What, not How.
Date: 
Message-ID: <3f8e0e4b@news.sentex.net>
In article <······································@netnews.attbi.com>,
	Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:
>> A programmer accustomed to the 
>> functional style finds the need in non-FP languages to name every 
>> function analogously awkward.
> 
> No one is talking about need, but about clarity of exposition.

which is essentially a style question, which usually don't have
absolute answers

> It is perfectly possible to program functionally in lisp, as I'm sure 
> you know. It just makes code less readable to use _anonymous_ functions. 
> Code is no less functional when the functions are named.

this would largely depend on the function.  e.g. i don't see any
benefit in adding function definitions to add 2 or multiply by 3
instead of using anonymous functions

(defun add2 (x) (+ x 2))

... many lines / pages/ screenloads of code

(map 'list #'add2 list)

doesn't look any more expositive to me than

(map 'list (lambda (x) (+ x 2)) list),

quite to the contrary.  there are enough cases where you need
something like this.  obviously, you can abuse this

> ...
> Anonymous functions force the _how_ to be interleaved with the _what_, 
> breaking up the clarity of the _what_. Named functions (and macros) 
> allow the high level abstractions to be expressed in terms of _what_ is 
> happening, without unnecessary reference to _how_.
> 
> Anonymous functions force the reader to deal with _how_ precisely 
> because there is no descriptive name that expresses _what_ the funtion 
> does. This is an inappropriate conflation of two distinct purposes, that 
> can and should be separated in source code.

the problem with your position is that you make a dogma out of a
generally useful observation

hs

-- 

ceterum censeo SCO esse delendam
From: David Rush
Subject: Re: Express What, not How.
Date: 
Message-ID: <oprw8crrz03seq94@news.nscp.aoltw.net>
On Tue, 14 Oct 2003 22:09:44 GMT, Raffael Cavallaro 
<················@junk.mail.me.not.mac.com> wrote:

> In article <············@terabinaries.xmission.com>,
> Thant Tessman <·····@acm.org> wrote:
>
>> A programmer accustomed to the functional style finds the need in non-FP 
>> languages to name every function analogously awkward.
>
> No one is talking about need, but about clarity of exposition.
...
> It just makes code less readable to use _anonymous_ functions.

No. It doesn't.

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: ··········@ii.uib.no
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <egy8vn26xv.fsf@vipe.ii.uib.no>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:

> I think it is the mark of functional cleverness that people's code is 
> filled with anonymous functions. These show you how the code is doing 
> what it does, not what it is doing.

Uh, I often use a lambda because I think it improves readability.

I could write

        (,) x . length . fst

but think 

        \(a,_) -> (x,lenght a)

is clearer, because it is *less* functionally clever.  Of course, it
could be written

        let pair_x_and_length_of_first (a,_) = (x,lenght a)
        in pair_x_and_length_of_first

but I don't think it improves things, and in fact reduces lucidity and
maintainability.  Naming is like comments, when the code is clear
enough, it should be minimized.  IMHO.

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <d6d01e2g.fsf@comcast.net>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:

> Note that Lisp and Scheme have a quite unpleasant anonymous function
> syntax, which induces a stronger tension to macros than in e.g. Ruby or
> Haskell.

Good grief!

Unpleasant is the inner classes needed to emulate anonymous functions
in Java.
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310131251.2f87bba5@posting.google.com>
Matthias Blume <····@my.address.elsewhere> wrote in message news:<··············@tti5.uchicago.edu>... 
> Well, no, not really.  You can define new syntactic forms in terms of
> old ones, and the evaluation rules end up being determined by those of
> the old ones.  Again, with HOFs you can always get the same
> effect -- at the expense of an extra lambda here and there in your
> source code.

A macro can control optimization: whether or not something is achieved
by that extra lambda, or by some open coding.

In the worst cases, the HOF solution would require the user to
completely obfuscate the code with explicitly-coded lambdas. The code
would be unmaintainable.

Secondly, it would be unoptimizeable. The result of evaluating a
lambda expression is an opaque function object. It can only be called.

Consider the task of embedding one programming language into another
in a seamless way. I want to be able to write utterances in one
programming language in the middle of another. At the same time, I
want seamless integration between them right down to the lexical
level. For example, the embedded language should be able to refer to
an outer variable defined in the host language.

HOF's are okay if the embedded language is just some simple construct
that controls the evaluation of coarse-grained chunks of the host
language. It's not too much of an inconvenience to turn a few
coarse-grained chunks into lambdas.

But what if the parameters to the macro are not at all chunks of the
source language but completely new syntax? What if that syntax
contains only microscopic utterances of the host language, such as the
mentions of the names of variables bound in surrounding host language?

You can't put a lambda around the big construct, because it's not even
written in the host language! So what do you do? You can use an escape
hatch to code all the individual little references as host-language
lambdas, and pepper these into the embedded language utterance. For
variables that are both read and written, you need a reader and writer
lambda. Now you have a tossed salad. And what's worse, you have poor
optimization. The compiler for the embedded language has to work with
these lambdas which it cannot crack open. It can't just spit out code
that is integrated into the host language compile, where references
can be resolved directly.

> > This can only be accomplished with functions if you're
> > willing to write a set of functions that defer evaluation, by, say
> > parsing input, massaging it appropriately, and then passing it to the
> > compiler. At that point, however, you've just written your own macro
> > system, and invoked Greenspun's 10th Law.
> 
> This is false.  Writing your own macro expander is not necessary for
> getting the effect.  The only thing that macros give you in this
> regard is the ability to hide the lambda-suspensions. 

That's like saying that a higher level language gives you the ability
to hide machine instructions. But there is no single unique
instruction sequence that corresponds to the higher level utterance.

Macros not only hide lambdas, but they hide the implementation choice
whether or not lambdas are used, and how! It may be possible to
compile the program in different ways, with different choices.

Moreover, there might be so many lambda closures involved that writing
them by hand may destroy the clarity of expression and maintainability
of the code.

> To some people
> this is more of a disadvantage than an advantage because, when not
> done in a very carefully controlled manner, it ends up obscuring the
> logic of the code.  (Yes, yes, yes, now someone will jump in an tell
> me that it can make code less obscure by "canning" certain common
> idioms.  True, but only when not overdone.)

Functions can obscure in the same ways as macros. You have no choice.
Large programs are written by delegating details elsewhere so that a
concise expression can be obtained.

You can no more readily understand some terse code that consists
mostly of calls to unfamiliar functions than you can understand some
terse code written in an embedded language build on unfamiliar macros.

All languages ultimately depend on macros, even those functional
languages that don't have user-defined macros. They still have a whole
bunch of syntax. You can't define a higher order function if you don't
have a compiler which recognizes the higher-order-function-defining
syntax, and that syntax is nothing more than a macro that is built
into the compiler which captures the idioms of programming with higher
order functions!

All higher level languages are based on syntax which captures idioms,
and this is nothing more than macro processing.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pan.2003.10.13.21.26.56.715704@knm.org.pl>
On Mon, 13 Oct 2003 13:51:22 -0700, Kaz Kylheku wrote:

> Secondly, it would be unoptimizeable. The result of evaluating a
> lambda expression is an opaque function object. It can only be called.

This is not true. When the compiler sees the application of a lambda,
it can inline it and perform further optimizations, fusing together
its arguments, its body and its context.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310140857.7b76f14b@posting.google.com>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote in message news:<······························@knm.org.pl>...
> On Mon, 13 Oct 2003 13:51:22 -0700, Kaz Kylheku wrote:
> 
> > Secondly, it would be unoptimizeable. The result of evaluating a
> > lambda expression is an opaque function object. It can only be called.
> 
> This is not true. When the compiler sees the application of a lambda,
> it can inline it and perform further optimizations, fusing together
> its arguments, its body and its context.

Kindly keep in mind the overall context of the discussion, which is
HOF's versus macros. The closures being discussed are ones passed down
into functions. Those closures typically cannot be inlined, except
under very special circumstances taken advantage of by a compiler with
very smart global optimizations.
From: Matthias Blume
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m1k777n2i2.fsf@tti5.uchicago.edu>
···@ashi.footprints.net (Kaz Kylheku) writes:

> Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote in message news:<······························@knm.org.pl>...
> > On Mon, 13 Oct 2003 13:51:22 -0700, Kaz Kylheku wrote:
> > 
> > > Secondly, it would be unoptimizeable. The result of evaluating a
> > > lambda expression is an opaque function object. It can only be called.
> > 
> > This is not true. When the compiler sees the application of a lambda,
> > it can inline it and perform further optimizations, fusing together
> > its arguments, its body and its context.
> 
> Kindly keep in mind the overall context of the discussion, which is
> HOF's versus macros. The closures being discussed are ones passed down
> into functions. Those closures typically cannot be inlined, except
> under very special circumstances taken advantage of by a compiler with
> very smart global optimizations.

If a macro works in a particular situation, then any equivalent HOF
can be inlined there as well.  Granted, not all compilers will
actually do so, but the possibility trivially exists.  This does not
depend on "very smart" global optimizations.

Matthias
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310141516.5027ee91@posting.google.com>
Matthias Blume <····@my.address.elsewhere> wrote in message news:<··············@tti5.uchicago.edu>...
> ···@ashi.footprints.net (Kaz Kylheku) writes:
> 
> > Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote in message news:<······························@knm.org.pl>...
> > > On Mon, 13 Oct 2003 13:51:22 -0700, Kaz Kylheku wrote:
> > > 
> > > > Secondly, it would be unoptimizeable. The result of evaluating a
> > > > lambda expression is an opaque function object. It can only be called.
> > > 
> > > This is not true. When the compiler sees the application of a lambda,
> > > it can inline it and perform further optimizations, fusing together
> > > its arguments, its body and its context.
> > 
> > Kindly keep in mind the overall context of the discussion, which is
> > HOF's versus macros. The closures being discussed are ones passed down
> > into functions. Those closures typically cannot be inlined, except
> > under very special circumstances taken advantage of by a compiler with
> > very smart global optimizations.
> 
> If a macro works in a particular situation, then any equivalent HOF
> can be inlined there as well.  Granted, not all compilers will
> actually do so, but the possibility trivially exists.  This does not
> depend on "very smart" global optimizations.

That is a case of bringing all of the function into the present
context so it can be mixed with the closures manually created there.

A macro controls how much material is inlined and how much isn't.

A macro can have its own binary interface between the expanded
material and some material in a library that is associated with the
macro.

The macro decides what forms need to be made into a closure that is
passed to the library and which are not.

These considerations are important, because in the Lisp world,
programs are dynamically updated while they are running. There are
versioning issues, like keeping new versions of a macro's library
compatible with existing macro-expansions, which won't be re-expanded
and re-compiled when the new code is loaded into an existing
application.
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310151032.2c668a06@posting.google.com>
···@ashi.footprints.net (Kaz Kylheku) wrote in message news:<····························@posting.google.com>...
> Matthias Blume <····@my.address.elsewhere> wrote in message news:<··············@tti5.uchicago.edu>...
> > ···@ashi.footprints.net (Kaz Kylheku) writes:
> > 
> > > Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote in message news:<······························@knm.org.pl>...
> > > > On Mon, 13 Oct 2003 13:51:22 -0700, Kaz Kylheku wrote:
> > > > 
> > > > > Secondly, it would be unoptimizeable. The result of evaluating a
> > > > > lambda expression is an opaque function object. It can only be called.
> > > > 
> > > > This is not true. When the compiler sees the application of a lambda,
> > > > it can inline it and perform further optimizations, fusing together
> > > > its arguments, its body and its context.
> > > 
> > > Kindly keep in mind the overall context of the discussion, which is
> > > HOF's versus macros. The closures being discussed are ones passed down
> > > into functions. Those closures typically cannot be inlined, except
> > > under very special circumstances taken advantage of by a compiler with
> > > very smart global optimizations.
> > 
> > If a macro works in a particular situation, then any equivalent HOF
> > can be inlined there as well.  Granted, not all compilers will
> > actually do so, but the possibility trivially exists.  This does not
> > depend on "very smart" global optimizations.
> 
> That is a case of bringing all of the function into the present
> context so it can be mixed with the closures manually created there.
> 
> A macro controls how much material is inlined and how much isn't.

What I said here is silly because a HOF can also be structured to have
inlined and noninlined parts: an inlined skeleton function that calls
non-inlined functions.

> A macro can have its own binary interface between the expanded
> material and some material in a library that is associated with the
> macro.
> 
> The macro decides what forms need to be made into a closure that is
> passed to the library and which are not.

This is the real point; in a Lisp macro, material from parameters is
usually spun into closures precisely because inlining is not wanted;
it's a compromise which allows some remote function to call back into
the present lexical environment, allowing the macro to generate less
inlined bloat.

In functional languages with lazy evaluation, evey expression is
effectively a closure. When you call some function f with argument x,
that x is effectively a lambda function which returns the value of x
in its original environment.

When the argument to a function is an expression, it need not be
evaluated prior to the call; it may be delayed until the last possible
moment when its value is actually needed, and it may never be
evaluated at all.

So it seems as if higher order functions have the evaluation control
of macros. But delaying evaluation is not the same as control over
evaluation. Moreover, a macro is not just some mechanism for delaying
the evaluation of expressions; it's a mechanism for assigning an
arbitrary meaning to expressions.

A HOF can generate code only by interpolating parameters into a fixed
body. The meaning of everything stays the same. A HOF can trivially
replace a macro under two conditions:

1. The macro is used as an interface to hide lambdas from the user.
This is not necessary if the language has lazy evaluation. Every
expression is already a lambda, capable of being passed to a foreign
environment and evaluated there, with all the hooks to the original
environment.

2. The macro is used as a trivial inlining mechanism, which
substitutes expressions into a template. HOF inlining effectively does
the same thing. Since evaluation is lazy, there is little or no
semantic difference between evaluating parameters and calling a
function, or inserting the unevaluated expressions into the body and
inlining it.

In Common Lisp, we don't have the lazy evaluation semantics, so
certain macro uses that fall under 1. are essential. People who argue
against these always use HOF examples from another programming
language. But CL programmers don't want to switch to another
programming language. You can't switch programming languages while
holding everything else constant.

Certain macro uses in Lisp that seem to fall under 2. are also
essential; some macros that do nothing more than substitute their
arguments into some functional template nevertheless have imperative
semantics, such as conditional or repeated evaluation of some forms.
When Lisp programmers demonstrate these uses, again, they are
countered by examples from a different programming language. ``Gee, if
you only had virtual sequences (or whatever gadget), you wouldn't need
that imperative DO- stuff.'' But now you are no longer talking about
just HOF's, but HOF's plus virtual sequences.

In general, for every macro use, you could design a programming
language feature, such as higher order functions, lazy sequences and
whatnot, and then claim that the macro use is unnecessary when you
have that feature. The problem is that there is no end to this
progression. Macros can implement anything you want (arbitrary syntax
to semantics mapping), and that anything can always be given a name
and codified in some offshoot academic language under a coat of
hard-coded syntax, and you can then claim that you eliminated macros
once and for all for all situations that you (and by implication
everyone else) cares about.
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310131201.776b85dd@posting.google.com>
·····@cs.uwa.edu.au wrote in message news:<············@enyo.uwa.edu.au>...
> In comp.lang.functional Erann Gat <··························@jpl.nasa.gov> wrote:
> :> I can't see why a LISP programmer would even want to write a macro.
> : That's because you are approaching this with a fundamentally flawed
> : assumption.  Macros are mainly not used to make the syntax prettier
> : (though they can be used for that).  They are mainly used to add features
> : to the language that cannot be added as functions.
> 
> Really? Turing-completeness and all that... I presume you mean "cannot

``Turing completeness and all that'' is an argument invoked by the
clueless.

Turing completeness doesn't say anything about how long something
takes to compute, or how easy it is to express some interesting
computation.

In the worst case, for you to get the behavior in some program I wrote
in language A in your less powerful (but Turing complete!) language B,
you might have to write an A interpreter or compiler, and then just
run my original program written in A! The problem is that you did not
actually find a way to *express* the A program in language B, only a
way to make its behavior unfold.

Moreover, you may have other problems, like difficulties in
communicating between the embedded A program and the surrounding B
code! These difficulties could be alleviated if you could write an A
*compiler* in B, a compiler which is integrated into your B compiler,
so that a mixture of A and B code is processed as one unit!

This is precisely what Lisp macros allow us to do: write compilers for
embedded languages, which operate together, all in the same pass.

So for instance an utterance in the embedded language can refer
directly to a local variable defined in a lexically surrounding
construct of the host language.

> : DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
> : any other way because they take variable names and code as arguments.
> 
> What does it mean to take a variable-name as an argument? How is that
> different to taking a pointer? What does it mean to take "code" as an
> argument? Is that different to taking a function as an argument?

Sheesh. A funtion is an object containing a program, and an
environment that establishes the meaning of entities like variables
for that program.

Code, in this context, means source code: a raw data structure
representing syntax.

Code can be analyzed, subject to transformations, and interpreted to
have arbitrary semantics.

A function can merely be invoked with arguments.

A compiler or interpreter for a functional language like Haskell still
has to deal with the representation of the program at some point: it
has to parse the source characters, recognize the syntax and translate
it into some meaning.

Lisp macros are part of the toolset that allow this translation itself
to be programmable. Thus you are not stuck with a fixed phrase
structure grammar with fixed semantics.

Nearly every programming language has macros, it's just that most of
them have a hard-coded set of ``factory defined'' macros in the form
of a fixed set of production rules with rigidly defined semantics.

What is a macro? It's a recognizer for syntax that implements some
kind of syntax-directed translation. I would argue that   while (expr)
statement   in the C language is a macro: it's a pattern that matches
a parse subtree that is tagged with the ``while'' token and translates
it into looping code, whose semantics call for the repeated testing of
the guarding expression, followed by execution of the statement if
that expression is true.
From: Category 5
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yy107k383k49.fsf@chaosnet.org>
···@ashi.footprints.net (Kaz Kylheku) writes:

> Lisp macros are part of the toolset that allow this translation itself
> to be programmable. Thus you are not stuck with a fixed phrase
> structure grammar with fixed semantics.
>
> Nearly every programming language has macros, it's just that most of
> them have a hard-coded set of ``factory defined'' macros in the form
> of a fixed set of production rules with rigidly defined semantics.

Exactly so.  But the average human mind clings viciously to rigid schema
of all kinds in reflexive defence against the terrible uncertainties of
freedom.

To get someone with this neurological ailment to give up their preferred
codification for another is very difficult.  To get them to see beyond
the limits of particular hardcoded schema altogether is practically
impossible.

This observation applies uniformly to programming and religion, but is
not limited to them.

-- 
 
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310131300.7742c8bf@posting.google.com>
·····@cs.uwa.edu.au wrote in message news:<············@enyo.uwa.edu.au>...
> In comp.lang.functional Erann Gat <··························@jpl.nasa.gov> wrote:
> : For example, imagine you want to be able to traverse a binary tree and do
> : an operation on all of its leaves.  In Lisp you can write a macro that
> : lets you write:
> : (doleaves (leaf tree) ...)
> : You can't do that in Python (or any other langauge).
> 
> My Lisp isn't good enough to answer this question from your code,
> but isn't that equivalent to the Haskell snippet: (I'm sure
> someone here is handy in both languages)
> 
> doleaves f (Leaf x)     = Leaf (f x)
> doleaves f (Branch l r) = Branch (doleaves f l) (doleaves f r)

You appear to be using macros here to define some entities. What if we
took away the syntax which lets you write the above combination of
symbols to achieve the associated meaning? By what means would you
give meaning to the = symbol or the syntax (Leaf x)?

Or give me a plausible argument to support the assertion that the =
operator is not a macro. If it's not a macro, then what is it, and how
can I make my own thing that resembles it?
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pan.2003.10.13.21.50.45.837962@knm.org.pl>
On Mon, 13 Oct 2003 14:00:50 -0700, Kaz Kylheku wrote:

>> doleaves f (Leaf x)     = Leaf (f x)
>> doleaves f (Branch l r) = Branch (doleaves f l) (doleaves f r)
> 
> You appear to be using macros here to define some entities. What if we
> took away the syntax which lets you write the above combination of
> symbols to achieve the associated meaning?

It's not macros. If essential syntax of some language was taken away,
perhaps programming in that language would be impossible - but it's not
being taken away, so what's the point?

> By what means would you give meaning to the = symbol or the syntax (Leaf x)?

I don't have to - the compiler already did that.

> Or give me a plausible argument to support the assertion that the =
> operator is not a macro. If it's not a macro, then what is it,

Builtin syntax. Macros are defined outside the compiler and they expand
into other syntax which doesn't use them. '=' here doesn't expand to
anything, it's a primitive language construct.

> and how can I make my own thing that resembles it?

You can't. But you haven't demonstrated that one would want to.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <he2c1eb5.fsf@comcast.net>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:

> On Mon, 13 Oct 2003 14:00:50 -0700, Kaz Kylheku wrote:
>
>> If it's not a macro, then what is it,
>> and how can I make my own thing that resembles it?
>
> You can't. But you haven't demonstrated that one would want to.

Can we take that as a given, please?  We lispers are a whining,
complaining lot and we can figure out what we want or don't want all
by ourselves thankyouverymuch.  Kaz Kylheku wants a new infix
operator and he doesn't have to justify that to anyone.
From: Tomasz Zielonka
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbonhmq.qqt.t.zielonka@zodiac.mimuw.edu.pl>
·············@comcast.net napisa�:
> Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> 
>> On Mon, 13 Oct 2003 14:00:50 -0700, Kaz Kylheku wrote:
>>
>>> If it's not a macro, then what is it,
>>> and how can I make my own thing that resembles it?
>>
>> You can't. But you haven't demonstrated that one would want to.
> 
> Can we take that as a given, please?  We lispers are a whining,
> complaining lot and we can figure out what we want or don't want all
> by ourselves thankyouverymuch.  Kaz Kylheku wants a new infix
> operator and he doesn't have to justify that to anyone.

The problem is that = is not an operator in Haskell. You can define your
own === =!= *** <+> <|> ? # etc operators or even redefine standard
equality == operator. 

Can you redefine parentheses in Lisp?

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310140939.2f23521b@posting.google.com>
Tomasz Zielonka <··········@students.mimuw.edu.pl> wrote in message news:<·························@zodiac.mimuw.edu.pl>...
> ·············@comcast.net napisa�:
> > Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> > 
> >> On Mon, 13 Oct 2003 14:00:50 -0700, Kaz Kylheku wrote:
> >>
> >>> If it's not a macro, then what is it,
> >>> and how can I make my own thing that resembles it?
> >>
> >> You can't. But you haven't demonstrated that one would want to.
> > 
> > Can we take that as a given, please?  We lispers are a whining,
> > complaining lot and we can figure out what we want or don't want all
> > by ourselves thankyouverymuch.  Kaz Kylheku wants a new infix
> > operator and he doesn't have to justify that to anyone.
> 
> The problem is that = is not an operator in Haskell. You can define your
> own === =!= *** <+> <|> ? # etc operators or even redefine standard
> equality == operator. 

In Lisp terminology we use the term operator to denote something that
is distinct from a function; it's something that can act on the
syntactic structure of its arguments, rather than just on the objects
that result from evaluating the arguments. Operators are either macros
(sometimes called macro operators) or special forms.

In some languages, an operator is simply a function whose name
consists of punctuation marks. So for instance in C++, there is a +
operator, but it's really just a function. When you overload it, you
write a member or non-member function.

This distinction doesn't meaningfully arise in Lisp, because symbols
can have names consisting of glyps like +, <*> .

> Can you redefine parentheses in Lisp?

Yes you can. The lexical analysis of Lisp is driven by character
dispatch tables which are programmable. The well-known infix read
macro assigns a very different meaning to parentheses, for instance;
they do not indicate list structure but arithmetic precedence.

But anyway, it's ridiculous to compare the Haskell = to a Lisp
parenthesis.

Parentheses are completely general indicators of list structure, not
tied to any particular semantics. They are processed at the lexical
level. Once the list data structure is obtained from the text
characters, the parentheses disappear; only the structure remains. The
real syntax is then treated at a higher level. Consequently, a
parenthesized list can represent a class definition, a logical
inference rule, a bar of sheet music, whatever. So yes, in this sense
you are effectively redefining parentheses, even if you are not
manipulating the read tables which change the lexical action by which
parentheses make lists.

Does the Haskell = punctuator give rise to a well-defined target data
structure which is processed independently of that character? Or is it
a lexical mark that is conflated into the highest levels of syntactic
processing in that language?
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmgoc8$133a$1@f1node01.rhrz.uni-bonn.de>
Tomasz Zielonka wrote:

> Can you redefine parentheses in Lisp?

Yes. By default they belong to the set of macro characters. See 
http://www.lispworks.com/reference/HyperSpec/Body/02_add.htm

A pretty cool example of what you can do with macro characters is given 
at http://groups.google.com/groups?selm=gat-2604031057370001%40192.168.1.51


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Kaz Kylheku
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <cf333042.0310140923.7a72c828@posting.google.com>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote in message news:<······························@knm.org.pl>...
> On Mon, 13 Oct 2003 14:00:50 -0700, Kaz Kylheku wrote:
> 
> >> doleaves f (Leaf x)     = Leaf (f x)
> >> doleaves f (Branch l r) = Branch (doleaves f l) (doleaves f r)
> > 
> > You appear to be using macros here to define some entities. What if we
> > took away the syntax which lets you write the above combination of
> > symbols to achieve the associated meaning?
> 
> It's not macros. If essential syntax of some language was taken away,
> perhaps programming in that language would be impossible - but it's not
> being taken away, so what's the point?

In the Lisp language, you never know what is a macro and what is
intrinsic to the compiler. There is no difference between these two;
it's just an implementation choice.

Lisp programmers regard macros to be miniature compilers. They can be
used to implement new language syntax and semantics that are
indistinguishable from something that is built in.

Lisp macros are code that is loaded into the compiler's image. They
are even compiled to machine code. There may be no compile-time
performance disadvantage whatsoever in implementing some language
feature as a macro.

> > By what means would you give meaning to the = symbol or the syntax (Leaf x)?
> 
> I don't have to - the compiler already did that.

No, some *people* did that. Since their work is not designed for
extensibility, you have to live with their design decisions.

Of course, you trust them to be infinitely more intelligent than
yourself, such that you are incapable of improving upon their work.

You believe that their work is so perfect, that no new syntax and
semantics need be invented. You can do all your work within their
system, without ever acting upon that system.

Which leads to the question: why do you ever switch to a new
programming language?

> > Or give me a plausible argument to support the assertion that the =
> > operator is not a macro. If it's not a macro, then what is it,
> 
> Builtin syntax. Macros are defined outside the compiler and they expand
> into other syntax which doesn't use them. '=' here doesn't expand to

Can you tell me whether the Common Lisp LOOP operator outside the
compiler or inside?

Do you know that even DEFUN and DEFMACRO are typically macros? That's
right; when yous DEFMACRO to write macros, you are using a macro,
without which macro-writing would be less convenient. If someone took
DEFMACRO away, the user could write code to put it back.

A significantly large proportion of any CL implementation consists of
macros. There is no agreed upon subset of Lisp intrinsics. What is a
macro in one implementation may be built into the compiler in another.

> anything, it's a primitive language construct.

Your responses *perfectly* capture the big gap between those who get
macros, and those who don't.

There is no ``primitive language construct''. This is an illusion
supported by the limitations of some programming languages, notably
ones which define the source representation of a program as a sequence
of characters interpreted according to a rigid syntax, and which
provide named subroutines as the only means of extension.

> > and how can I make my own thing that resembles it?
> 
> You can't. But you haven't demonstrated that one would want to.

Obviously, the people who designed that programming language feature
wanted to because they made it happen! And whoever uses that language
feature demostrates a desire for it.

It's amusing how the same programmers who show a disdain for macros
tend to also hop from one programming language to another and worship
the new hard-coded syntax and semantics they find in the ever greener
pasture.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pan.2003.10.14.19.04.33.376540@knm.org.pl>
On Tue, 14 Oct 2003 10:23:16 -0700, Kaz Kylheku wrote:

> You believe that their work is so perfect, that no new syntax and
> semantics need be invented. You can do all your work within their
> system, without ever acting upon that system.

No. I believe the cost of allowing to systematically extend the syntax is
too high. Namely it either requires the syntax to have a simple surface
structure, so macros can examine it (Lisp) or the macro system is very
complex (camlp4, Template Haskell) or limited (Template Haskell can't
really change the syntax much).

The syntax of many languages can be aesthetic because they lack macros.
It's very hard or impossible to design a composable language of
non-trivial syntax extensions. I'm pretty sure that if one Lisp macro
package tried to provide indentation based grouping, another - infix
operators, another - list comprehensions, and yet another - tuples written
with commas between elements, then they won't play together unless they
are aware of each other.

> It's amusing how the same programmers who show a disdain for macros
> tend to also hop from one programming language to another and worship
> the new hard-coded syntax and semantics they find in the ever greener
> pasture.

Because these hard-coded syntaxes are prettier than the extensible Lisp
syntax full of parentheses.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Rainer Joswig
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <joswig-4A5FDF.17121114102003@news.fu-berlin.de>
In article <······························@knm.org.pl>,
 Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:

> On Tue, 14 Oct 2003 10:23:16 -0700, Kaz Kylheku wrote:
> 
> > You believe that their work is so perfect, that no new syntax and
> > semantics need be invented. You can do all your work within their
> > system, without ever acting upon that system.
> 
> No. I believe the cost of allowing to systematically extend the syntax is
> too high. Namely it either requires the syntax to have a simple surface
> structure, so macros can examine it (Lisp) or the macro system is very
> complex (camlp4, Template Haskell) or limited (Template Haskell can't
> really change the syntax much).
> 
> The syntax of many languages can be aesthetic because they lack macros.
> It's very hard or impossible to design a composable language of
> non-trivial syntax extensions. I'm pretty sure that if one Lisp macro
> package tried to provide indentation based grouping, another - infix
> operators, another - list comprehensions, and yet another - tuples written
> with commas between elements, then they won't play together unless they
> are aware of each other.
> 
> > It's amusing how the same programmers who show a disdain for macros
> > tend to also hop from one programming language to another and worship
> > the new hard-coded syntax and semantics they find in the ever greener
> > pasture.
> 
> Because these hard-coded syntaxes are prettier than the extensible Lisp
> syntax full of parentheses.

Beauty is in the eye of the beholder.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmhri6$mm2$1@newsreader2.netcologne.de>
Marcin 'Qrczak' Kowalczyk wrote:

> Because these hard-coded syntaxes are prettier than the extensible Lisp
> syntax full of parentheses.

Obviously, you haven't tried to actually program in Lisp. Getting used 
to the syntax is a matter of one or two weeks at most of actual coding, 
provided you use a decent editor that supports parenthesis highlighting 
and automatic indentation.

Despising Lisp because of its syntax is like thinking that Japanese is a 
too complicated language because it doesn't use latin characters.


Mind you, I had more or less exactly the same objections to Lisp's 
syntax about one and a half year ago. Now, I don't see any language out 
there that nearly provides the same level of usability than Lisp, 
exactly because of its regular syntax "full of parentheses". It's far 
prettier and easier to read than languages whose syntaxes are based on 
some unreflected, purely aesthetical choices.


Pascal
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmqr0v$4u5$1@news-int2.gatech.edu>
> Obviously, you haven't tried to actually program in Lisp. Getting used
> to the syntax is a matter of one or two weeks at most of actual coding,
> provided you use a decent editor that supports parenthesis highlighting
> and automatic indentation.
I'd have to concur with this one. Parenthesized-prefix syntax is rather
pretty. What I like is the flexibility in code layout. Ex:

(defun foo (x)
        ...long function definition here...)

and

int foo(int x) 
{
        ...long function definition here...
}

Are equally natural in their respective syntaxes. However, if you have a
short, simple function:

(defun foo (x) (+ x 2)) 

is still perfectly natural, while:

int foo(int x) { return x + 2; }

looks a little weird. Most people would write the above similarly to the
first example, which makes it much longer. Block-structured languages in
general tend to suffer from this problem.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <pan.2003.10.18.15.07.31.105348@knm.org.pl>
On Sat, 18 Oct 2003 03:42:23 +0000, Rayiner Hashem wrote:

> (defun foo (x) (+ x 2))
> 
> is still perfectly natural, while:
> 
> int foo(int x) { return x + 2; }
> 
> looks a little weird.

I write 'int foo(int x) {return x + 2;}' when I have to write in C,
although I agree that many people always put {}'s contents in separate
lines. In OCaml it's 'let foo x = x + 2' and nobody would split it into
lines, so it's definitely not because of parenthesized-prefix vs. other
syntaxes - rather just a tradition of C.

OTOH Lisp syntax usually takes more horizontal space than Haskell, OCaml,
Ruby or Python (more parentheses - e.g. in 'let', spaces around all
operators, #'(lambda ...) versus \... or fun ... or {...}, no compact
record.field and sequence[index] syntaxes, no pattern matching, more
awkward dealing with multiple values to return). Horizontal space turns
vertical when lines get too long.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmkad1$2a8$3@newsreader2.netcologne.de>
Marcin 'Qrczak' Kowalczyk wrote:

 > Because these hard-coded syntaxes are prettier than the extensible Lisp
 > syntax full of parentheses.


Obviously, you haven't tried to actually program in Lisp. Getting used 
to the syntax is a matter of one or two weeks at most of actual coding, 
provided you use a decent editor that supports parenthesis highlighting 
and automatic indentation.

Despising Lisp because of its syntax is like thinking that Japanese is a 
too complicated language because it doesn't use latin characters.


Mind you, I had more or less exactly the same objections to Lisp's 
syntax about one and a half year ago. Now, I don't see any language out 
there that nearly provides the same level of usability than Lisp, 
exactly because of its regular syntax "full of parentheses". It's far 
prettier and easier to read than languages whose syntaxes are based on 
some unreflected, purely aesthetical choices.


Pascal


> 
From: Daniel Silva
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <Pine.GSO.4.58.0310031815040.3468@denali.ccs.neu.edu>
On Fri, 3 Oct 2003, MetalOne wrote:
> I am just barely familiar with Lisp and Scheme.  However, I always
> find comments like the above interesting.  I have seen other people
> make this claim also.
> However, from an earlier post on comp.lang.python comparing a simple
> loop.
>
> Scheme
> (define vector-fill!
>   (lambda (v x)
>     (let ((n (vector-length v)))
>       (do ((i 0 (+ i 1)))
>           ((= i n))
>           (vector-set! v i x)))))
>
> Python
> def vector_fill(v, x):
>     for i in range(len(v)):
>         v[i] = x
>
> To me the Python code is easier to read, and I can't possibly fathom
> how somebody could think the Scheme code is easier to read.  It truly
> boggles my mind.
>

I'd prefer one of these two implementations myself:

(define (vector-fill! v x)
  (let loop ([i (sub1 (vector-length v))])
     (unless (< i 0)
       (vector-set! v i x)
       (loop (sub1 i)))))

(define (vector-fill-again! v x)
  (for-each (lambda (i)
              (vector-set! v i x))
            (build-list (vector-length v) identity)))


The second one actually does almost exactly what the Python version does,
other than creating a lambda and mapping identity across range(len(v)).

If you want to use macros to make a for-each that does just what your
example asks for:


(define-syntax (for stx)
  (syntax-case stx ()
    [(_ idx lst exp) #`(for-each (lambda (idx)
                                   exp)
                                 lst)]))

And given a function range that does the same thing:

(define (range r)
  (build-list r identity))

Now you have the same for loop:

(define (my-vector-fill! v x)
  (for i (range (vector-length v))
       (vector-set! v i x)))


- Daniel
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m31xtu2cqf.fsf@javamonkey.com>
···@iteris.com (MetalOne) writes:

> ······@lycos.com (Mark Brady) wrote in message news:<····························@posting.google.com>...
> > Personally I find Scheme and Common Lisp easier to read but that's
> > just me, I prefer S-exps ...
> 
> I am just barely familiar with Lisp and Scheme. However, I always
> find comments like the above interesting. I have seen other people
> make this claim also. However, from an earlier post on
> comp.lang.python comparing a simple loop.
> 
> Scheme
> (define vector-fill!
>   (lambda (v x)
>     (let ((n (vector-length v)))
>       (do ((i 0 (+ i 1)))
>           ((= i n))
>           (vector-set! v i x)))))
> 
> Python
> def vector_fill(v, x):
>     for i in range(len(v)):
>         v[i] = x
> 
> To me the Python code is easier to read, and I can't possibly fathom
> how somebody could think the Scheme code is easier to read. It truly
> boggles my mind.

Well, over in comp.lang.lisp (where we speak Common Lisp, more so than
Scheme) we might write that:

  (defun vector-fill (v x)
    (dotimes (i (length v)) (setf (aref v i) x)))

or 

  (defun vector-fill (v x)
    (loop for i below (length v)
          do (setf (aref v i) x)))  (defun vector-fill (v x)


which seems pretty similar to the Python version.

(If of course we didn't already have the FILL function that does just
that.)

> The second thing that puzzles me is the usage of the LISP macro
> system. This system is touted as one of LISPs major strengths. I
> believe the "Do" above is a macro. Is that the best syntax that can
> be achieved with a macro for "Do".

Nope. Common Lisp includes the standard macros DOTIMES and LOOP as
shown above.

> I would think there would already be macros to write the Scheme code
> above in a format similar to the Python code below, or some more
> readable syntax. I have looked for repositories of such macros and I
> can't find any.

I'm sure the Scheme folks will tell you were you can find such
repositories for Scheme. But Common Lisp has them built in.

> This leads me to think that in practice LISP macros are not used.

That is decidedly not true of Common Lisp.

> Couple this with the fact that LISP programmers seem happier with
> S-exprs, and I can't see why a LISP programmer would even want to
> write a macro.

Well, macros aren't intended to get you away from s-exps though the
LOOP macro does to a certain extent. They are just intended to get you
to more to-the-point s-exps. You put your finger right on it when you
wondered why there wasn't a better way to write your loop than DO. If
DOTIMES didn't already exist, you'd write it as a macro that expands
into DO. That is: DO is a almost completely general looping construct
which makes it more than you want in a lot of situations. Macros let
you turn what you want to write (DOTIMES) into the right version of
the more general, more powerful construct (DO).

> I have tried on 3 occassions to become a LISP programmer, based upon
> the constant touting of LISP as a more powerful language and that
> ultimately S-exprs are a better syntax. Each time, I have been
> stopped because the S-expr syntax makes we want to vomit.

Hmmm. If all three of those times have been with Scheme, you might
want to try Common Lisp for a change of pace.

> If a set of macros could be written to improve LISP syntax, then I
> think that might be an amazing thing.  An interesting question to me
> is why hasn't this already been done.

Some (including me) would argue it has. They just don't define
"improve" as "get rid of all sexps".

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Paolo Amoroso
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <871xtt5pbj.fsf@plato.moon.paoloamoroso.it>
[followup to comp.lang.lisp only]

Peter Seibel writes:

>   (defun vector-fill (v x)
>     (dotimes (i (length v)) (setf (aref v i) x)))

I personally prefer:

  (defun vector-fill (v x)
    (dotimes (i (length v))
      (setf (aref v i) x)))


Paolo
-- 
Paolo Amoroso <·······@mclink.it>
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsy8w0hlvo.fsf@black132.ex.ac.uk>
[comp.lang.functional removed]
Peter Seibel <·····@javamonkey.com> writes:

> which seems pretty similar to the Python version.
> 
> (If of course we didn't already have the FILL function that does just
> that.)

Just for the record, in python all you'd write is: v[:] = a

'as
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <gzFfb.167106$hE5.5619423@news1.tin.it>
Alexander Schmolck wrote:

> [comp.lang.functional removed]
> Peter Seibel <·····@javamonkey.com> writes:
> 
>> which seems pretty similar to the Python version.
>> 
>> (If of course we didn't already have the FILL function that does just
>> that.)
> 
> Just for the record, in python all you'd write is: v[:] = a
> 
> 'as

I suspect you may intend "v[:] = [a]*len(v)", although a good alternative
may also be "v[:] = itertools.repeat(a, len(v))".


Alex
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfs7k3hgl27.fsf@black132.ex.ac.uk>
Alex Martelli <·····@aleax.it> writes:

> Alexander Schmolck wrote:
> > Just for the record, in python all you'd write is: v[:] = a
> I suspect you may intend "v[:] = [a]*len(v)", although a good alternative
> may also be "v[:] = itertools.repeat(a, len(v))".

Thanks for the correction (I sent this one of prematurely and then the network
broke down for 2 days).

``v[:] = a`` will actually work fine on Numeric/numarray arrays (thanks to
broadcasting), and presumably this scenario will occur more often in more in
pratice than the need to similarly destructively fill a (python) list (of
course Numeric/numarray are currently add-on's but I'd guess they'll make it
into python core eventually). In either case, as you demonstrate above there
is no need to write a for loop.

'as
From: Grzegorz Chrupala
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8b9e2260.0310032317.72abd86a@posting.google.com>
···@iteris.com (MetalOne) wrote in message news:<····························@posting.google.com>...
> Scheme
> (define vector-fill!
>   (lambda (v x)
>     (let ((n (vector-length v)))
>       (do ((i 0 (+ i 1)))
>           ((= i n))
>           (vector-set! v i x)))))
> 
> Python
> def vector_fill(v, x):
>     for i in range(len(v)):
>         v[i] = x
> 
> To me the Python code is easier to read, and I can't possibly fathom
> how somebody could think the Scheme code is easier to read.  It truly
> boggles my mind.

Pick a construct your pet language has specialized support, write an
ugly equivalent in a language that does not specifically support it
and you have proved your pet language to be superior to the other
language. (I myself have never used the "do" macro in Scheme and my
impression is few people do. I prefer "for-each", named "let" or the
CL-like "dotimes" for looping).
The point is if you want you can easily implement something like
"range" in Scheme (as shown by other posters). It would be more
illustrative choose an area where one of the languages is inherently
underpowered. For example I was shocked at how awkward Paul Graham's
"accumulator generator" snippet is in Python:

class foo:
                        def __init__(self, n):
                            self.n = n
                        def __call__(self, i):
                            self.n += i
                            return self.n


> If a set of macros could be written to improve LISP syntax, then I
> think that might be an amazing thing.  An interesting question to me
> is why hasn't this already been done.

There are libraries that let you write Scheme in Python-like
indentation syntax (<URL:http://cliki.tunes.org/Scheme>, look for
Alternative Syntaxes). However, they are not widely used.

Cheers,
--
Grzegorz
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <VMvfb.164318$hE5.5520220@news1.tin.it>
Grzegorz Chrupala wrote:
   ...
> class foo:
>                         def __init__(self, n):
>                             self.n = n
>                         def __call__(self, i):
>                             self.n += i
>                             return self.n

some might prefer:

def foo(n):
    tot = [n]
    def acc(i):
        tot[0] += i
        return tot[0]
    return acc

which is roughly equivalent.  It's true that most Pythonistas prefer to
use class instances, rather than closures, in order to group together
some state and some behavior, and the language favours that; and Python
separates expressions and statements quite firmly, so one just can't
increment-and-return in one stroke, nor define-and-return-function ditto.
But I don't see how these issues spell "awkwardness" in this case.


Alex
From: Bengt Richter
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blm34i$l6s$0@216.39.172.122>
On 4 Oct 2003 00:17:30 -0700, ········@pithekos.net (Grzegorz Chrupala) wrote:

>···@iteris.com (MetalOne) wrote in message news:<····························@posting.google.com>...
>> Scheme
>> (define vector-fill!
>>   (lambda (v x)
>>     (let ((n (vector-length v)))
>>       (do ((i 0 (+ i 1)))
>>           ((= i n))
>>           (vector-set! v i x)))))
>> 
>> Python
>> def vector_fill(v, x):
>>     for i in range(len(v)):
>>         v[i] = x
>> 
I guess you could also just write

    v[:] = [x]*len(v)

instead of calling a function (though it takes more space), e.g.,

 >>> v=range(10)
 >>> id(v),v
 (9442064, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
 >>> v[:] = [55]*len(v)
 >>> id(v),v
 (9442064, [55, 55, 55, 55, 55, 55, 55, 55, 55, 55])

using id(v) to show that the same object is mutated.

>> To me the Python code is easier to read, and I can't possibly fathom
>> how somebody could think the Scheme code is easier to read.  It truly
>> boggles my mind.
>
>Pick a construct your pet language has specialized support, write an
>ugly equivalent in a language that does not specifically support it
>and you have proved your pet language to be superior to the other
>language. (I myself have never used the "do" macro in Scheme and my
>impression is few people do. I prefer "for-each", named "let" or the
>CL-like "dotimes" for looping).
>The point is if you want you can easily implement something like
>"range" in Scheme (as shown by other posters). It would be more
>illustrative choose an area where one of the languages is inherently
>underpowered. For example I was shocked at how awkward Paul Graham's
>"accumulator generator" snippet is in Python:
>
>class foo:
>                        def __init__(self, n):
>                            self.n = n
>                        def __call__(self, i):
>                            self.n += i
>                            return self.n
>
Do you like this better?

 >>> def foo(n):
 ...     box = [n]
 ...     def foo(i): box[0]+=i; return box[0]
 ...     return foo
 ...
 >>> bar = foo(10)
 >>> bar(1)
 11
 >>> bar(2)
 13
 >>> bar(37)
 50
 >>> baz = foo(100)
 >>> bar(1), baz(23)
 (51, 123)

>
>> If a set of macros could be written to improve LISP syntax, then I
>> think that might be an amazing thing.  An interesting question to me
>> is why hasn't this already been done.
>
>There are libraries that let you write Scheme in Python-like
>indentation syntax (<URL:http://cliki.tunes.org/Scheme>, look for
>Alternative Syntaxes). However, they are not widely used.
>
>Cheers,
>--
>Grzegorz

Regards,
Bengt Richter
From: Grzegorz Chrupala
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8b9e2260.0310040524.229dfd9f@posting.google.com>
····@oz.net (Bengt Richter) wrote in message news:<············@216.39.172.122>...

> Do you like this better?
> 
>  >>> def foo(n):
>  ...     box = [n]
>  ...     def foo(i): box[0]+=i; return box[0]
>  ...     return foo
>  ...

It's still a hack that shows an area where Python has unnecessary
limitations, isn't it?
As Paul Graham says (<URL:http://www.paulgraham.com/icad.html>):

> Python users might legitimately ask why they can't just write
> 
> def foo(n):
>   return lambda i: return n += i 
> 
>  or even 
> 
> def foo(n):
>   lambda i: n += i
> 

Cheers,
-- Grzegorz
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <R2Dfb.166526$hE5.5598516@news1.tin.it>
Grzegorz Chrupala wrote:
   ...
>>  >>> def foo(n):
>>  ...     box = [n]
>>  ...     def foo(i): box[0]+=i; return box[0]
>>  ...     return foo
>>  ...
> 
> It's still a hack that shows an area where Python has unnecessary
> limitations, isn't it?

Debatable, and debated.  See the "Rebinding names in enclosing
scopes" section of http://www.python.org/peps/pep-0227.html .

Essentially, Guido prefers classes (and instances thereof) to
closures as a way to bundle state and behavior; thus he most
emphatically does not want to add _any_ complication at all,
when the only benefit would be to have "more than one obvious
way to do it".

Guido's generally adamant stance for simplicity has been the
key determinant in the evolution of Python.  Guido is also on
record as promising that the major focus in the next release
of Python where he can introduce backwards incompatibilities
(i.e. the next major-number-incrementing release, 3.0, perhaps,
say, 3 years from now) will be the _elimination_ of many of
the "more than one way to do it"s that have accumulated along
the years mostly for reasons of keeping backwards compatibility
(e.g., lambda, map, reduce, and filter, which Guido mildly
regrets ever having accepted into the language).


> As Paul Graham says (<URL:http://www.paulgraham.com/icad.html>):
> 
>> Python users might legitimately ask why they can't just write
>> 
>> def foo(n):
>>   return lambda i: return n += i

The rule Python currently use to determine whether a variable
is local is maximally simple: if the name gets bound (assigned
to) in local scope, it's a local variable.  Making this rule
*any* more complicated (e.g. to allow assignments to names in
enclosing scopes) would just allow "more than one way to do
it" (making closures a viable alternative to classes in more
cases) and therefore it just won't happen.  Python is about
offering one, and preferably only one, obvious way to do it,
for any value of "it".  And another key principle of the Zen
of Python is "simple is better than complex".

Anybody who doesn't value simplicity and uniformity is quite
unlikely to be comfortable with Python -- and this should
amply answer the question about the motivations for reason
number 1 why the above foo is unacceptable in Python (the
lambda's body can't rebind name n in an enclosing scope).

Python draws a firm distinction between expressions and
statements.  Again, the deep motivation behind this key
distinction can be found in several points in the Zen of
Python, such as "flat is better than nested" (doing away
with the expression/statement separation allows and indeed
encourages deep nesting) and "sparse is better than dense"
(that 'doing away' would encourage expression/statements
with a very high density of operations being performed).

This firm distinction should easily explain other reasons
why the above foo is unacceptable in Python: n+=i is a
statement (not an expression) and therefore it cannot be
held by a 'return' keyword; 'return' is a statement and
therefore cannot be in the body of a 'lambda' keyword.

>>  or even
>> 
>> def foo(n):
>>   lambda i: n += i

And this touches on yet another point of the Zen of Python:
explicit is better than implicit.  Having a function
implicitly return the last expression it computes would
violate this point (and is in fact somewhat error-prone,
in my experience, in the several languages that adopt
this rule).

Somebody who is unhappy with this drive for explicitness,
simplicity, uniformity, and so on, cannot be happy with
Python.  If he wants a very similar language from most
points of view, BUT with very different philosophies, he
might well be quite happy with Ruby.  Ruby does away with
any expression/statement distinction; it makes the 'return'
optional, as a method returns the last thing it computes;
it revels in "more than one way to do it", clever and cool
hacks, not perhaps to the extent of Perl, but close enough.

In Ruby, the spaces of methods and data are separate (i.e.,
most everything is "an object" -- but, differently from
Python, methods are not objects in Ruby), and I do not
think, therefore, that you can write a method that builds
and returns another method, and bind the latter to a name --
but you can return an object with a .call method, a la:

def outer(a) proc do |b| a+=b end end

x = outer(23)
puts x.call(100)   # emits 123
puts x.call(100)   # emits 223

[i.e., I can't think of any way you could just use x(100)
at the end of such a snippet in Ruby -- perhaps somebody
more expert of Ruby than I am can confirm or correct...?]
but apart from this it seems closer to what the above
quotes appear to be probing for.  In particular, it lets
you be MUCH, MUCH denser, if that is your purpose in life,
easily squeezing that outer function into a (short) line.
Python is NOT about making code very dense, indeed, as
above mentioned, it sees _sparseness_ as a plus; a typical
Pythonista would cringe at the density of that 'outer'
and by contrast REVEL at the "sparsity" and "explicitness"
(due to the many names involved:-) of, e.g.:

def make_accumulator(initial_value):
    accumulator = Bunch(value=initial_value)
    def accumulate(addend):
        accumulator.value += addend
        return accumulator.value
    return accumulate

accumulate = make_accumulator(23)
print accumulate(100)   # emits 123
print accumulate(100)   # emits 223


(using the popular Bunch class commonly defined as:
    class Bunch(object):
        def __init__(self, **kwds):
            self.__dict__.update(kwds)
).  There is, of course, a cultural gulf between this
verbose 6-liner [using an auxiliary class strictly for
reasons of better readability...!] and the terse Ruby 
1-liner above, and no doubt most practitioners of both
languages would in practice choose intermediate levels,
such as un-densifying the Ruby function into:


def outer(a)
  proc do |b|
    a+b
  end
end

or shortening/densifying the Python one into:

def make_accumulator(a):
    value = [a]
    def accumulate(b):
        value[0] += b
        return value[0]
    return accumulate

but I think the "purer" (more extreme) versions are
interesting "tipizations" for the languages, anyway.


Alex
From: Jens Axel Søgaard
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F7F0236.30309@jasoegaard.dk>
Alex Martelli wrote:

> Essentially, Guido prefers classes (and instances thereof) to
> closures as a way to bundle state and behavior; thus he most
> emphatically does not want to add _any_ complication at all,
> when the only benefit would be to have "more than one obvious
> way to do it".
> 
> Guido's generally adamant stance for simplicity has been the
> key determinant in the evolution of Python.  

The following is taken from  "All Things Pythonic - News from Python UK"
written by Guido van Rossum April 17, 
<2003:http://www.artima.com/weblogs/viewpost.jsp?thread=4550>

   During Simon's elaboration of an example (a type-safe printf function)
   I realized the problem with functional programming: there was a simple
   programming problem where a list had to be transformed into a
   different list. The code to do this was a complex two-level lambda
   expression if I remember it well, and despite Simon's lively
   explanation (he was literally hopping around the stage making
   intricate hand gestures to show how it worked) I failed to "get" it. I
   finally had to accept that it did the transformation without
   understanding how it did it, and this is where I had my epiphany about
   loops as a higher level of abstraction than recursion - I'm sure that
   the same problem would be easily solved by a simple loop in Python,
   and would leave no-one in the dark about what it did.

Hmm.

-- 
Jens Axel S�gaard
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ad8f2090.fsf@comcast.net>
Alex Martelli <·····@aleax.it> writes:

> Python draws a firm distinction between expressions and
> statements.  Again, the deep motivation behind this key
> distinction can be found in several points in the Zen of
> Python, such as "flat is better than nested" (doing away
> with the expression/statement separation allows and indeed
> encourages deep nesting) and "sparse is better than dense"
> (that 'doing away' would encourage expression/statements
> with a very high density of operations being performed).

Having written macros and higher-order code in languages that make a
firm distinction between expressions and statements, I can tell you
from experience that doing so doubles the amount of higher-order code.

The issue is that the higher-order code may expand in either a
statement or an expression context, and the key mechanism for
returning a value, the RETURN expression, is *required* in one
context, but *forbidden* in the other.  Additionally, whether a code
fragment is an expression or statement is usually implicit (depends on
what context it is used in), and therefore not available to the
higher-order code.  The end result is you write two of everything, one
that returns a result, one that does not.

I think the Zen of Python can be summed up as
  `Guido's style is better than yours'
 
From: Lulu of the Lotus-Eaters
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065288850.20400.python-list@python.org>
········@pithekos.net (Grzegorz Chrupala) wrote previously:
|shocked at how awkward Paul Graham's "accumulator generator" snippet is
|in Python:
|class foo:
|   def __init__(self, n):
|       self.n = n
|   def __call__(self, i):
|       self.n += i
|       return self.n

Me too.  The way I'd do it is probably a lot closer to the way Schemers
would do it:

    >>> def foo(i, accum=[0]):
    ...     accum[0]+=i
    ...     return accum[0]
    ...
    >>> foo(1)
    1
    >>> foo(3)
    4

Shorter, and without an awkward class.

Yours, David...

--
Buy Text Processing in Python: http://tinyurl.com/jskh
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <·····@gnosis.cx> ]--------------------------
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-2AD3A9.11220204102003@news.service.uci.edu>
In article <····································@python.org>,
 Lulu of the Lotus-Eaters <·····@gnosis.cx> wrote:

> ········@pithekos.net (Grzegorz Chrupala) wrote previously:
> |shocked at how awkward Paul Graham's "accumulator generator" snippet is
> |in Python:
> |class foo:
> |   def __init__(self, n):
> |       self.n = n
> |   def __call__(self, i):
> |       self.n += i
> |       return self.n
> 
> Me too.  The way I'd do it is probably a lot closer to the way Schemers
> would do it:
> 
>     >>> def foo(i, accum=[0]):
>     ...     accum[0]+=i
>     ...     return accum[0]
>     ...
>     >>> foo(1)
>     1
>     >>> foo(3)
>     4
> 
> Shorter, and without an awkward class.

There's an important difference between these two: the object-based 
solution (and the solutions with two nested functions and a closure) 
allow more than one accumulator to be created.  Yours only creates a 
one-of-a-kind accumulator.

I happen to like the object-based solution better.  It expresses more 
clearly to me the intent of the code.  I don't find the class awkward; 
to me, a class is what you use when you want to keep some state around, 
which is exactly the situation here.  "Explicit is better than 
implicit."  Conciseness is not always a virtue.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <t_Dfb.225088$R32.7238989@news2.tin.it>
Lulu of the Lotus-Eaters wrote:

> ········@pithekos.net (Grzegorz Chrupala) wrote previously:
> |shocked at how awkward Paul Graham's "accumulator generator" snippet is
> |in Python:
> |class foo:
> |   def __init__(self, n):
> |       self.n = n
> |   def __call__(self, i):
> |       self.n += i
> |       return self.n
> 
> Me too.  The way I'd do it is probably a lot closer to the way Schemers
> would do it:
> 
>     >>> def foo(i, accum=[0]):
>     ...     accum[0]+=i
>     ...     return accum[0]
>     ...
>     >>> foo(1)
>     1
>     >>> foo(3)
>     4
> 
> Shorter, and without an awkward class.

There's an important difference: with your approach, you cannot just
instantiate multiple independent accumulators like with the other --
    a = foo(10)
    b = foo(23)
in the 'class foo' approach, just as in all of those where foo returns an
inner-function instance, a and b are now totally independent accumulator
callables -- in your approach, 'foo' itself is the only 'accumulator
callable', and a and b after these two calls are just two numbers.

Making a cookie, and making a cookie-cutter, are quite different issues.


Alex
From: Sander Vesik
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1065306143.899745@haldjas.folklore.ee>
In comp.lang.scheme Grzegorz Chrupala <········@pithekos.net> wrote:
> ···@iteris.com (MetalOne) wrote in message news:<····························@posting.google.com>...
>> Scheme
>> (define vector-fill!
>>   (lambda (v x)
>>     (let ((n (vector-length v)))
>>       (do ((i 0 (+ i 1)))
>>           ((= i n))
>>           (vector-set! v i x)))))
>> 
>> Python
>> def vector_fill(v, x):
>>     for i in range(len(v)):
>>         v[i] = x
>> 
>> To me the Python code is easier to read, and I can't possibly fathom
>> how somebody could think the Scheme code is easier to read.  It truly
>> boggles my mind.
> 
> Pick a construct your pet language has specialized support, write an
> ugly equivalent in a language that does not specifically support it
> and you have proved your pet language to be superior to the other
> language. (I myself have never used the "do" macro in Scheme and my
> impression is few people do. I prefer "for-each", named "let" or the
> CL-like "dotimes" for looping).

Whiile true, if solving a problem requires you to use a lot of constructs
that one language provides and for which youave to do lots of extra work 
in teh other, one might aswell take the pragmatic approach that the other
language is better for the given problem at hand.

> 
> Cheers,
> --
> Grzegorz

-- 
	Sander

+++ Out of cheese error +++
From: Frode Vatvedt Fjeld
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <2h65j69d1k.fsf@vserver.cs.uit.no>
···@iteris.com (MetalOne) writes:

> [..] However, from an earlier post on comp.lang.python comparing a
> simple loop.
>
> Scheme
> (define vector-fill!
>   (lambda (v x)
>     (let ((n (vector-length v)))
>       (do ((i 0 (+ i 1)))
>           ((= i n))
>           (vector-set! v i x)))))
>
> Python
> def vector_fill(v, x):
>     for i in range(len(v)):
>         v[i] = x
>
> To me the Python code is easier to read, and I can't possibly fathom
> how somebody could think the Scheme code is easier to read.  It truly
> boggles my mind. [..]

The scheme example can only have been written by someone who is on the
outset determined to demonstrate that sexp-syntax is complicated. This
is how I'd write it in Common Lisp:

  (defun vector-fill (v x)
    (dotimes (i (length v))
      (setf (aref v i) x)))

As you can see, it matches the python example quite closely.

> [..] If a set of macros could be written to improve LISP syntax,
> then I think that might be an amazing thing.  An interesting
> question to me is why hasn't this already been done.

Lisp macros and syntactic abstractions are one of those things whose
power and elegance it is somewhat hard to explain to those who have
not experienced it themselves first hand. Paul Graham's book "On Lisp"
is considered by many to be a good introduction to the subject.

I am quite comforatble with Common Lisp's syntax, and I see no
particular need for some set of macros to improve its syntax. In fact
I have no idea what so ever as to what such a set of macros would look
like.

-- 
Frode Vatvedt Fjeld
From: MetalOne
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <92c59a2c.0310040919.7f926e79@posting.google.com>
Thanks for everybody's responses.  I found them quite informative.
From: Alan Crowe
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8665j5dyse.fsf@cawtech.freeserve.co.uk>
MetalOne wrote
> If a set of macros could be written to improve LISP
> syntax, then I think that might be an amazing thing.  An
> interesting question to me is why hasn't this already been
> done.

I think the issue is the grandeur of the Lisp vision. More
ambitious projects require larger code bases. Ambition is
hard to quantify. Nevertheless one must face the issue of
scaling. Does code size go as the cube of ambition, or is it
the fourth power of ambition? Or something else entirely.

Lisp aspires to change the exponent, not the constant
factor. The constant factor is very important. That is why
CL has FILL :-) but shrinking the constant factor has been
done (and with C++ undone).

Macros can be used to abbreviate code. One can spot that one
is typing similar code over and over again. One says
"whoops, I'm typing macro expansions". Do you use macros to
tune the syntax, so that you type N/2 characters instead of
N characters, or do you capture the whole concept in macro
and eliminate the repetition altogether?

The point is that there is nowhere very interesting to go
with syntax tuning. It is the bolder goal of changing the
exponent, and thus seriously enlarging the realm of the
possible, that excites.

Alan Crowe
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <7k3io36p.fsf@ccs.neu.edu>
Alan Crowe <····@cawNOtech.freeSPAMserve.co.uk> writes:

> Macros can be used to abbreviate code. One can spot that one
> is typing similar code over and over again. One says
> "whoops, I'm typing macro expansions". Do you use macros to
> tune the syntax, so that you type N/2 characters instead of
> N characters, or do you capture the whole concept in macro
> and eliminate the repetition altogether?

It depends.

I have a rather hairy system I'm working on and there are places where
I have to define and register certain things in certain ways.  By using
a rather trivial macro, I can write code like this:

(defmumble foo #x3FAE)
(defmumble bar #x3FAF)
...

The power in doing this is not in the abbreviated typing, though.  The
power is when a junior programmer is assigned to update the mumble
list to include the new token XYZ which is supposed to be #x4801.
I could trust virtually *any* reasonable computer person to maintain
the mumble list, even if they have no familiarity with lisp.  I don't
even have to ask them to document the code:  it is literally
self-documenting.

> The point is that there is nowhere very interesting to go
> with syntax tuning.  It is the bolder goal of changing the
> exponent, and thus seriously enlarging the realm of the
> possible, that excites.

As a language designer, I agree that tiny syntax changes aren't all
that challenging.  As a system designer, though, it is quite useful
to change the slope of the learning curve, even if it does not change
the power of the language.
From: Mario S. Mommer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <fz3ce8u87s.fsf@cupid.igpm.rwth-aachen.de>
···@iteris.com (MetalOne) writes:
> I have tried on 3 occassions to become a LISP programmer, based upon
> the constant touting of LISP as a more powerful language and that
> ultimately S-exprs are a better syntax.  Each time, I have been
> stopped because the S-expr syntax makes we want to vomit.

:-)

Although people are right when they say that S-exprs are simpler, and
once you get used to them they are actually easier to read, I think
the visual impact they have on those not used to it is often
underestimated.

And to be honest, trying to deal with all these parenthesis in an
editor which doesn't help you is not an encouraging experience, to say
the least. You need at least a paren-matching editor, and it is a real
big plus if it also can reindent your code properly. Then, very much
like in python, the indent level tells you exactly what is happening,
and you pretty much don't see the parens anymore.

Try it! In emacs, or Xemacs, open a file ending in .lisp and
copy/paste this into it:

;; Split a string at whitespace.
(defun splitatspc (str)
(labels ((whitespace-p (c)
(find c '(#\Space #\Tab #\Newline))))
(let* ((posnew -1)
(posold 0)
(buf (cons nil nil))
(ptr buf))
(loop while (and posnew (< posnew (length str))) do
(setf posold (+ 1 posnew))
(setf posnew (position-if #'whitespace-p str
:start posold))
(let ((item (subseq str posold posnew)))
(when (< 0 (length item))
(setf (cdr ptr) (list item))
(setf ptr (cdr ptr)))))
(cdr buf))))

Now place the cursor on the paren just in front of the defun in the
first line, and hit ESC followed by <ctrl-Q>.

> If a set of macros could be written to improve LISP syntax, then I
> think that might be an amazing thing.  An interesting question to me
> is why hasn't this already been done.

Because they are so damned regular. After some time you do not even
think about the syntax anymore.
From: Lothar Scholz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <6ee58e07.0310030647.7f53e154@posting.google.com>
Paul Rubin <·············@NOSPAM.invalid> wrote in message news:<··············@ruckus.brouhaha.com>...
> ·······@ziplip.com writes:
> > If the answer is yes, would many Python programmers switch to Lisp
> > or Scheme if they were offered identation-based syntax?
> 
> I don't think the syntax is that big a deal.  But programming in lisp
> or scheme has a creaky feeling these days, because the traditional
> runtime libraries in those languages have fallen so far behind the
> times.

Funny. Yesterday i downloaded the trial version of Franz Lisp (Allegro
CL).
I can'T say if the runtime libraries are out of date because there is
absolute no documentation for the runtime libraries - of course they
also bundle the ANSI-Common Lisp book.

I found that they still want to sell every fucking line of code in an
extra library raising the price to an unexceptable high value.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3cea3gqq.fsf@comcast.net>
·······@ziplip.com writes:

> I think everyone who used Python will agree that its syntax is
> the best thing going for it. 

I've used Python.  I don't agree.

> It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while 
> keeping its amazing syntax, and if it could be possible to
> add Pythonistic syntax to Lisp or Scheme, while keeping all
> of the functionality and convenience. If the answer is yes,
> would many Python programmers switch to Lisp or Scheme if
> they were offered identation-based syntax?

Yes, you would be able to add macros to Python.  No, it isn't anywhere
as easy as it is with Lisp.

I imagine you could come up with a readtable hack for reading
pythonesque syntax in lisp.  *shudder*
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsbrsyi505.fsf@black132.ex.ac.uk>
·············@comcast.net writes:

> ·······@ziplip.com writes:
> 
> > I think everyone who used Python will agree that its syntax is
> > the best thing going for it. 
> 
> I've used Python.  I don't agree.

I'd be interested to hear your reasons. *If* you take the sharp distinction
that python draws between statements and expressions as a given, then python's
syntax, in particular the choice to use indentation for block structure, seems
to me to be the best choice among what's currently on offer (i.e. I'd claim
that python's syntax is objectively much better than that of the C and Pascal
descendants -- comparisons with smalltalk, prolog or lisp OTOH are an entirely
different matter).

'as
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <he2qdv4y.fsf@ccs.neu.edu>
Alexander Schmolck <··········@gmx.net> writes:

> ·············@comcast.net writes:
>
>> ·······@ziplip.com writes:
>> 
>> > I think everyone who used Python will agree that its syntax is
>> > the best thing going for it. 
>> 
>> I've used Python.  I don't agree.
>
> I'd be interested to hear your reasons. *If* you take the sharp distinction
> that python draws between statements and expressions as a given, then python's
> syntax, in particular the choice to use indentation for block structure, seems
> to me to be the best choice among what's currently on offer (i.e. I'd claim
> that python's syntax is objectively much better than that of the C and Pascal
> descendants -- comparisons with smalltalk, prolog or lisp OTOH are an entirely
> different matter).

(I'm ignoring the followup-to because I don't read comp.lang.python)

Indentation-based grouping introduces a context-sensitive element into
the grammar at a very fundamental level.  Although conceptually a
block is indented relative to the containing block, the reality of the
situation is that the lines in the file are indented relative to the
left margin.  So every line in a block doesn't encode just its depth
relative to the immediately surrounding context, but its absolute
depth relative to the global context.  Additionally, each line encodes
this information independently of the other lines that logically
belong with it, and we all know that when some data is encoded in one
place may be wrong, but it is never inconsistent.

There is yet one more problem.  The various levels of indentation
encode different things: the first level might indicate that it is
part of a function definition, the second that it is part of a FOR
loop, etc.  So on any line, the leading whitespace may indicate all
sorts of context-relevant information.  Yet the visual representation
is not only identical between all of these, it cannot even be
displayed.

Is this worse than C, Pascal, etc.?  I don't know.  
Worse than Lisp, Forth, or Smalltalk?  Yes.
From: Ingvar Mattsson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87r81qogs6.fsf@gruk.tech.ensign.ftech.net>
Joe Marshall <···@ccs.neu.edu> writes:

> Alexander Schmolck <··········@gmx.net> writes:
> 
> > ·············@comcast.net writes:
> >
> >> ·······@ziplip.com writes:
> >> 
> >> > I think everyone who used Python will agree that its syntax is
> >> > the best thing going for it. 
> >> 
> >> I've used Python.  I don't agree.
> >
> > I'd be interested to hear your reasons. *If* you take the sharp distinction
> > that python draws between statements and expressions as a given, then python's
> > syntax, in particular the choice to use indentation for block structure, seems
> > to me to be the best choice among what's currently on offer (i.e. I'd claim
> > that python's syntax is objectively much better than that of the C and Pascal
> > descendants -- comparisons with smalltalk, prolog or lisp OTOH are an entirely
> > different matter).
> 
> (I'm ignoring the followup-to because I don't read comp.lang.python)
> 
> Indentation-based grouping introduces a context-sensitive element into
> the grammar at a very fundamental level.  Although conceptually a
> block is indented relative to the containing block, the reality of the
> situation is that the lines in the file are indented relative to the
> left margin.  So every line in a block doesn't encode just its depth
> relative to the immediately surrounding context, but its absolute
> depth relative to the global context.  Additionally, each line encodes
> this information independently of the other lines that logically
> belong with it, and we all know that when some data is encoded in one
> place may be wrong, but it is never inconsistent.
> 
> There is yet one more problem.  The various levels of indentation
> encode different things: the first level might indicate that it is
> part of a function definition, the second that it is part of a FOR
> loop, etc.  So on any line, the leading whitespace may indicate all
> sorts of context-relevant information.  Yet the visual representation
> is not only identical between all of these, it cannot even be
> displayed.

It's actually even worse than you think. Imagine you want "blank
lines" in your code, so act as paragraph separators. Do these require
indentation, even though there is no code on them? If so, how does
that interact with a listener? From what I can tell, the option chosen
in the Python (the language) community, the listener and the file
reader have different view on blank lines. This makes it harder than
necessary to edit stuff in one window and "just paste" code from
another. Bit of a shame, really.

//ingvar
-- 
When it doesn't work, it's because you did something wrong.
Try to do it the right way, instead.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsekxog5gu.fsf@black132.ex.ac.uk>
Joe Marshall <···@ccs.neu.edu> writes:


> Alexander Schmolck <··········@gmx.net> writes:
> 
> > ·············@comcast.net writes:
> (I'm ignoring the followup-to because I don't read comp.lang.python)

Well, I supposed this thread has spiralled out of control already anyway:)
 
> Indentation-based grouping introduces a context-sensitive element into
> the grammar at a very fundamental level.  Although conceptually a
> block is indented relative to the containing block, the reality of the
> situation is that the lines in the file are indented relative to the
> left margin.  So every line in a block doesn't encode just its depth
> relative to the immediately surrounding context, but its absolute
> depth relative to the global context.  

I really don't understand why this is a problem, since its trivial to
transform python's 'globally context' dependent indentation block structure
markup into into C/Pascal-style delimiter pair block structure markup.

Significantly, AFAICT you can easily do this unambiguously and *locally*, for
example your editor can trivially perform this operation on cutting a piece of
python code and its inverse on pasting (so that you only cut-and-paste the
'local' indentation). Prima facie I don't see how you loose any fine control.

> Additionally, each line encodes this information independently of the other
> lines that logically belong with it, and we all know that when some data is
> encoded in one place may be wrong, but it is never inconsistent.

Sorry, I don't understand this sentence, but maybe you mean that the potential
inconsitency between human and machine interpretation is a *feature* for Lisp,
C, Pascal etc!? If so I'm really puzzled.

> There is yet one more problem. The various levels of indentation encode
> different things: the first level might indicate that it is part of a
> function definition, the second that it is part of a FOR loop, etc. So on
> any line, the leading whitespace may indicate all sorts of context-relevant
> information. 

I don't understand why this is any different to e.g. ')))))' in Lisp. The
closing ')' for DEFUN just looks the same as that for IF.

> Yet the visual representation is not only identical between all of these, it
> cannot even be displayed.

I don't understand what you mean. Could you maybe give a concrete example of
the information that can't be displayed? AFAICT you can have 'sexp'-movement,
markup and highlighting commands all the same with whitespace delimited block
structure.

> 
> Is this worse than C, Pascal, etc.?  I don't know.

I'm pretty near certain it is better: In Pascal, C etc. by and large block
structure delimitation is regulated in such a way that what has positive
information content for the human reader/programmer (indentation) has zero to
negative information content for the compiler and vice versa. This is a
remarkably bad design (and apart from cognitive overhead obviously also causes
errors).

Python removes this significant problem, at as far as I'm aware no real cost
and plenty of additional gain (less visual clutter, no waste of delimiter
characters ('{','}') or introduction of keywords that will be sorely missed as
user-definable names ('begin', 'end')).

In Lisp the situtation isn't quite as bad, because although most of the parens
are of course mere noise to a human reader, not all of them are and because of
lisp's simple but malleable syntactic structure a straighforward replacement
of parens with indendation would obviously result in unreadable code
(fragmented over countless lines and mostly in past the 80th column :).

So unlike C and Pascal where a fix would be relatively easy, you would need
some more complicated scheme in the case of Lisp and I'm not at all sure it
would be worth the hassle (especiallly given that efforts in other areas would
likely yield much higher gains).

Still, I'm sure you're familiar with the following quote (with which I most
heartily agree):

 "[P]rograms must be written for people to read, and only incidentally for
   machines to execute."

People can't "read" '))))))))'.

> Worse than Lisp, Forth, or Smalltalk?  Yes.

Possibly, but certainly not due to the use of significant whitespace. 


'as
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <wubg634p.fsf@comcast.net>
Alexander Schmolck <··········@gmx.net> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
>
>
>> Alexander Schmolck <··········@gmx.net> writes:
>> 
>> > ·············@comcast.net writes:
>> (I'm ignoring the followup-to because I don't read comp.lang.python)
>
> Well, I supposed this thread has spiralled out of control already anyway:)
>  
>> Indentation-based grouping introduces a context-sensitive element into
>> the grammar at a very fundamental level.  Although conceptually a
>> block is indented relative to the containing block, the reality of the
>> situation is that the lines in the file are indented relative to the
>> left margin.  So every line in a block doesn't encode just its depth
>> relative to the immediately surrounding context, but its absolute
>> depth relative to the global context.  
>
> I really don't understand why this is a problem, since its trivial to
> transform python's 'globally context' dependent indentation block structure
> markup into into C/Pascal-style delimiter pair block structure markup.

Of course it can.  Any unambiguous grammar has a parse tree.

> Significantly, AFAICT you can easily do this unambiguously and *locally*, for
> example your editor can trivially perform this operation on cutting a piece of
> python code and its inverse on pasting (so that you only cut-and-paste the
> 'local' indentation). Prima facie I don't see how you loose any fine control.

Only if your cut boundaries are at the same lexical level.  If you cut
across boundaries, it is no longer clear what should happen at the paste.

Also, it is frequently the case that you need to `tweak' the code after
you paste it.

>> Additionally, each line encodes this information independently of the other
>> lines that logically belong with it, and we all know that when some data is
>> encoded in one place may be wrong, but it is never inconsistent.
>
> Sorry, I don't understand this sentence, but maybe you mean that the potential
> inconsitency between human and machine interpretation is a *feature* for Lisp,
> C, Pascal etc!? If so I'm really puzzled.

You misunderstand me.  In a python block, two expressions are
associated with each other if they are the same distance from the left
edge.  This is isomorphic to having a nametag identifying the scope
of the line.  Lines are associated with each other iff they have the
same nametag.  Change one, and all must change.

If, instead, you use balanced delimiters, then a subexpression no
longer has to encode its position within the containing expression.

Let me demonstrate the isomorphism.  A simple python expression:
(grrr..   I cut and paste it, but it lost its indentation between
the PDF file and Emacs.  I hope I redo it right...)

def index(directory):
    # like os.listdir, but traverses directory trees
    stack = [directory]
    files = []
    while stack:
        directory = stack.pop()
        for file in os.listdir(directory):
            fullname = os.path.join(directory, file)
            files.append(fullname)
            if os.path.isdir(fullname) and not os.path.islink(fullname):
                stack.append(fullname)
    return files

Now the reason we know that `            files.append(fullname)' and
`            fullname = os.path.join(directory, file)' are part of the 
same block is because they both begin with 12 spaces.  The first
four spaces encode the fact that they belong to the same function,
the next four indicate that they belong in the while loop, and
the final four indicate that they belong in the for loop.
The `    return files', on the other hand, only has four spaces, so
it cannot be part of the while or for loop, but it is still part
of the function.  I can represent this same information as a code:

t   -def index(directory):
d   -    # like os.listdir, but traverses directory trees
d   -    stack = [directory]
d   -    files = []
d   -    while stack:
dw  -        directory = stack.pop()
dw  -        for file in os.listdir(directory):
dwf -            fullname = os.path.join(directory, file)
dwf -            files.append(fullname)
dwf -            if os.path.isdir(fullname) and not os.path.islink(fullname):
dwfi-                stack.append(fullname)
d   -    return files

The letter in front indicates what lexical group the line belongs to.  This
is simply a different visual format for the leading spaces.

Now, suppose that I wish to protect the body of the while statement
within a conditional.  Simply adding the conditional won't work:

d   -    while stack:
dw  -        if copacetic():
dw  -        directory = stack.pop()
dw  -        for file in os.listdir(directory):
dwf -            fullname = os.path.join(directory, file)
dwf -            files.append(fullname)
dwf -            if os.path.isdir(fullname) and not os.path.islink(fullname):
dwfi-                stack.append(fullname)

because the grouping information is replicated on each line, I have to
fix this information in the six different places it is encoded:

d    -    while stack:
dw   -        if copacetic():
dwi  -            directory = stack.pop()
dwi  -            for file in os.listdir(directory):
dwif -                fullname = os.path.join(directory, file)
dwif -                files.append(fullname)
dwif -                if os.path.isdir(fullname) and not os.path.islink(fullname):
dwifi-                    stack.append(fullname)
 
The fact that the information is replicated, and that there is nothing
but programmer discipline keeping it consistent is a source of errors.

>> There is yet one more problem. The various levels of indentation encode
>> different things: the first level might indicate that it is part of a
>> function definition, the second that it is part of a FOR loop, etc. So on
>> any line, the leading whitespace may indicate all sorts of context-relevant
>> information. 
>
> I don't understand why this is any different to e.g. ')))))' in Lisp. The
> closing ')' for DEFUN just looks the same as that for IF.

That is because the parenthesis *only* encode the grouping information,
they do not do double duty and encode what they are grouping.  The key
here is to realize that the words `DEFUN' and the `IF' themselves look 
very different.

>> Yet the visual representation is not only identical between all of these, it
>> cannot even be displayed.
>
> I don't understand what you mean. Could you maybe give a concrete example of
> the information that can't be displayed? 

Sure.  Here are five parens )))))  How much whitespace is there here:          

>
> Still, I'm sure you're familiar with the following quote (with which I most
> heartily agree):
>
>  "[P]rograms must be written for people to read, and only incidentally for
>    machines to execute."
>
> People can't "read" '))))))))'.

Funny, the people you just quoted would disagree with you about parenthesis.
I expect that they would disagree with you about whitespace as well.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <878ynw75yo.fsf@thalassa.informatimago.com>
·············@comcast.net writes:
> You misunderstand me.  In a python block, two expressions are
> associated with each other if they are the same distance from the left
> edge.  This is isomorphic to having a nametag identifying the scope
> of the line.  Lines are associated with each other iff they have the
> same nametag.  Change one, and all must change.

Exactly. What was  that language where you wrote  tags to indicate the
indenting of data structures:

      01  DREP.
          02  NO-REPR          PIC 9999.
          02  NO-SOTR          PIC 9999.
          02  NOM              PIC X(20).
          02  PRENOM           PIC X(15).
          02  A                PIC 9.
          02  B                PIC 9.
          02  FILLER           PIC X.
          02  D                PIC 9.
          02  FILLER           PIC X(33).
      01  DVTE.
          02  NO-SOTV          PIC 9999.
          02  NO-REPV          PIC 9999.
          02  MTV              PIC 9(6)V99.
          02  FILLER           PIC X(64).


> If, instead, you use balanced delimiters, then a subexpression no
> longer has to encode its position within the containing expression.
> [...]

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsbrsl6mq3.fsf@black132.ex.ac.uk>
·············@comcast.net writes:
> Suppose I cut just one arm of a conditional.  When I paste, it is
> unclear whether I intend for the code after the paste to be part of
> that arm, part of the else, or simply part of the same block.

Sorry, I have difficulties understanding what exactly you mean again. Would
you mind cutting and pasting something like the THEN/ELSE in the examples
below (say just marking the cut region with {}s and and where you'd like to
paste with @)?

(if CONDITION
    THEN
  ELSE)

if CONDITION:
   THEN
else:
   ELSE

> 
> >> The fact that the information is replicated, and that there is nothing
> >> but programmer discipline keeping it consistent is a source of errors.
> >
> > Sure there is. Your editor and immediate visual feedback (no need to remember
> > to reindent after making the semantic changes).
> 
> `immediate visual feedback' = programmer discipline
> Laxness at this point is a source of errors.

You got it backwards. 
Not forgetting to press 'M-C-\' = programmer discipline.
Laxness at this point is a source of errors. 

And indeed, people *do* have to be educated not to be lax when editing lisp -
newbies frequently get told in c.l.l or c.l.s that they should have reindented
their code because then they would have seen that they got their parens mixed
up.

OTOH, if you make an edit in python the result of this edit is immediately
obvious -- no mismatch between what you think it means and what your computer
thinks it means and thus no (extra) programmer discipline required.

Of course you need *some* basic level of discipline to not screw up your
source code when making edits -- but for all I can see at the moment (and know
from personal experience) it is *less* than what's required when you edit lisp
(I have provided a suggested way to edit this particular example in emacs for
python in my previous post -- you haven't provided an analoguous editing
operation for lisp with an explanation why it would be less error-prone)).


> >> >> Yet the visual representation is not only identical between all of these, it
> >> >> cannot even be displayed.
> >> >
> >> > I don't understand what you mean. Could you maybe give a concrete example of
> >> > the information that can't be displayed? 
> >> 
> >> Sure.  Here are five parens )))))  How much whitespace is there here:          
> >
> > 10 spaces (which BTW I counted in emacs in just the same way that I'd count a
> > similar number of parens) -- but what has counting random trailing whitespace
> > got to do with anything? 
> 
> It is simply an illustration that there is no obvious glyph associated
> with whitespace, and you wanted a concrete example of something that can't
> be displayed.

No, I didn't want just *any* example of something that can't be displayed; I
wanted an example of something that can't be displayed and is *pertinent* to
our discussion (based on the Quinean assumption that you wouldn't have brought
up "things that can't be displayed" if they were completely besides the
point).

me:
> >> > People can't "read" '))))))))'.
[more dialog snipped]
> I cannot read Abelson and Sussman's minds, but neither of them are
> ignorant of the vast variety of computer languages in the world.
> Nonetheless, given the opportunity to choose any of them for
> exposition, they have chosen lisp.  Sussman went so far as to
> introduce lisp syntax into his book on classical mechanics.

Well the version of SICM *I've* seen predeominantly seems to use (infixy) math
notation, so maybe Sussman is a little less confident in the perspicuousness
of his brainchild than you (also cf. Iverson)?

> Apparently he felt that not only *could* people read ')))))))', but
> that it was often *clearer* than the traditional notation.

Uhm, maybe we've got an different interpretation of 'read'?

If by 'read' you mean 'could hypothetically decipher', then yeah, sure with
enough effort and allowable margin of error, people can indeed 'read'
')))))))' and know that it amounts to 7 parens, and with even higher effort
and error margins they should even be able to figure out what each ')'
corresponds to.

I'm equally confident that you'd be in principle capable of 'deciphering' a
printout of my message in rot-13, modulo some errors.

I nontheless suspect I might hear complaints from you along the lines that
"couldn't read that" (if you had some reason to expect that its contents would
be of value to you in the first place).

I'm also pretty sure if I gave you version with each line accompagnied by its
rot-13 equivalent (and told you so) you'd just try to read the alphabetical
lines and ignore the rot-13 as noise (even if I told you that the rot-13 is
really the canonical version and the interspersed lines are just there for
visual convenience).

Now it's pretty much exactly the same for lisp code and trailing parens -- any
sane person in a normal setting will just try to ignore them as best as she
can and go by indentation instead -- despite the fact that doing so risks
misinterpreting the code, because the correspondence between parens and
indentation is unenforced and exists purely by convention (and lispers even
tend to have slightly different conventions, e.g. IF in CL/scheme) and C-M-\.

Reading *to me* means extracting the significant information from some written
representation and the ability to read is to do so with a reasonable amount of
effort. So in my diction, if a certain aspect of a written representation is
systematically and universally ignored by readers (at their peril) then surely
this aspect is unlikely to get points of maximum readability and one might
even conclude that people can't read so-and-so?

I don't personally think (properly formated) lisp reads that badly at all
(compared to say C++ or java) and you sure got the word-seperators right. But
to claim that using lisp-style parens are in better conformance with the
dictum above than python-style indentation frankly strikes me as a bit silly
(whatever other strengths and weaknesses these respective syntaxes might
have).


> Obviously the indentation.  
> But I'd notice the mismatch.

(Hmm, you or emacs?)
 
> If I gave you a piece of python code jotted down on paper that (as these
> hypothetical examples usually are) for some reason was of vital importance
> but I accidentally misplaced the indentation -- how would you know?

Excellent point. But -- wait! Were it Lisp, how would I know that you didn't
intend e.g.

  (if (bar watz) foo)

instead of 

  (if (bar) watz foo)

?

Like in so many fields of human endeavor, XML provides THE solution:

 <if><bar/>watz foo</if>

So maybe we should both switch to waterlang, eh? 


Moral: I really think your (stereoptypical) argument that the possibility of
inconsistency between "user interpretation" and "machine interpretation" of a
certain syntax is a feature (because it introduces redundancy that can can be
used for error detection) requires a bit more work.


'as

p.s:

[oh, just to demonstrate that large groups of trailing parens actually do
occur and that, as has been  mentioned, even perl has its uses]:

 /usr/share/emacs/> perl -ne '$count++ if m/\){7}/; END{print "$count\n";}' **/*el
 2008
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <n0c41ejb.fsf@comcast.net>
Alexander Schmolck <··········@gmx.net> writes:

> ·············@comcast.net writes:
>> Suppose I cut just one arm of a conditional.  When I paste, it is
>> unclear whether I intend for the code after the paste to be part of
>> that arm, part of the else, or simply part of the same block.
>
> Sorry, I have difficulties understanding what exactly you mean again. 

Let me back up here.  I originally said:

>> Every line in a block doesn't encode just its depth relative to the
>> immediately surrounding context, but its absolute depth relative to
>> the global context.

To which you replied:

> I really don't understand why this is a problem, since its trivial to
> transform python's 'globally context' dependent indentation block structure
> markup into into C/Pascal-style delimiter pair block structure markup.

> Significantly, AFAICT you can easily do this unambiguously and *locally*, for
> example your editor can trivially perform this operation on cutting a piece of
> python code and its inverse on pasting (so that you only cut-and-paste the
> 'local' indentation).

Consider this python code (lines numbered for exposition):

 1 def dump(st):
 2     mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime = st
 3     print "- size:", size, "bytes"
 4     print "- owner:", uid, gid
 5     print "- created:", time.ctime(ctime)
 6     print "- last accessed:", time.ctime(atime)
 7     print "- last modified:", time.ctime(mtime)
 8     print "- mode:", oct(mode)
 9     print "- inode/dev:", ino, dev
10
11 def index(directory):
12     # like os.listdir, but traverses directory trees
13     stack = [directory]
14     files = []
15     while stack:
16         directory = stack.pop()
17         for file in os.listdir(directory):
18             fullname = os.path.join(directory, file)
19             files.append(fullname)
20             if os.path.isdir(fullname) and not os.path.islink(fullname):
21                 stack.append(fullname)
22     return files

This code is to provide verisimilitude, not to actually run.  I wish
to show that local information is insufficient for cutting and pasting
under some circumstances.

If we were to cut lines 18 and 19 and to insert them between lines
4 and 5, we'd have this result: 

 3     print "- size:", size, "bytes"
 4     print "- owner:", uid, gid
18             fullname = os.path.join(directory, file)
19             files.append(fullname)
 5     print "- created:", time.ctime(ctime)
 6     print "- last accessed:", time.ctime(atime)

Where we can clearly see that the pasted code is at the wrong
indentation level.  It is also clear that in this case, the
editor could easily have determined the correct indentation.

But let us consider cutting lines 6 and 7 and putting them
between lines 21 and 22.  We get this: 

15     while stack:
16         directory = stack.pop()
17         for file in os.listdir(directory):
18             fullname = os.path.join(directory, file)
19             files.append(fullname)
20             if os.path.isdir(fullname) and not os.path.islink(fullname):
21                 stack.append(fullname)
 6     print "- last accessed:", time.ctime(atime)
 7     print "- last modified:", time.ctime(mtime)
22     return files

But it is unclear whether the intent was to be outside the while,
or outside the for, or part of the if.  All of these are valid: 

15     while stack:
16         directory = stack.pop()
17         for file in os.listdir(directory):
18             fullname = os.path.join(directory, file)
19             files.append(fullname)
20             if os.path.isdir(fullname) and not os.path.islink(fullname):
21                 stack.append(fullname)
 6         print "- last accessed:", time.ctime(atime)
 7         print "- last modified:", time.ctime(mtime)
22     return files

15     while stack:
16         directory = stack.pop()
17         for file in os.listdir(directory):
18             fullname = os.path.join(directory, file)
19             files.append(fullname)
20             if os.path.isdir(fullname) and not os.path.islink(fullname):
21                 stack.append(fullname)
 6             print "- last accessed:", time.ctime(atime)
 7             print "- last modified:", time.ctime(mtime)
22     return files

15     while stack:
16         directory = stack.pop()
17         for file in os.listdir(directory):
18             fullname = os.path.join(directory, file)
19             files.append(fullname)
20             if os.path.isdir(fullname) and not os.path.islink(fullname):
21                 stack.append(fullname)
 6                 print "- last accessed:", time.ctime(atime)
 7                 print "- last modified:", time.ctime(mtime)
22     return files

Now consider this `pseudo-equivalent' parenthesized code:

 1 (def dump (st)
 2    (destructuring-bind (mode ino dev nlink uid gid size atime mtime ctime) st
 3       (print "- size:" size "bytes")
 4       (print "- owner:" uid gid)
 5       (print "- created:" (time.ctime ctime))
 6       (print "- last accessed:" (time.ctime atime))
 7       (print "- last modified:" (time.ctime mtime))
 8       (print "- mode:" (oct mode))
 9       (print "- inode/dev:" ino dev)))
10
11 (def index (directory)
12     ;; like os.listdir, but traverses directory trees
13     (let ((stack directory)
14           (files '()))
15       (while stack
16         (setq directory (stack-pop))
17         (dolist (file (os-listdir directory))
18            (let ((fullname (os-path-join directory file)))
19              (push fullname files)
20              (if (and (os-path-isdir fullname) (not (os-path-islink fullname)))
21                  (push fullname stack)))))
22       files))

If we cut lines 6 and 7 with the intent of inserting them
in the vicinity of line 21, we have several options (as in python),
but rather than insert them incorrectly and then fix them, we have
the option of inserting them into the correct place to begin with.
In the line `(push fullname stack)))))', there are several close
parens that indicate the closing of the WHILE, DOLIST, LET, and IF,
assuming we wanted to include the lines in the DOLIST, but not
in the LET or IF, we'd insert here:
                                            V
21                  (push fullname stack)))   ))

The resulting code is ugly:

11 (def index (directory)
12     ;; like os.listdir, but traverses directory trees
13     (let ((stack directory)
14           (files '()))
15       (while stack
16         (setq directory (stack-pop))
17         (dolist (file (os-listdir directory))
18            (let ((fullname (os-path-join directory file)))
19              (push fullname files)
20              (if (and (os-path-isdir fullname) (not (os-path-islink fullname)))
21                  (push fullname stack)))
6       (print "- last accessed:" (time.ctime atime))
7       (print "- last modified:" (time.ctime mtime))))
22       files))

But it is correct.

(Incidentally inserting at that point is easy:  you move the cursor over
the parens until the matching one at the beginning of the DOLIST begins
to blink.  At this point, you know that you are at the same syntactic level
as the dolist.)

>> >> The fact that the information is replicated, and that there is nothing
>> >> but programmer discipline keeping it consistent is a source of errors.

Let me expand on this point.  The lines I cut are very similar to each
other, and very different from the lines where I placed them.  But
suppose they were not, and I had ended up with this:

19             files.append(fullname)
20             if os.path.isdir(fullname) and not os.path.islink(fullname):
21                 stack.append(fullname)
 6     print "- last accessed:", time.ctime(atime)
 7     print "- last modified:", time.ctime(mtime)
22     print "- copacetic"
23     return files

Now you can see that lines 6 and 7 ought to be re-indented, but line 22 should
not.  It would be rather easy to either accidentally group line seven with
line 22, or conversely line 22 with line 7. 

>> > Sure there is. Your editor and immediate visual feedback (no need to remember
>> > to reindent after making the semantic changes).
>> 
>> `immediate visual feedback' = programmer discipline
>> Laxness at this point is a source of errors.
>
> You got it backwards. 
> Not forgetting to press 'M-C-\' = programmer discipline.
> Laxness at this point is a source of errors. 

Forgetting to indent properly in a lisp program does not yield
erroneous code.

> And indeed, people *do* have to be educated not to be lax when editing lisp -
> newbies frequently get told in c.l.l or c.l.s that they should have reindented
> their code because then they would have seen that they got their parens mixed
> up.

This is correct.  But what is recommended here is to use a simple tool to
enhance readability and do a trivial syntactic check. 

> OTOH, if you make an edit in python the result of this edit is immediately
> obvious -- no mismatch between what you think it means and what your computer
> thinks it means and thus no (extra) programmer discipline required.

Would that this were the case.  Lisp code that is poorly indented will still
run.  Python code that is poorly indented will not.  I have seen people write
lisp code like this:

(defun factorial (x)
(if (> x 0)
x
(*
(factorial (- x 1))
x
)))

I still tell them to re-indent it.  A beginner writing python in this manner
would be unable to make the code run.

> Of course you need *some* basic level of discipline to not screw up your
> source code when making edits -- but for all I can see at the moment (and know
> from personal experience) it is *less* than what's required when you edit lisp
> (I have provided a suggested way to edit this particular example in emacs for
> python in my previous post -- you haven't provided an analoguous editing
> operation for lisp with an explanation why it would be less error-prone)).

Ok.  For any sort of semantic error (one in which a statement is
associated with an incorrect group) one could make in python, there is
an analagous one in lisp, and vice versa.  This is simply because both
have unambiguous parse trees.

However, there is a class of *syntactic* error that is possible in
python, but is not possible in lisp (or C or any language with
balanced delimiters).  Moreover, this class of error is common,
frequently encountered during editing, and it cannot be detected
mechanically.

Consider this thought experiment:  pick a character (like parenthesis
for example) go to a random line in a lisp file and insert four of them.
Is the result syntactically correct?  No.  Could a naive user find them?
Trivially.  Could I program Emacs to find them?  Sure.

Now go to a random line in a python file and insert four spaces.  Is
the result syntactically correct?  Likely.  Could a naive user find
them?  Unlikely.  Could you write a program to find them?  No.

Delete four adjacent parens in a Lisp file.  Will it still compile?  No.
Will it even be parsable?  No.

Delete four adjacent spaces in a Python file.  Will it still compile?
Likely.

>> >> >> Yet the visual representation is not only identical between all of these, it
>> >> >> cannot even be displayed.
>> >> >
>> >> > I don't understand what you mean. Could you maybe give a concrete example of
>> >> > the information that can't be displayed? 
>> >> 
>> >> Sure.  Here are five parens )))))  How much whitespace is there here:          
>> >
>> > 10 spaces (which BTW I counted in emacs in just the same way that I'd count a
>> > similar number of parens) -- but what has counting random trailing whitespace
>> > got to do with anything? 
>> 
>> It is simply an illustration that there is no obvious glyph associated
>> with whitespace, and you wanted a concrete example of something that can't
>> be displayed.
>
> No, I didn't want just *any* example of something that can't be displayed; I
> wanted an example of something that can't be displayed and is *pertinent* to
> our discussion (based on the Quinean assumption that you wouldn't have brought
> up "things that can't be displayed" if they were completely besides the
> point).

I thought that whitespace was significant to Python.

My computer does not display whitespace.  I understand that most
computers do not.  There are few fonts that have glyphs at the space
character.

Since having the correct amount of whitespace is *vital* to the
correct operation of a Python program, it seems that the task of
maintaining it is made that much more difficult because it is only
conspicuous by its absence.

> me:
>> >> > People can't "read" '))))))))'.
> [more dialog snipped]
>> I cannot read Abelson and Sussman's minds, but neither of them are
>> ignorant of the vast variety of computer languages in the world.
>> Nonetheless, given the opportunity to choose any of them for
>> exposition, they have chosen lisp.  Sussman went so far as to
>> introduce lisp syntax into his book on classical mechanics.
>
> Well the version of SICM *I've* seen predeominantly seems to use (infixy) math
> notation, so maybe Sussman is a little less confident in the perspicuousness
> of his brainchild than you (also cf. Iverson)?

Perhaps you are looking at the wrong book.  The full title is
`Structure and Interpretation of Classical Mechanics' by Gerald Jay
Sussman and Jack Wisdom with Meinhard E. Mayer, and it is published by
MIT Press.  Every computational example in the book, and there are
many, is written in Scheme.

Sussman is careful to separate the equations of classical mechanics
from the *implementation* of those equations in the computer, the
former are written using a functional mathematical notation similar to
that used by Spivak, the latter in Scheme.  The two appendixes give
the details.  Sussman, however, notes ``For very complicated
expressions the prefix notation of Scheme is often better''

> I don't personally think (properly formated) lisp reads that badly at all
> (compared to say C++ or java) and you sure got the word-seperators right. But
> to claim that using lisp-style parens are in better conformance with the
> dictum above than python-style indentation frankly strikes me as a bit silly
> (whatever other strengths and weaknesses these respective syntaxes might
> have).

And where did I claim that?  You originally stated:

> Still, I'm sure you're familiar with the following quote (with which I most
> heartily agree):
>
>  "[P]rograms must be written for people to read, and only incidentally for
>   machines to execute."
>
> People can't "read" '))))))))'.

Quoting Sussman and Abelson as a prelude to stating that parenthesis are
unreadable is hardly going to be convincing to anyone.

>> Obviously the indentation.  
>> But I'd notice the mismatch.
>
> (Hmm, you or emacs?)

Does it matter?

>> If I gave you a piece of python code jotted down on paper that (as these
>> hypothetical examples usually are) for some reason was of vital importance
>> but I accidentally misplaced the indentation -- how would you know?
>
> Excellent point. But -- wait! Were it Lisp, how would I know that you didn't
> intend e.g.
>
>   (if (bar watz) foo)
>
> instead of 
>
>   (if (bar) watz foo)

You are presupposing *two* errors of two different kinds here:  the
accidental inclusion of an extra parenthesis after bar *and* the
accidental omission of a parenthesis after watz.

The kind of error I am talking about with Python code is a single
error of either omission or inclusion.

> Moral: I really think your (stereoptypical) argument that the possibility of
> inconsistency between "user interpretation" and "machine interpretation" of a
> certain syntax is a feature (because it introduces redundancy that can can be
> used for error detection) requires a bit more work.

I could hardly care less.
From: Andrew Dalke
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <80Rib.625$7a4.350@newsread4.news.pas.earthlink.net>
(I know, I swore off cross-posting on this topic, but the claims
made here were too outrageous for me to ignore)

<·············@comcast.net>
> I wish to show that local information is insufficient for cutting and
> pasting under some circumstances.

Absolutely correct, but rarely the source of errors.  When it does
occur it is almost always immediately after the cut&paste and so
the context is fresh in the mind of the who did the c&p.  The chance
for it to appear in wild code is minute.  I can't recall ever coming
across it.

> Consider this thought experiment:  pick a character (like parenthesis
> for example) go to a random line in a lisp file and insert four of them.
> Is the result syntactically correct?  No.

You're surely exaggerating here.  Here's your factorial example,
which has not been cleaned up.

(defun factorial (x)
(if (> x 0)
x
(*
(factorial (- x 1))
x
)))

 I'll insert four "a" characters in the function name

(defun aaaafactorial (x)
(if (> x 0)
x
(*
(factorial (- x 1))
x
)))

Is that not syntactically correct?  For that matter, what if
I insert four spaces, like

(defun factorial (x)
(if (> x 0)
x
(*
(fact    orial (- x 1))
x
)))

or insert four quotes

(defun factorial (x)
(if (> x 0)
x
''''(*
(factorial (- x 1))
x
)))


> However, there is a class of *syntactic* error that is possible in
> python, but is not possible in lisp

Here's a class of error possible in Lisp and extremely hard to get
in Python -- omitting a space between an operator and an operand
causes an error

Valid Lisp: (- x 1)
Invalid Lisp: (-x 1)     ; ;well, not invalid but semantically different

Valid Python: x - 1
Valid Python: x-1

Yes, I know, it's because '-x' isn't an operator.  Tell it to the
beginning programmer who would have these problems in Python.

Here's another class of error you can get in Lisp but is hard to
get in Python (except in a string).  Randomly insert a '

Valid Lisp: (- x 1)
Valid Lisp: '(- x 1)   ;;; but semantically very different

Will the same beginning user you talk about for Python be
able to identify a single randomly inserted quote in Lisp?

> Now go to a random line in a python file and insert four spaces.  Is
> the result syntactically correct?  Likely.  Could a naive user find
> them?  Unlikely.  Could you write a program to find them?  No.

I tried writing code to test this automatically but ran into problems
because I inserting four spaces at the start of a line may be syntactically
correct and may also not affect the semantics.  For example

def spam(x = some_value,
         y = some_other_value):

Adding 4 characters to the start of the 2nd line doesn't change the
meaning of the line.

There definitely were silent errors, like changing returns of
the sort

    if x > 0:
        return "positive"
    return "nonpositive"

into

    if x > 0:
        return "positive"
        return "nonpositive"

NB: This should be caught in any sort of unit test.  The real test
is if it's hard to detect by a programmer; I'm not the one to
answer that test since I'm too used to Python.  I suspect it is
generally easy to find, especially when the code is actually run,
but that it isn't always automatic.

I also figured given the quote counter example it wasn't
worthwhile categoring everything by hand.

> Delete four adjacent spaces in a Python file.  Will it still compile?
> Likely.

Here's test code.  Note that I give each file 30 chances to succeed
after deleting 4 spaces, and it *never* did so.  That surprised me as
I thought some of the hits would be in continuation blocks.  There
may be a bug in my test code so I submit it here for review.

=================
import string, random, os

def remove_random_4_spaces(s):
    x = s.split("    ")
    if len(x) <= 1:
        # needed for re.py which doesn't have 4 spaces
        return "]]"  # force a syntax error
    i = random.randrange(1, len(x))
    x[i-1:i+1] = [x[i-1] + x[i]]
    return "    ".join(s)

def check_for_errors(filename):
    s = open(filename).read()
    for i in range(30):
        t = remove_random_4_spaces(s)
        try:
            exec t in {}
            print "Success with", filename, "on try", i
            return 0
        except SyntaxError:
            pass
    return 1

def main():
    dirname = os.path.dirname(string.__file__)
    filenames = [name for name in os.listdir(dirname)
                      if name.endswith(".py")]
    count = 0
    errcount = 0
    problems = []
    for filename in filenames:
        print filename,
        err = check_for_errors(os.path.join(dirname, filename))
        if err:
            errcount += 1
            print "properly failed"
        else:
            print "still passed!"
            problems.append(filename)
        count += 1
    print errcount, "correctly failed of", count
    print "had problems with", problems

if __name__ == "__main__":
    main()


=================
anydbm.py properly failed
asynchat.py properly failed
asyncore.py properly failed
atexit.py properly failed
audiodev.py properly failed
base64.py properly failed
  ...
__future__.py properly failed
__phello__.foo.py properly failed
185 correctly failed of 185
had problems with []


                    Andrew
                    ·····@dalkescientific.com
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <NvGcnfI8NtfNgBGiU-KYgg@comcast.com>
<·············@comcast.net> wrote in message

Thank you for the clarification.  The message for me is this: a
Python-aware editor should have an option to keep a pasted-in snippet
selected so that the indentation can be immediately adjusted by the
normal selected-block indent/dedent methods without having to
reselect.

TJR
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsllrn5zue.fsf@black132.ex.ac.uk>
"Terry Reedy" <·······@udel.edu> writes:

> <·············@comcast.net> wrote in message
> 
> Thank you for the clarification.  The message for me is this: a
> Python-aware editor should have an option to keep a pasted-in snippet
> selected so that the indentation can be immediately adjusted by the
> normal selected-block indent/dedent methods without having to
> reselect.

emacs. Just press C-c> or C-c< right after pasting.

'as
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ekxfmhhl.fsf@thalassa.informatimago.com>
·············@comcast.net writes:
> [...]
> I thought that whitespace was significant to Python.
> 
> My computer does not display whitespace.  I understand that most
> computers do not.  There are few fonts that have glyphs at the space
> character.
> 
> Since having the correct amount of whitespace is *vital* to the
> correct operation of a Python program, it seems that the task of
> maintaining it is made that much more difficult because it is only
> conspicuous by its absence.

:-)

That remembers me that when  the languages had significant spaces, the
programming was  done with forms, sheets of  physical paper preprinted
with empty spaces:


|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 1           7        12

and you could then fill the blanks and have the significant spaces and
columns nicely visualized.

I assume  python editors now  show this kind  of form as  a background
bitmap, don't they.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <llrn47mb.fsf@comcast.net>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> ·············@comcast.net writes:
>> [...]
>> I thought that whitespace was significant to Python.
>> 
>> My computer does not display whitespace.  I understand that most
>> computers do not.  There are few fonts that have glyphs at the space
>> character.
>> 
>> Since having the correct amount of whitespace is *vital* to the
>> correct operation of a Python program, it seems that the task of
>> maintaining it is made that much more difficult because it is only
>> conspicuous by its absence.
>
> :-)
>
> That remembers me that when  the languages had significant spaces, the
> programming was  done with forms, sheets of  physical paper preprinted
> with empty spaces:
>
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
>  1           7        12
>
> and you could then fill the blanks and have the significant spaces and
> columns nicely visualized.
>
> I assume  python editors now  show this kind  of form as  a background
> bitmap, don't they.

The Lisp Machine had a visual Hollerith editor.
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1cucnY9twevVdxGiU-KYhA@comcast.com>
"Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in
message ···················@thalassa.informatimago.com...
>
> ·············@comcast.net writes:
> > Since having the correct amount of whitespace is *vital* to the
> > correct operation of a Python program, it seems that the task of
> > maintaining it is made that much more difficult because it is only
> > conspicuous by its absence.

> That remembers me that when  the languages had significant spaces,
the
> programming was  done with forms, sheets of  physical paper
preprinted
> with empty spaces:
[further idiocy snipped]

I do believe that several Lispers have suggested that people should
give Lisp a fair trial before rejecting it on account of parentheses
or macros.  The same goes, of course, for Python and significant
indents/dedents.  For most people who try Python, freedom from
visually redundant fences is a feature.  Those who find it a bother
after trying are welcome to chose another language.

What makes the comments above doubly absurd is that Lisp has as much
or more need for 'significant spaces' as Python.  Compare (1,2,3)
versus (1 2 3).  Having the "correct amount of whitespace is *vital*
to the correct operation of a" Lisp program as much as for any other.
Do Lispers therefore use forms?  I suspect not ;-)

Terry J. Reedy
From: Vijay L
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <1eaf81aa.0310150533.265145b9@posting.google.com>
"Terry Reedy" <·······@udel.edu> wrote in message news:<······················@comcast.com>...
> "Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in
> message ···················@thalassa.informatimago.com...
> >
> > ·············@comcast.net writes:
> > > Since having the correct amount of whitespace is *vital* to the
> > > correct operation of a Python program, it seems that the task of
> > > maintaining it is made that much more difficult because it is only
> > > conspicuous by its absence.
>  
> > That remembers me that when  the languages had significant spaces,
>  the
> > programming was  done with forms, sheets of  physical paper
>  preprinted
> > with empty spaces:
> [further idiocy snipped]

I don't know why you categorize it as idiocy.  I, having no experience
whatsoever with Python, find it hard to believe that indentation is
easy without "("s and "{"s.  (Yes, yes, I know, it can't be so hard. 
I've read the other posts, but I find it hard to believe nonetheless.)
 In the next paragraph you ask people not to be judgmental and here
you are doing it yourself.
 
> I do believe that several Lispers have suggested that people should
> give Lisp a fair trial before rejecting it on account of parentheses
> or macros.  

I love Lisp primarily /because/ of its macros.
 
> The same goes, of course, for Python and significant
> indents/dedents.  For most people who try Python, freedom from
> visually redundant fences is a feature.  Those who find it a bother
> after trying are welcome to chose another language.

> What makes the comments above doubly absurd is that Lisp has as much
> or more need for 'significant spaces' as Python.  Compare (1,2,3)
> versus (1 2 3).  Having the "correct amount of whitespace is *vital*
> to the correct operation of a" Lisp program as much as for any other.
> Do Lispers therefore use forms?  I suspect not ;-)

I don't know what you've meant by "white-space" here.

Removing white-space from (1 2 3) gives me (123).  I agree, very
different, but noone knowing the language would consciously do this,
not even a newbie.  A newbie, used to other languages, would probably
write (1,2,3) only to get and error saying that the comma cannot be
used outside of a backquote ... and no newbie I know is going to start
off with backquotes.  So once he gets an error what does he do?  Curse
the language and get on with the same list without the commas.  As
time goes by he begins to forget the commas in other languages and
curses /those/ languages.  (This happens to me sometimes :)

In Lisp, apart from the whitespace-where-required, whitespace is
insignificant.  You can write (1               2


3)
as well as (1 2 3) and get the same meaning.

So we Lispers don't need to use any forms.

Cheers,
Vijay

All future commitments are optimistic.
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <KrSdnZXxRpNQAhCiRVn-iw@comcast.com>
"Vijay L" <······@lycos.com> wrote in message
·································@posting.google.com...
> "Terry Reedy" <·······@udel.edu> wrote in message
news:<······················@comcast.com>...
> > "Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in
> > message ···················@thalassa.informatimago.com...
> > >
> > > ·············@comcast.net writes:
> > > > Since having the correct amount of whitespace is *vital* to
the
> > > > correct operation of a Python program, it seems that the task
of
> > > > maintaining it is made that much more difficult because it is
only
> > > > conspicuous by its absence.
> >
> > > That remembers me that when  the languages had significant
spaces,
> >  the
> > > programming was  done with forms, sheets of  physical paper
> >  preprinted
> > > with empty spaces:
> > [further idiocy snipped]
>
> I don't know why you categorize it as idiocy.

The 'it' that I snipped was an ASCII mockup of a Fortran coding sheet
or something and the implied suggestion that we Pythoneers are
Neanderthals who should write our programs on such, instead of using
Python-aware computer editors.  Very funny, not.

A month and two ago, some Lispers posted polite and intelligent
suggestions on c.l.py that Pythoneers not familiar with Lisp might
want to take a real look.  I bit and finally read the used Winston and
Horn LISP book that I bought about 10 years ago.  However, the recent
spate of garbage-dumping has lead me to question whether I should even
look at CL.  It seems that c.l.lisp would not be a friendly place to
ask questions.

> I, having no experience whatsoever with Python, find it hard to
believe that
> indentation is easy without "("s and "{"s.  (Yes, yes, I know, it
can't be so
> hard.  I've read the other posts, but I find it hard to believe
nonetheless.)

??? Don't you use indentation when writing Lisp?
It is even easier without adding redundant fences.
Learn something before 'sharing' such useless beliefs.

> In the next paragraph you ask people not to be judgmental and here
> you are doing it yourself.

I specifically suggested, and suggest, that Lispers, including you,
follow the posted suggestion of fellow Lispers that people not finally
judge the burdensomeness of a syntactic feature without actually using
it enough to experience the corresponding benefit, so one can make a
balanced judgment.  Calling a stupid insult 'idiotic' is another
matter entirely ;-)

> > What makes the comments above doubly absurd is that Lisp has as
much
> > or more need for 'significant spaces' as Python.  Compare (1,2,3)
> > versus (1 2 3).  Having the "correct amount of whitespace is
*vital*
> > to the correct operation of a" Lisp program as much as for any
other.
> > Do Lispers therefore use forms?  I suspect not ;-)
>
> I don't know what you've meant by "white-space" here.

If you look more carefully at both my paragraph and the one near the
top copied from
Mr. prunesquallor's post, you might discover that 'whitespace', a
programming term dating back 30 years old or more, occurs in a phrase
quoted from Mr. P's post.  So ask him.

> Removing white-space from (1 2 3) gives me (123).  I agree, very
different,

Which is exactly my point.  Thank you for agreeing.  This supports the
main point of my post, which is that attacking Python for having
critical whitespace is logically also an attack on Lisp for the same
reason.

>but noone knowing the language would consciously do this, not even a
newbie.

Ditto for Python newbies and removing commas or whitespace where
needed.

...
> In Lisp, apart from the whitespace-where-required, whitespace is
> insignificant.  You can write (1               2               3)
> as well as (1 2 3) and get the same meaning.

And in Python, (1,       2,        3) == (1,2,3).  So what?

> So we Lispers don't need to use any forms.

Neither do we Pythoneers -- and it was idiotic to suggest otherwise.

Terry J. Reedy
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ad8246zs.fsf@ccs.neu.edu>
"Terry Reedy" <·······@udel.edu> writes:

> However, the recent spate of garbage-dumping has lead me to question
> whether I should even look at CL.  It seems that c.l.lisp would not
> be a friendly place to ask questions.

I'll apologize for the posts of mine that drifted over into
comp.lang.python  they were unintentional.

We're not deliberately unfriendly here in c.l.l, but about once or
twice a month someone comes into the group and makes claims about the
illegibility of parenthesis.  We do get tired of this.

Of course it is as unreasonable to bitch and moan to python people
about whitespace in comp.lang.python.  I've haven't intentionally
started any arguments in comp.lang.python about it, but I'm afraid
that I haven't been as vigilant in watching the followups as I should
have been.

> If you look more carefully at both my paragraph and the one near the
> top copied from Mr. prunesquallor's post, you might discover that
> 'whitespace', a programming term dating back 30 years old or more,
> occurs in a phrase quoted from Mr. P's post.  So ask him.

Whitespace in Lisp is defined as 

  whitespace n. 1. one or more characters that are either the graphic
  character #\Space or else non-graphic characters such as #\Newline
  that only move the print position. 2. a. n. the syntax type of a
  character that is a token separator. b. adj. (of a character) having
  the whitespace[2a] syntax type[2]. c. n. a whitespace[2b] character.

Other non-graphic characters usually include #\Tab, #\Form, #\Return,
#\Linefeed, and sometimes #\VT and #\NUL.

>> Removing white-space from (1 2 3) gives me (123).  I agree, very
> different,
>
> Which is exactly my point.  Thank you for agreeing.  This supports the
> main point of my post, which is that attacking Python for having
> critical whitespace is logically also an attack on Lisp for the same
> reason.

I was being imprecise.  Since Python treats intertoken whitespace
essentially the same as Lisp, there is no logical argument that can
include one and exclude the other.  My concern revolves around
delineating code blocks through creating common prefixes on the
associated lines, *and* that these prefixes are hard to see (although
it is *not* hard to see that they exist, nor hard to see if two
adjacent ones are the same or different, but that it *is* hard to see
exactly how many of them are there in deeply indented code). 


I'll remove further followups to comp.lang.python
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.123.1066251473.2192.python-list@python.org>
Joe Marshall <···@ccs.neu.edu> wrote previously:
|it is *not* hard to see that they exist, nor hard to see if two
|adjacent ones are the same or different, but that it *is* hard to see
|exactly how many of them are there in deeply indented code).

Here's a quick rule that is pretty damn close to categorically true for
Python programming:  If you use more than five levels of indent, you are
coding badly.  Something is in desperate need of refactoring.

I did a scan of my Gnosis Utilities, which the tool SLOCCount' reports
as having about 7500 lines of Python code.  Using a quick custom script,
I find that I use more than depth five a total of four times--all of
them within a class definition.  Maybe that means I should do a little
refactoring, but even five levels is pretty unusual.

Visually distinguishing among four or five possible indent levels is
extremely easy.  The nonsensical non-problem about indecipherable
indents just simply never happens in useful code.

Yours, David...

--
·····@  | The specter of free information is haunting the `Net!  All the
gnosis  | powers of IP- and crypto-tyranny have entered into an unholy
.cx     | alliance...ideas have nothing to lose but their chains.  Unite
        | against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8765iplt91.fsf@thalassa.informatimago.com>
·····@gnosis.cx (David Mertz) writes:

> Joe Marshall <···@ccs.neu.edu> wrote previously:
> |it is *not* hard to see that they exist, nor hard to see if two
> |adjacent ones are the same or different, but that it *is* hard to see
> |exactly how many of them are there in deeply indented code).
> 
> Here's a quick rule that is pretty damn close to categorically true for
> Python programming:  If you use more than five levels of indent, you are
> coding badly.  Something is in desperate need of refactoring.
> 
> I did a scan of my Gnosis Utilities, which the tool SLOCCount' reports
> as having about 7500 lines of Python code.  Using a quick custom script,
> I find that I use more than depth five a total of four times--all of
> them within a class definition.  Maybe that means I should do a little
> refactoring, but even five levels is pretty unusual.
> 
> Visually distinguishing among four or five possible indent levels is
> extremely easy.  The nonsensical non-problem about indecipherable
> indents just simply never happens in useful code.
> 
> Yours, David...

Here is an histogram of the depths  of the top level sexps found in my
emacs sources:

((1 . 325) (2 . 329) (3 . 231) (4 . 163) (5 . 138) (6 . 158) (7 . 102)
 (8 . 94) (9 . 63) (10 . 40) (11 . 16) (12 . 20) (13 . 9) (14 . 4) 
 (15 . 5) (16 . 4) (17 . 2) (19 . 2) (23 . 1))

Am I depraved in writting code with depths down to 23?

Ok, in Python, you may  have also expressions that will further deepen
the tree,  but how can  you justify an artificial  segregation between
indentation and sub-expressions?

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.136.1066279096.2192.python-list@python.org>
|> Here's a quick rule that is pretty damn close to categorically true for
|> Python programming:  If you use more than five levels of indent, you are
|> coding badly.  Something is in desperate need of refactoring.

Pascal Bourguignon <····@thalassa.informatimago.com> wrote previously:
|Here is an histogram of the depths  of the top level sexps found in my
|emacs sources:
|((1 . 325) (2 . 329) (3 . 231) (4 . 163) (5 . 138) (6 . 158) (7 . 102)
| (8 . 94) (9 . 63) (10 . 40) (11 . 16) (12 . 20) (13 . 9) (14 . 4)
| (15 . 5) (16 . 4) (17 . 2) (19 . 2) (23 . 1))
|Am I depraved in writting code with depths down to 23?

As I've written lots of times in these threads, I haven't really used
Lisp.  In fact, I really only did my first programming in Scheme (for an
article on SSAX) in the last couple weeks; I know Scheme isn't Common
Lisp, no need to point that out again.  However, I -have- read a fair
number of snippets of Lisp code over the years, so my familiarity runs
slightly deeper than the couple weeks.

All that said, my gut feeling is that depth 23 is, indeed, ill-designed.
Even the more common occurrences of 12 or 13 levels seems like a lot
more than my brain can reason about.  I'm happy to stipulate that
Bourguignon is smarter than I am... but I'm still confident that I can
do this sort of thinking better than 95% of the people who might have to
READ his code.

And the purpose of code, after all, is to COMMUNICATE ideas:  firstly to
other people, and only secondly to machines.

|Ok, in Python, you may  have also expressions that will further deepen
|the tree,  but how can  you justify an artificial  segregation between
|indentation and sub-expressions?

Because it's Python!  There is a fundamental syntactic distinction
between statments and expressions, and statements introduce blocks
(inside suites, bare expressions can occur though--usually functions
called for their side effects).  It is the belief of the BDFL--and of
the large majority of programmers who use Python--that a syntactic
distinction between blocks with relative indention and experessions
that nest using parens and commas AIDS READABILITY.

I can say experientially, and from reading and talking to other
Pythonistas, that my brain does a little flip when it finishes
identifying a suite, then starts identifying the parts of an expression.
And conveniently, in Python, the sort of thinking I need to do when I
read or write the lines of a suite is a bit different than for the parts
of an expression.  Not just because I am deceived by the syntax, but
because the language really does arrange for a different sort of thing
to go on in statements versus expressions (obviously, there are SOME
overlaps and equivalences; but there's still a useful pattern to the
distinction).

Still, for a real comparison of depth, I suppose I'd need to look at the
combined depth of indent+paren-nesting.  Even for that, well-designed
Python programs top out at 7 or 8, IMO.  Maybe something a little deeper
reasonably occurs occassionally, but the histogram would sure look
different from Pascal's ("Flat is better than nested").

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Iran nuclear neocon POTUS patriot Pakistan weaponized uranium invasion UN
smallpox Gitmo Castro Tikrit armed revolution Carnivore al-Qaeda sarin
---[ Gnosis Software ("We know stuff") <·····@gnosis.cx> ]---------------
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <u169ww4t.fsf@comcast.net>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Here is an histogram of the depths  of the top level sexps found in my
> emacs sources:
>
> ((1 . 325) (2 . 329) (3 . 231) (4 . 163) (5 . 138) (6 . 158) (7 . 102)
>  (8 . 94) (9 . 63) (10 . 40) (11 . 16) (12 . 20) (13 . 9) (14 . 4) 
>  (15 . 5) (16 . 4) (17 . 2) (19 . 2) (23 . 1))
>
> Am I depraved in writting code with depths down to 23?

Geez, I hope not.  I have some code down to 27.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsn0c24dqu.fsf@black132.ex.ac.uk>
······@lycos.com (Vijay L) writes:
> I don't know why you categorize it as idiocy.  

But I know why you don't know:

> I, having no experience whatsoever with Python

'as
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <he2b7wum.fsf@comcast.net>
"Terry Reedy" <·······@udel.edu> writes:

> "Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in
> message ···················@thalassa.informatimago.com...
>>
>> ·············@comcast.net writes:
>> > Since having the correct amount of whitespace is *vital* to the
>> > correct operation of a Python program, it seems that the task of
>> > maintaining it is made that much more difficult because it is only
>> > conspicuous by its absence.
>
>> That remembers me that when  the languages had significant spaces,
> the
>> programming was  done with forms, sheets of  physical paper
> preprinted
>> with empty spaces:
> [further idiocy snipped]
>
> I do believe that several Lispers have suggested that people should
> give Lisp a fair trial before rejecting it on account of parentheses
> or macros.  The same goes, of course, for Python and significant
> indents/dedents.  For most people who try Python, freedom from
> visually redundant fences is a feature.  Those who find it a bother
> after trying are welcome to chose another language.
>
> What makes the comments above doubly absurd is that Lisp has as much
> or more need for 'significant spaces' as Python.  

That is simply incorrect.  It is a small matter to set the readtable
such that things like (+x3) are interpreted as (+ x 3).  This would
make it much more difficult to use complicated variable names, but
that's the tradeoff. 

> Compare (1,2,3) versus (1 2 3).  Having the "correct amount of
> whitespace is *vital* to the correct operation of a" Lisp program as
> much as for any other.  Do Lispers therefore use forms?  I suspect
> not ;-)

There's a bit of a difference between the whitespace separating tokens
and the whitespace that delineates blocks.  The former is a member
of the half-open interval (0, +inf), the latter is a singleton.
From: Terry Reedy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8sGcnY8KoZnVyBCiU-KYjw@comcast.com>
<·············@comcast.net> wrote in message
·················@comcast.net...
> "Terry Reedy" <·······@udel.edu> writes:

> >> ·············@comcast.net writes:
> >> > Since having the correct amount of whitespace is *vital* to the

> > "Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in
> >> That remembers me that when  the languages had significant
spaces,
> >> programming was  done with forms, sheets of  physical paper

> > I do believe that several Lispers have suggested that people
should
> > give Lisp a fair trial before rejecting it on account of
parentheses
> > or macros.  The same goes, of course, for Python and significant
> > indents/dedents.  For most people who try Python, freedom from
> > visually redundant fences is a feature.  Those who find it a
bother
> > after trying are welcome to chose another language.
> >
> > What makes the comments above doubly absurd is that Lisp has as
much
> > or more need for 'significant spaces' as Python.

> That is simply incorrect.  It is a small matter to set the readtable
> such that things like (+x3) are interpreted as (+ x 3).  This would
> make it much more difficult to use complicated variable names, but
> that's the tradeoff.

So I revise my statement: unless one uses a Lisp with a 'nospace'
option present and turned on, Lisp ...

But why be defensive and nitpicky?  I consider this whitespace use (in
the usual case) to be a feature of Lisp.  It works well for Lisp
because subexpressions are sublists delimited by ().  By contrast,
eliminating commas for Python sequences would be awkward since tuples
are currently *defined* by the present of commas.

> > Compare (1,2,3) versus (1 2 3).  Having the "correct amount of
> > whitespace is *vital* to the correct operation of a" Lisp program
as
> > much as for any other.  Do Lispers therefore use forms?  I suspect
> > not ;-)
>
> There's a bit of a difference between the whitespace separating
tokens
> and the whitespace that delineates blocks.

We agree; this was one point of my posting.   If you are going to slam
Python for its block-delimiting whitespace feature, with or without
having tried it, I would prefer that you say so specificly instead of
using sloppy generalizations like 'whitespace' or 'significance
spaces' that apply to most languages ;-)

As for the programming-form gag, if I were to write substantial
amounts of Python by hand (as I once did with Fortran), I should like
having lined paper with unobtrusive indent ticks every centimeter or
half inch.

Terry J. Reedy
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <vfqq6stu.fsf@comcast.net>
"Terry Reedy" <·······@udel.edu> writes:

> <·············@comcast.net> wrote in message
>>
>> There's a bit of a difference between the whitespace separating
> tokens
>> and the whitespace that delineates blocks.
>
> We agree; this was one point of my posting.   If you are going to slam
> Python for its block-delimiting whitespace feature, with or without
> having tried it, I would prefer that you say so specificly instead of
> using sloppy generalizations like 'whitespace' or 'significance
> spaces' that apply to most languages ;-)

I'll endeavor to be more precise.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsr81e4eym.fsf@black132.ex.ac.uk>
·············@comcast.net writes:

> Consider this python code (lines numbered for exposition):

Thanks for going through the trouble of posting an elaborate example.

> 
>  1 def dump(st):
>  2     mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime = st
>  3     print "- size:", size, "bytes"
>  4     print "- owner:", uid, gid
>  5     print "- created:", time.ctime(ctime)
>  6     print "- last accessed:", time.ctime(atime)
>  7     print "- last modified:", time.ctime(mtime)
>  8     print "- mode:", oct(mode)
>  9     print "- inode/dev:", ino, dev
> 10
> 11 def index(directory):
> 12     # like os.listdir, but traverses directory trees
> 13     stack = [directory]
> 14     files = []
> 15     while stack:
> 16         directory = stack.pop()
> 17         for file in os.listdir(directory):
> 18             fullname = os.path.join(directory, file)
> 19             files.append(fullname)
> 20             if os.path.isdir(fullname) and not os.path.islink(fullname):
> 21                 stack.append(fullname)
> 22     return files

[...]

> But let us consider cutting lines 6 and 7 and putting them
> between lines 21 and 22.  We get this: 
> 
> 15     while stack:
> 16         directory = stack.pop()
> 17         for file in os.listdir(directory):
> 18             fullname = os.path.join(directory, file)
> 19             files.append(fullname)
> 20             if os.path.isdir(fullname) and not os.path.islink(fullname):
> 21                 stack.append(fullname)
>  6     print "- last accessed:", time.ctime(atime)
>  7     print "- last modified:", time.ctime(mtime)
> 22     return files
> 
> But it is unclear whether the intent was to be outside the while,
> or outside the for, or part of the if.

I don't think so. Before pasting you just move your cursor to #1 #2 or #3 to
achieve the respective results:

> 15     while stack:
> 16         directory = stack.pop()
> 17         for file in os.listdir(directory):
> 18             fullname = os.path.join(directory, file)
> 19             files.append(fullname)
> 20             if os.path.isdir(fullname) and not os.path.islink(fullname):
> 21                 stack.append(fullname)
         #1  #2      #3
> 22     return files

What's wrong with that? (If nothing, I'll finally hack it up in elisp,
unless someone already has done it).

[snipped]

> Now consider this `pseudo-equivalent' parenthesized code:
> 
>  1 (def dump (st)
>  2    (destructuring-bind (mode ino dev nlink uid gid size atime mtime ctime) st
>  3       (print "- size:" size "bytes")
>  4       (print "- owner:" uid gid)
>  5       (print "- created:" (time.ctime ctime))
>  6       (print "- last accessed:" (time.ctime atime))
>  7       (print "- last modified:" (time.ctime mtime))
>  8       (print "- mode:" (oct mode))
>  9       (print "- inode/dev:" ino dev)))
> 10
> 11 (def index (directory)
> 12     ;; like os.listdir, but traverses directory trees
> 13     (let ((stack directory)
> 14           (files '()))
> 15       (while stack
> 16         (setq directory (stack-pop))
> 17         (dolist (file (os-listdir directory))
> 18            (let ((fullname (os-path-join directory file)))
> 19              (push fullname files)
> 20              (if (and (os-path-isdir fullname) (not (os-path-islink fullname)))
> 21                  (push fullname stack)))))
> 22       files))
> 
> If we cut lines 6 and 7 with the intent of inserting them
> in the vicinity of line 21, we have several options (as in python),
> but rather than insert them incorrectly and then fix them, we have
> the option of inserting them into the correct place to begin with.
> In the line `(push fullname stack)))))', there are several close
> parens that indicate the closing of the WHILE, DOLIST, LET, and IF,
> assuming we wanted to include the lines in the DOLIST, but not
> in the LET or IF, we'd insert here:
>                                             V
> 21                  (push fullname stack)))   ))

AFAICT this is a more difficult editing operation to get right than what I
suggested above to get the desired effect for python and you still have to
reindent.

> 
> The resulting code is ugly:
[...]
> But it is correct.

Correct as in "has the desired behavior" is not the only thing that counts.

> 
> (Incidentally inserting at that point is easy:  you move the cursor over
> the parens until the matching one at the beginning of the DOLIST begins
> to blink.  At this point, you know that you are at the same syntactic level
> as the dolist.)

Sure, it's not very taxing, but I think still slightly more so than placing
the cursor at #1 #2 or #3 for the python example (you need to invoke extra
functionality, even if this functionality is quite convinient and you need to
devote visual attention to an extra site).

> 
> >> >> The fact that the information is replicated, and that there is nothing
> >> >> but programmer discipline keeping it consistent is a source of errors.
> 
> Let me expand on this point.  The lines I cut are very similar to each
> other, and very different from the lines where I placed them.  But
> suppose they were not, and I had ended up with this:
> 
> 19             files.append(fullname)
> 20             if os.path.isdir(fullname) and not os.path.islink(fullname):
> 21                 stack.append(fullname)
>  6     print "- last accessed:", time.ctime(atime)
>  7     print "- last modified:", time.ctime(mtime)
> 22     print "- copacetic"
> 23     return files
> 
> Now you can see that lines 6 and 7 ought to be re-indented, but line 22
> should not. It would be rather easy to either accidentally group line seven
> with line 22, or conversely line 22 with line 7.

True, but as I stated above AFAICT there is no need to paste-and fix, you can
just paste correctly (Digression for the emacs-interested: a really
emacs-savvy user will paste and fix in a pretty safe fashion anyway, because
the source of error above would be to inadvertently select a (wrong) region
for reindentation. If you just reindent (with C-c> or C-c<) right after
pasting (the pasted code will automatically form the region then) you don't
have this problem).

> 
> >> > Sure there is. Your editor and immediate visual feedback (no need to remember
> >> > to reindent after making the semantic changes).
> >> 
> >> `immediate visual feedback' = programmer discipline
> >> Laxness at this point is a source of errors.
> >
> > You got it backwards. 
> > Not forgetting to press 'M-C-\' = programmer discipline.
> > Laxness at this point is a source of errors. 
> 
> Forgetting to indent properly in a lisp program does not yield
> erroneous code.

I think this highlights an implicit but mistaken assumption underlying
anti WS arguments.

No, of course forgetting to indent does not *directly* yield erroneous code.
That's not good enough, however because it is associated with 2 problems:

1) masking an error: if you perform an operation that can go wrong and
   frequently does (such as issuing an editing command) then enforcing manual
   verification of the desired outcome (read C-M-\) is a source of error.

2) misleading later readers (including the programmer himself, esp. while he's
   editing): the bad indentation might well suggest an altnernative meaning
   from the actually intended one that goes unnoticed till someone reindents
   the code -- again a source of errors.


> 
> > And indeed, people *do* have to be educated not to be lax when editing
> > lisp - newbies frequently get told in c.l.l or c.l.s that they should have
> > reindented their code because then they would have seen that they got
> > their parens mixed up.
> 
> This is correct.  But what is recommended here is to use a simple tool to
> enhance readability and do a trivial syntactic check.

I think "enhance readability" is more than an understatement. Lisp code of
reasonable complexity is simply unreadable if not or arbitrarily indented
(even more so than XML!).
 
> > OTOH, if you make an edit in python the result of this edit is immediately
> > obvious -- no mismatch between what you think it means and what your computer
> > thinks it means and thus no (extra) programmer discipline required.
> 
> Would that this were the case.  Lisp code that is poorly indented will still
> run.
> Python code that is poorly indented will not. I have seen people write lisp
> code like this:
> 
> (defun factorial (x)
> (if (> x 0)
> x
> (*
> (factorial (- x 1))
> x
> )))
> 
> I still tell them to re-indent it.  A beginner writing python in this manner
> would be unable to make the code run.

But the fact that you can't do this in python (and BTW I've never seen a
*python* newbie TRY -- have you?) is a FEATURE, for crying out loud.

Or what exactly do you think the benefit of making it easier for beginners to
write error-prone and unreadable code to be? Why is it a paedagogical
disadvantageous for python beginners to automatically write readable code that
does what they think it does (at least as far as block structure is concerned)
compared to lisp newbies who either often write code that doesn't do what they
(and other readers) think it does (because of indentation/paren mismatch) or
that is inpenetrable (just think about how many hours these people have wasted
trying to decipher and debug their code before you gave them the fatherly
advice to try to indent it)?

> Ok.  For any sort of semantic error (one in which a statement is
> associated with an incorrect group) one could make in python, there is
> an analagous one in lisp, and vice versa.  This is simply because both
> have unambiguous parse trees.
> 
> However, there is a class of *syntactic* error that is possible in
> python, but is not possible in lisp (or C or any language with
> balanced delimiters).  Moreover, this class of error is common,
> frequently encountered during editing, and it cannot be detected
> mechanically.

This argument basically boils down to "lisp is more redundant and therefore
less error prone". This inself is not a valid argument as it depends on the
type of redundancy and the extend to which this redundancy itself causes
errors, e.g. by rendering the code more obscure by additional verbosity (as in
xml compared to sexps); whether this redundancy helps or hinders perception
and how this redundancy interferes with the editing process.

As an example of such interference in the case of lisp consider the example of
commenting/deleteing/appending after a line with surplus trailing parens
(corresponding ot opening parens in earlier lines). Conceptually this line is
the same as all the other lines in the code in the same block, but you have to
use quite different (and more complicated and error-prone) commands to achieve
the same editing process. Not so in python.

> 
> Consider this thought experiment:  pick a character (like parenthesis
> for example) go to a random line in a lisp file and insert four of them.

This thougt experiment seems of limited informational value. While I can see
how you might accidentally indent 4 spaces by pressing tab (which you'd
normally notice) accidently, inserting 4 spaces or 4 parens (by pressing space
or ')') seems highly unlikely to me.

Additionally most of the time the code is actively being edited and thus *not*
in a consistent state -- this is how most editing errors occur and I don't
think lisp compares favourably to python here.

This is largely due to the fact that the relationship between suggested
meaning and actual meaning of the code is automatically maintained in python
and only semi-automatically by emacs/lisp. As an example consider introducing
additional local vars by adding a let-block. This is not quite equivalent to
the same example in python (which is trivial, editing wise, baring potential
for local name-conflicts), but close enough and (unless you've plenty at
routine at editing lisp code) it's pretty easy to screw things up here (paren
matching makes it easy to match with visually exposed outer parents (viz.
corresponding to e.g. "(LET"'), but I find it's still pretty easy to end up
with wrong parens inside, viz. the var forms/body) -- the more code you write
before reindenting everything the higher the likelyhood something went wrong,
although the total number of parens will be correct.

Anyway, back to your thought-experiment:

> Is the result syntactically correct?  No.  Could a naive user find them?
> Trivially.  Could I program Emacs to find them?  Sure.
> 
> Now go to a random line in a python file and insert four spaces.  Is

Uhm where? A) Anywhere in the line? Since only *leading whitespace* is
significant this wouldn't alter the meaning (safe in strings and identifiers
-- as in CL). So I assume you mean B) at the beginning of the line, in which
case:

> the result syntactically correct?  
> Likely.  

Depends on what you mean by "likely". A necessary condition for the result to
be syntactically valid and semantically different is that the preceding
(non-comment) line has the same indent (which occurs in about of 10% of the
lines in a representative sample [1]).

> Could a naive user find  them?  
> Unlikely. 

Uhm, actually extremely likely because 90% of the cases in B) yield invalid
syntax, which both python and your editor can easily figure out for the naive
user without even running the code.

> Could you write a program to find them?  No.

Sure I could, but writing one that performs better then say 95% would involve
an amount of work unwarranted by the unrealistic scenario.

 > Delete four adjacent parens in a Lisp file.  Will it still compile?  No.
> Will it even be parsable?  No.
> 
> Delete four adjacent spaces in a Python file.  Will it still compile?
> Likely.

See above.

> > No, I didn't want just *any* example of something that can't be displayed;
> > I wanted an example of something that can't be displayed and is

> > *pertinent* to our discussion (based on the Quinean assumption that you
                                                ^^^^^^^
                      [thinko; should have been Gricean]

> > wouldn't have brought up "things that can't be displayed" if they were
> > completely besides the point).
> 
> I thought that whitespace was significant to Python.

Only human readable whitespace [2].

> 
> My computer does not display whitespace. 

Mine sure does.

    if bar:
    foo

and 

    if bar:
       foo

look quite different on my computer. Since this (leading ws) is the only type
of whitespace that semtantically matters to python, I still fail to see your
point.


> I understand that most computers do
> not. There are few fonts that have glyphs at the space character.
> 
> Since having the correct amount of whitespace is *vital* to the
> correct operation of a Python program, it seems that the task of
> maintaining it is made that munch more difficult because it is only
> conspicuous by its absence.

No idea what you're driving at -- maybe you've got some wrong assumptions
about the details of python's syntax?

> 
> Sussman is careful to separate the equations of classical mechanics
> from the *implementation* of those equations in the computer, the

I really don't want to push this point too hard, but why not use sexps for
both if sexp-readability was near optimal (Iverson seems to have done the
equivlanent for his mathematical books using APL/J)?

> former are written using a functional mathematical notation similar to
> that used by Spivak, the latter in Scheme.  The two appendixes give
> the details.  Sussman, however, notes ``For very complicated
> expressions the prefix notation of Scheme is often better''

That statement seems to suggest to me that in the general case MN is
preferable.
 
> > I don't personally think (properly formated) lisp reads that badly at all
> > (compared to say C++ or java) and you sure got the word-seperators right.
> > But to claim that using lisp-style parens are in better conformance with
> > the dictum above than python-style indentation frankly strikes me as a bit
> > silly (whatever other strengths and weaknesses these respective syntaxes
> > might have).
> 
> And where did I claim that?  You originally stated:

Well I didn't explicitly say you did, but you contested the claim requoted
below about ')))))))))' (I'm still not quite sure why) and stated that Abelson
and Sussman would disagree with my assesments of parens and whitespace, so
this interpretation seemed not entirely implausible to me.

> 
> > Still, I'm sure you're familiar with the following quote (with which I most
> > heartily agree):
> >
> >  "[P]rograms must be written for people to read, and only incidentally for
> >   machines to execute."
> >
> > People can't "read" '))))))))'.
> 
> Quoting Sussman and Abelson as a prelude to stating that parenthesis are
> unreadable is hardly going to be convincing to anyone.

I didn't say parens are generally unreadable, as the quote above shows I said
that people can't read *large numbers of trailing parens*, which is quite
different (I would also have had to contradict myself otherwise in stating
that properly formated lisp reads well)?

The reason why I brought up this quote is because you were trashing python's
indentation based syntax (which, remember, I didn't claim was suitable or
"better" than sexps for lisp or similar expression based languages) as an
illustration that python's syntax at least compares favourably to sexps in an
area that is of regarded as very important by prominent members of the
lisp/scheme community.

Look, I *like* lisp syntax (and I'm even happy with you to claim it's better
than python's, as long as I can dissuade you from claiming that it's terribly
error-prone, unless you've actually tried writing some reasonable amount of
python yourself).

But clearly a syntax were some vital information is not so much there for
people to read but for editors and compilers is not in full conformance with
the above goal (if you really disagree with this, again why alias '[]' in
pretty much all schemes if nested '()'s are just as readable?). 

In python you don't need the editor to semi-automatically put comments in your
code (which is what pressing 'M-C-\' amounts to) to render it intelligible.

> 
> >> Obviously the indentation.  
> >> But I'd notice the mismatch.
> >
> > (Hmm, you or emacs?)
> 
> Does it matter?

Of course it does matter. We were talking about readability by *humans*.

I know that emacs has no trouble "reading" 7 trailing parenthesis (i.e.
extracting the relevant semantic information from them, namely what they
delimit), but I doubt you (or other humans) can (without some prosthetic aid
in the form of brain implants or manually invoked emacs commands).

 
> >> If I gave you a piece of python code jotted down on paper that (as these
> >> hypothetical examples usually are) for some reason was of vital importance
> >> but I accidentally misplaced the indentation -- how would you know?
> >
> > Excellent point. But -- wait! Were it Lisp, how would I know that you didn't
> > intend e.g.
> >
> >   (if (bar watz) foo)
> >
> > instead of 
> >
> >   (if (bar) watz foo)
> 
> You are presupposing *two* errors of two different kinds here:  the
> accidental inclusion of an extra parenthesis after bar *and* the
> accidental omission of a parenthesis after watz.
> 
> The kind of error I am talking about with Python code is a single
> error of either omission or inclusion.

In my book this is a *single* error of one kind: accidental misplacement of a
parenthesis (sure happens to me as an *atomic* operation). Does this never
happen to you (maybe you use more effective editing strategies, M-( etc.)?


> 
> > Moral: I really think your (stereoptypical) argument that the possibility
> > of inconsistency between "user interpretation" and "machine
> > interpretation" of a certain syntax is a feature (because it introduces
> > redundancy that can can be used for error detection) requires a bit more
> > work.
> 
> I could hardly care less.

Well, anyway I'll leave it at that before this one completely degrades, too. I
hope at least the discussion of editing errors and strategies will have had
some value.

'as

Footnotes

[1] [I really get to write more than my fair share of perl in this thread ;|]

  perl -ne '/^ */; $lines++; $canIndent++ if (length($last)
  == length($&)+4);$last = $&; END{print "LOC:$lines CANINDENT:$canIndent\n";
  print "ratio:" . $canIndent/$lines . "\n"}' /usr/local/lib/python2.3/*.py

  LOC:76264 CANINDENT:9307
  ratio:0.122036609671667

  This is an upper boundary, BTW. Not all these lines would semantically
  change if reindented.

[2] modulo #\Tab which we can include from the current discussion because its
  use is discouraged and the wart that python still allows use of tabs is not
  really relevant to evaluating the merrits of the use of identation for
  block-structure indication as such.
From: David Eppstein
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <eppstein-4A06F3.11104415102003@news.service.uci.edu>
In article <···············@black132.ex.ac.uk>,
 Alexander Schmolck <··········@gmx.net> wrote:

> > But let us consider cutting lines 6 and 7 and putting them
> > between lines 21 and 22.  We get this: 
> > 
> > 15     while stack:
> > 16         directory = stack.pop()
> > 17         for file in os.listdir(directory):
> > 18             fullname = os.path.join(directory, file)
> > 19             files.append(fullname)
> > 20             if os.path.isdir(fullname) and not os.path.islink(fullname):
> > 21                 stack.append(fullname)
> >  6     print "- last accessed:", time.ctime(atime)
> >  7     print "- last modified:", time.ctime(mtime)
> > 22     return files
> > 
> > But it is unclear whether the intent was to be outside the while,
> > or outside the for, or part of the if.

When I cut and paste code, I know what my intent is, and I use the 
block-indent (shift-left or shift-right) features of my text editor to 
achieve that intent.

-- 
David Eppstein                      http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <r81e1jtb.fsf@ccs.neu.edu>
Alexander Schmolck <··········@gmx.net> writes:


> Additionally most of the time the code is actively being edited and thus *not*
> in a consistent state -- this is how most editing errors occur and I don't
> think lisp compares favourably to python here.

EXACTLY!  The issue is that the inconsistent state in lisp is rarely
a legal expression, but an inconsistent state in Python often is.

I'll answer the rest of the post a bit later.  I had an idea I want
to think about.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfs7k3643v6.fsf@black132.ex.ac.uk>
Joe Marshall <···@ccs.neu.edu> writes:

> Alexander Schmolck <··········@gmx.net> writes:
> 
> 
> > Additionally most of the time the code is actively being edited and thus *not*
> > in a consistent state -- this is how most editing errors occur and I don't
> > think lisp compares favourably to python here.
> 
> EXACTLY!  The issue is that the inconsistent state in lisp is rarely
> a legal expression, but an inconsistent state in Python often is.

In case you misinterpreted the above: I meant in *both* python and lisp. The
likelihood of inconsistency in terms of a legal expression that doesn't do
what the superficial observer might think (which wasn't what I meant above) is
certainly considerably greater in lisp than in python (simply because python's
syntax places far more constraints on what a certain parse-tree can look like
as actual code).

I've also tried my best to show that for the examples you presented there is
no need to take an intermediate editing step in pyhthon that involves a
semantically valid but unintended state which could plausibly figure as a
source of errors.

'as
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <65iq805g.fsf@comcast.net>
Alexander Schmolck <··········@gmx.net> writes:

> ·············@comcast.net writes:
>
>> Consider this python code (lines numbered for exposition):

> [lots of snipping]

Ok, I *think* I uncovered the source of my discomfort:

    Python is not context-free

Yes, I know you can fake it by making the lexer keep track of the
indentation level, but I'm allergic to context-sensitive grammars.
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87brshlvey.fsf@thalassa.informatimago.com>
Alexander Schmolck <··········@gmx.net> writes:
> > However, there is a class of *syntactic* error that is possible in
> > python, but is not possible in lisp (or C or any language with
> > balanced delimiters).  Moreover, this class of error is common,
> > frequently encountered during editing, and it cannot be detected
> > mechanically.
> 
> This argument basically boils down to "lisp is more redundant and
> therefore less error prone". This inself is not a valid argument as
> it depends on the type of redundancy and the extend to which this
> redundancy itself causes errors, e.g. by rendering the code more
> obscure by additional verbosity (as in xml compared to sexps);
> whether this redundancy helps or hinders perception and how this
> redundancy interferes with the editing process.
> 
> As an example of such interference in the case of lisp consider the
> example of commenting/deleteing/appending after a line with surplus
> trailing parens (corresponding ot opening parens in earlier
> lines). Conceptually this line is the same as all the other lines in
> the code in the same block, but you have to use quite different (and
> more complicated and error-prone) commands to achieve the same
> editing process. Not so in python.

Sorry  to be silly,  but the  space bar  is that  enormous key  at the
bottom of the keyboard, while  the parethensis are small keys up there
on the top of the keyboard, and need a simultaneous press on the shift
key.  My big  belly never inadvertently lean on  the parenthesis keys,
but on the space bar, yes...



-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Marcin 'Qrczak' Kowalczyk
Subject: Significant whitespace
Date: 
Message-ID: <pan.2003.10.08.10.18.34.557600@knm.org.pl>
On Tue, 07 Oct 2003 21:25:53 +0100, Alexander Schmolck wrote:

> Python removes this significant problem, at as far as I'm aware no real cost
> and plenty of additional gain (less visual clutter, no waste of delimiter
> characters ('{','}') or introduction of keywords that will be sorely missed as
> user-definable names ('begin', 'end')).

There are three choices for a lanuage syntax:
1. Line breaks and indents are significant (Haskell, Python).
2. Line breaks only are significant (Ruby, Unix shell, Visual Basic).
3. Neither is significant (most languages).

I found the syntax of Haskell and Python aesthetic, and tried to introduce
significant whitespace into my own little language. It was surprisingly hard.

The first attempt used a quite minimalistic syntax and had significant
indents. In effect indentation errors usually went undetected and the
program suddently had a different meaning. Since you wouldn't want to
consistently use indentation for all local functions, they used either
braces or indentation - but not both! so it looked very differently
depending on whether you wanted to make use of significant indents or not.
And since it was a functional language, it used quite a lot of nesting.
I quickly abandoned this version.

Although misindenting Haskell code can produce a valid parse, the error
is usually caught either by scoping rules or by the typechecker; my
language was dynamically typed. Haskell doesn't have the "inconsistency"
problem because when you omit a line break which would introduce or close
indentation, you usually don't have to insert braces - syntax rules say
that virtual closing braces are inserted when not inserting it would cause
a parse error. Unfortunately this rule is almost impossible to implement
correctly (current compilers fail to use it correctly in some subtle cases).
There are cases when the language requires a different indentation than
I would like to use (mostly 'if-then-else' and 'let' inside 'do').

Python has a simpler syntax, where indentation is used on the level of
statements as the only delimiting mechanism, and not on the level of
expressions - which can't contain statements. It doesn't allow to replace
indentation with explicit delimiters. Since most expressions have pending
open parens or brackets when cut in the middle (because of mandatory
parens around function arguments), most line breaks inside expressions are
identifiable as insignificant without explicit marking. So it's easy to
design rules which use indentation, at the cost of the inability to
express various things as expressions. It's an imperative language and
such syntax won't fit a functional language where you would want to have
a deeper nesting, and where almost everything can be used inside an
expression.

Moral: Haskell and Python happen to succeed with significant indents
but their rules are hard to adapt to other languages. Significant
indentation constrains the syntax - if you like these constraints, fine,
but it would hurt if a language were incompatible with these constraints.

Having failed with significant indents, I tried to use significant line
breaks in next incarnations of my language, which looked like a good
compromise. The language had a richer syntax this time and it worked
quite well, except that one too often wanted to break a line in a place
which had to be explicitly marked as an insignificant break. I had
troubles with designing a good syntax for some constructs, mainly
if-then-else, being constrained to syntaxes which can be nicely split
into lines.

After experimenting with various syntaxes which used significant line
breaks to separate declarations and statements (delimiting was first done
by an opening word and 'end', later by braces), I tried how it would look
like with explicit semicolons. Surprisingly this opened new ways to build
some syntactic constructs. I finally got an 'if' which I was happy with,
I was no longer forced to choose to either not break a particular long
line or to mark the line break as insignificant, and I could abandon
designing a built-in syntax for catching exceptions because using a
suitable function no longer interfered with line breaking.

Moral is the same. Although designing and implementing a syntax with
significant line breaks and insignificant indentation is much easier than
with significant indentation, it still takes away some freedom of syntax
design which might be noticeable. Perhaps there are subtle ways to apply
significant line breaks to various languages, which you might find with
some luck or experience... I've given up, designing a syntax with
insignificant whitespace is much safer.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Alexander Schmolck
Subject: Re: Significant whitespace
Date: 
Message-ID: <yfssmm3ebc8.fsf@black132.ex.ac.uk>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:

> Moral: Haskell and Python happen to succeed with significant indents
> but their rules are hard to adapt to other languages. Significant
> indentation constrains the syntax - if you like these constraints, fine,
> but it would hurt if a language were incompatible with these constraints.

I'm not surprised -- as I said it is not straighforward to map the significant
indentation scheme to a language that doesn't have python(C/Pascal)'s
statement/expression distinction. My main point is that it is an excellent
choice for a language such as python (and far superior to the alternatives a
la Pascal/C). 

I'm not whitespace bigot: although I abhor C/Pascal I like the syntaxes of
smalltalk, prolog and lisp (maybe I could even partially warm to something in
the APL familiy) :)

'as
From: Tomasz Zielonka
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnqbgn.6rv.t.zielonka@zodiac.mimuw.edu.pl>
·······@ziplip.com napisa�:
> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately.

Well, there is Haskell which also offers indentation-base syntax and one
of it's compilers (GHC) recently added the Template Haskell extension.

This is a statically typed, non-strict purely functional language with
higher order and polymorphic functions, algebraic datatypes, etc. so
it's a BIT different than Python, but it's worth trying :)

PS. Haskell also allows to use {, } and ; instead of indentation. I
    wonder why Python doesn't.

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
From: Tomasz Zielonka
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnqbl0.6rv.t.zielonka@zodiac.mimuw.edu.pl>
·······@ziplip.com napisa�:
> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately.

Well, there is Haskell which also offers indentation-based syntax and one
of its compilers (GHC) recently added the Template Haskell extension.

This is a statically typed, non-strict, purely functional language with
higher order and polymorphic functions, algebraic datatypes,
type-classes base overloading, etc. so it's a BIT different than Python,
but it's worth trying IMO.
:)

PS. Haskell also allows to use {, } and ; instead of indentation. I
    wonder why Python doesn't.

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
From: Tomasz Zielonka
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnqbn2.6rv.t.zielonka@zodiac.mimuw.edu.pl>
·······@ziplip.com napisa�:
> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately.

Well, there is Haskell which also offers indentation-based syntax and
one
of its compilers (GHC) recently added the Template Haskell extension.

This is a statically typed, non-strict, purely functional language with
higher order and polymorphic functions, algebraic datatypes,
type-class based overloading, etc. so it's a BIT different than Python,
but it's worth trying IMO :)

PS. Haskell also allows to use {, } and ; instead of indentation. I
    wonder why Python doesn't.

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
From: Jeremy Yallop
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bljdaa$d0oce$2@ID-114079.news.uni-berlin.de>
Tomasz Zielonka wrote:
> ·······@ziplip.com napisa�:
>> I think everyone who used Python will agree that its syntax is
>> the best thing going for it. 

I've used Python rather a lot, and I don't agree with this, FWIW.

> PS. Haskell also allows to use {, } and ; instead of indentation. I
>     wonder why Python doesn't.

http://groups.google.com/groups?as_umsgid=199803092142.QAA04377%40fermi.eeel.nist.gov

Jeremy.
From: Tomasz Zielonka
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <slrnbnqfg7.k3b.t.zielonka@zodiac.mimuw.edu.pl>
Jeremy Yallop wrote:
>> PS. Haskell also allows to use {, } and ; instead of indentation. I
>>     wonder why Python doesn't.
> 
> http://groups.google.com/groups?as_umsgid=199803092142.QAA04377%40fermi.eeel.nist.gov

A state of the art sophisticated parser? :)))

You almost got me. I don't know very much about Python and I had to
check that # is a beginning of a comment.

Do you know the meaning of 'instead of' ?

You still have to use indentation, right? You can't write:

    if 1: #{ print 2 #} else: #{ print 3 #}

instead of

    if 1: #{
	print 2
    #}	
    else: #{ 
	print 3
    #}

because that would be read as

    if 1:

> Jeremy.

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
From: Dominic
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blj8a1$6kd$05$1@news.t-online.com>
·······@ziplip.com wrote:
> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while 
> keeping its amazing syntax, and if it could be possible to
> add Pythonistic syntax to Lisp or Scheme, while keeping all
> of the functionality and convenience. If the answer is yes,
> would many Python programmers switch to Lisp or Scheme if
> they were offered identation-based syntax?

Well, there's always a programming language which has
more features than another. However documentation,
libraries, software-engineering tools and developer
community have also to be accounted for.

So whenever a special features is deemed necessary
but not available in the language I suggest to use
code generators.

   E.g. you cannot express grammars in C/Java for
   parsing so usually you stick to yacc/bison/flex/cups etc.

   In C++ BOOST provides capabilites to express a parser
   by means of template metaprogramming but compile times
   are huge. In my opinion are old fashioned parser
   generators more transparent.
   So it's probably not worth the trouble.

I have successfuly implemented a simple code generator
for real-time control applications in Python
which outputs C-source.
http://www-user.rhrk.uni-kl.de/~hillbr/public/

Today I'd suggest to use  XML-files to describe
the problem and generate source code from it.
Source code needed for assembling the final
result could also be embedded into the XML-files.

Eclipse uses a kind of JSP to generate code
from templates. (Examples exist
for generating source code for enumerations
which are not yet supported by Java)
However it's still very primitive.
At the rapid pace at which Eclipse
is developed I am curious what way it is going to take.


Ciao,
  Dominic
From: Alex Martelli
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87efb.217818$R32.6985678@news2.tin.it>
·······@ziplip.com wrote:

> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while
> keeping its amazing syntax, and if it could be possible to

You can surely hack a "pre-processor" on top of the Python
interpreter.  With the Python 2.3 architecture of import
hooks, it might even be quite feasible to experiment with
this idea as a pure Python package and distribute it as such:
just add a hook that scans incoming source files (modules)
for definitions and/or occurrences of the 'macros' you want,
and (respectively) squirrels away the definitions, and/or
expands the macros.  As for designing the syntax for macro
definitions and expansions while remaining 'amazing', I'll
pass -- but surely it's not beyond human possibilities;-).

Anyway, see later in this post for a toy-level example.


> add Pythonistic syntax to Lisp or Scheme, while keeping all
> of the functionality and convenience. If the answer is yes,
> would many Python programmers switch to Lisp or Scheme if
> they were offered identation-based syntax?

If you could make all of the existing Python extensions,
libraries, frameworks, etc, instantly available from Lisp or
Scheme, you'd gain a LOT of kudos in the Lisp or Scheme
community, I suspect.  That most existing Python coders
would be happy to leave the semantic simplicity of their
chosen language for the richness of Common Lisp, I very,
very strongly doubt, but in any case until the whole array
of existing extensions &c is available it's not an issue;-).


So, anyway, here's the promised toy-level example of using
custom importers with the new Python 2.3 mechanics to get
macros.  I'm cutting corners to the bone (just to mix a
couple metaphors...) by using the C preprocessor (!) as my
"macro expander", ignoring packages, _and_ only looking for
"C-macro" definitions AND expansions in files with extension
".pyp" (all others, I'll leave alone...).  Oh, also, I do
not worry about saving bytecode for such files -- I'm gonna
preprocess and recompile them on every run of the program
(far too much trouble, when macros exist, to determine
whether a bytecode file is up to date -- one should check
it, not only with respect to the date of ONE source file,
but rather of a hard-to-pin-down collection of macro and
include files... so, in the spirit of cutting corners and
keeping this a VERY toy-level example, I'm punting:-).  So,
here's the gist...:


import sys
import os
import imp

prepro = 'cat %s | gcc -E -'

class MacroImporter(object):

    def __init__(self, path):
        self.path = path

    def find_module(self, modname):
        look_for_file = os.path.join(self.path, modname+'.pyp')
        self.code = os.popen(prepro % look_for_file).read()
        if self.code: return self
        else: return None
        
    def load_module(self, modname):
        mod = imp.new_module(modname)
        sys.modules[modname] = mod
        mod.__file__ = "<Macro-Expanded %s>" % modname
        exec self.code in mod.__dict__
        return mod

sys.path_hooks.append(MacroImporter)

example = open('pippo.pyp', 'w')
example.write('''
#define unless(cond) if not(cond)
def pippo(x):
    print 'x is', x
    unless(x>=2): print '  x is smaller than two'
    unless(x<=4): print '  x is bigger than four'
''')
example.close()

import pippo
pippo.pippo(1)
pippo.pippo(7)


Removing the various oversimplifications, and, in particular, designing
a better macro scheme than gcc -E supplies, is left as a trivial exercise
for the reader (I have in fact devised a perfect scheme, of course, but,
unfortunately, the margins of this post are too narrow for me to write it
down...).


Alex
From: Doug Tolton
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <rc2snvkt2one2n3redvcpmp1tujhbicvu9@4ax.com>
On Fri, 03 Oct 2003 12:40:36 GMT, Alex Martelli <·····@aleax.it>
wrote:

>·······@ziplip.com wrote:
>
>> I think everyone who used Python will agree that its syntax is
>> the best thing going for it. It is very readable and easy
>> for everyone to learn. But, Python does not a have very good
>> macro capabilities, unfortunately. I'd like to know if it may
>> be possible to add a powerful macro system to Python, while
>> keeping its amazing syntax, and if it could be possible to
>
>You can surely hack a "pre-processor" on top of the Python
>interpreter.  With the Python 2.3 architecture of import
>hooks, it might even be quite feasible to experiment with
>this idea as a pure Python package and distribute it as such:
>just add a hook that scans incoming source files (modules)
>for definitions and/or occurrences of the 'macros' you want,
>and (respectively) squirrels away the definitions, and/or
>expands the macros.  As for designing the syntax for macro
>definitions and expansions while remaining 'amazing', I'll
>pass -- but surely it's not beyond human possibilities;-).
>
>Anyway, see later in this post for a toy-level example.
>
>
>> add Pythonistic syntax to Lisp or Scheme, while keeping all
>> of the functionality and convenience. If the answer is yes,
>> would many Python programmers switch to Lisp or Scheme if
>> they were offered identation-based syntax?
>
>If you could make all of the existing Python extensions,
>libraries, frameworks, etc, instantly available from Lisp or
>Scheme, you'd gain a LOT of kudos in the Lisp or Scheme
>community, I suspect.  That most existing Python coders
>would be happy to leave the semantic simplicity of their
>chosen language for the richness of Common Lisp, I very,
>very strongly doubt, but in any case until the whole array
>of existing extensions &c is available it's not an issue;-).
>
>
>So, anyway, here's the promised toy-level example of using
>custom importers with the new Python 2.3 mechanics to get
>macros.  I'm cutting corners to the bone (just to mix a
>couple metaphors...) by using the C preprocessor (!) as my
>"macro expander", ignoring packages, _and_ only looking for
>"C-macro" definitions AND expansions in files with extension
>".pyp" (all others, I'll leave alone...).  Oh, also, I do
>not worry about saving bytecode for such files -- I'm gonna
>preprocess and recompile them on every run of the program
>(far too much trouble, when macros exist, to determine
>whether a bytecode file is up to date -- one should check
>it, not only with respect to the date of ONE source file,
>but rather of a hard-to-pin-down collection of macro and
>include files... so, in the spirit of cutting corners and
>keeping this a VERY toy-level example, I'm punting:-).  So,
>here's the gist...:
>
>
>import sys
>import os
>import imp
>
>prepro = 'cat %s | gcc -E -'
>
>class MacroImporter(object):
>
>    def __init__(self, path):
>        self.path = path
>
>    def find_module(self, modname):
>        look_for_file = os.path.join(self.path, modname+'.pyp')
>        self.code = os.popen(prepro % look_for_file).read()
>        if self.code: return self
>        else: return None
>        
>    def load_module(self, modname):
>        mod = imp.new_module(modname)
>        sys.modules[modname] = mod
>        mod.__file__ = "<Macro-Expanded %s>" % modname
>        exec self.code in mod.__dict__
>        return mod
>
>sys.path_hooks.append(MacroImporter)
>
>example = open('pippo.pyp', 'w')
>example.write('''
>#define unless(cond) if not(cond)
>def pippo(x):
>    print 'x is', x
>    unless(x>=2): print '  x is smaller than two'
>    unless(x<=4): print '  x is bigger than four'
>''')
>example.close()
>
>import pippo
>pippo.pippo(1)
>pippo.pippo(7)
>
>
>Removing the various oversimplifications, and, in particular, designing
>a better macro scheme than gcc -E supplies, is left as a trivial exercise
>for the reader (I have in fact devised a perfect scheme, of course, but,
>unfortunately, the margins of this post are too narrow for me to write it
>down...).
>
>
>Alex

Alex,

I'm somewhat suprised to see you posting a toy example of <gasp>
Macro's in Python.  When this discussion came up on comp.lang.python,
to say that you were averse to them would be a major understatement.

http://groups.google.com/groups?q=Alex+Martelli+Macros+group:comp.lang.python.*&hl=en&lr=&ie=UTF-8&group=comp.lang.python.*&selm=bht2gg030i6%40enews2.newsguy.com&rnum=2

What caused your change of heart?



Doug Tolton
(format t ···@~a~a.~a" "dtolton" "ya" "hoo" "com")
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F7DB8C0.8070806@cs.nyu.edu>
·······@ziplip.com wrote:
> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while 
> keeping its amazing syntax, and if it could be possible to
> add Pythonistic syntax to Lisp or Scheme, while keeping all
> of the functionality and convenience. If the answer is yes,
> would many Python programmers switch to Lisp or Scheme if
> they were offered identation-based syntax?

Why do I feel like crying? :{

Cheers
--
Marco
From: synthespian
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bllte0$dk586$1@ID-78052.news.uni-berlin.de>
Marco Antoniotti wrote:
> 
> 
> ·······@ziplip.com wrote:
> 
>> I think everyone who used Python will agree that its syntax is
>> the best thing going for it. It is very readable and easy
>> for everyone to learn. But, Python does not a have very good
>> macro capabilities, unfortunately. I'd like to know if it may
>> be possible to add a powerful macro system to Python, while keeping 
>> its amazing syntax, and if it could be possible to
>> add Pythonistic syntax to Lisp or Scheme, while keeping all
>> of the functionality and convenience. If the answer is yes,
>> would many Python programmers switch to Lisp or Scheme if
>> they were offered identation-based syntax?
> 
> 
> Why do I feel like crying? :{
> 
> Cheers
> -- 
> Marco
> 
Because it makes you wonder: "why?"

Henry
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfs65j0g4zv.fsf@black132.ex.ac.uk>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Why do I feel like crying? :{

Could it be because you've actually got some rational argument against
significant whitespace a la python?!

'as
From: Paolo Amoroso
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87brsyozfw.fsf@plato.moon.paoloamoroso.it>
[followup to comp.lang.lisp only]

mike420 writes:

> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy

I think everyone who used Lisp will agree that its syntax is the best
thing going for it.


> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while 
> keeping its amazing syntax, and if it could be possible to

Yes, it can be done. This is called "Greenspun's Tenth Rule of
Programming".


Paolo
-- 
Paolo Amoroso <·······@mclink.it>
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <u16qghjj.fsf@ccs.neu.edu>
Paolo Amoroso <·······@mclink.it> writes:

> [followup to comp.lang.lisp only]
>
> mike420 writes:
>
>> I think everyone who used Python will agree that its syntax is
>> the best thing going for it. It is very readable and easy
>
> I think everyone who used Lisp will agree that its syntax is the best
> thing going for it.

I wouldn't!  I think Lisp has a lot *more* than just syntax going for it!
From: David Golden
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <235b265c.0310041310.55fee9b3@posting.google.com>
Sugar exists. http://redhog.org/Projects/Programming/Current/Sugar/


let
 group
  foo
   + 1 2
  bar
   + 3 4
 + foo bar
From: Ed Avis
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <l1oewwhjl9.fsf@budvar.future-i.net>
·······@ziplip.com writes:

>I'd like to know if it may be possible to add a powerful macro system
>to Python, while keeping its amazing syntax,

I fear it would not be.  I can't say for certain but I found that the
syntax rules out nesting statements inside expressions (without adding
some kind of explicit bracketing, which rather defeats the point of
Python syntax) and you might run into similar difficulties if adding
macros.  It's a very clean syntax (well, with a few anomalies) but
this is at the price of a rigid separation between statements and
expressions, which doesn't fit well with the Lisp-like way of doing
things.

Myself I rather like the option chosen by Haskell, to define an
indentation-based syntax which is equivalent to one with bracketing,
and let you choose either.  You might do better to add a new syntax to
Lisp than to add macro capabilities to Python.  Dylan is one Lisp
derivative with a slightly more Algol-like syntax, heh, Logo is
another; GNU proposed some thing called 'CTAX' which was a C-like
syntax for Guile Scheme, I don't know if it is usable.

If the indentation thing appeals, maybe you could preprocess Lisp
adding a new kind of bracket - say (: - which closes at the next line
of code on the same indentation level.  Eg

    (: hello
       there
    (goodbye)

would be equivalent to

    (hello
     there)
    (goodbye)

I dunno, this has probably already been done.

-- 
Ed Avis <··@membled.com>
From: Corey Coughlin
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <a8623416.0310071319.34162404@posting.google.com>
I was never very fond of lisp.  I guess I mean scheme technically, I
took the Ableson and Sussman course back in college, so that's what I
learned of scheme, lisp in general I've mostly used embedded in other
things.  In general, it always seemed to me that a lot of the design
choices in lisp are driven more by elegance and simplicity than
usability.  When it comes to programming languages, I really want the
language to be a good tool, and to do as much of the work for me as
possible.  Using parentheses and rpn everywhere makes lisp very easy
to parse, but I'd rather have something easy for me to understand and
hard for the computer to parse.  (Not to mention car, cdr, cadr, and
so on vs. index notation, sheesh.)  That's why I prefer python, you
get a nice algebraic syntax with infix and equal signs, and it's easy
understand.  Taking out ';' at the ends of lines and indenting for
blocks helps me by removing the clutter and letting me see the code. 
And yes, I'm sure you can write macros in lisp to interpret infix
operators and indexing and whatever you want, but learning a core
language that's wildly non-intuitive so that I can make it more
intuitive never seemed like a good use of my time.  Python is
intuitive to me out of the box, and it just keeps getting better, so I
think I'll stick with it.
From: Peter Seibel
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m3brssr80v.fsf@javamonkey.com>
··············@attbi.com (Corey Coughlin) writes:

> Using parentheses and rpn everywhere makes lisp very easy to parse,
> but I'd rather have something easy for me to understand and hard for
> the computer to parse.

That would be a strong argument--seriously--if the only folks who
benefited from the trivial mapping between Lisp's surface syntax and
underlying were the compiler writers. I certainly agree that if by
expending some extra effort once compiler writers can save their users
effort every time they write a program that is a good trade off.

If the only thing a "regular" programmer ever does with a language's
syntax is read and write it, then the only balance to be struck is
between the perhaps conflicting goals of readability and writability.
(For instance more concise code may be more "writable" but taken to an
extreme it may be "write only".) But "machine parsability" beyond,
perhaps, being amennable to normal machine parsing techniques (LL,
LALR, etc.) should not be a consideration. So I agree with you.

But Lisp's syntax is not the way it is to make the compiler writer's
job easier. In Lisp "regular" programmers also interact with the code
as data. We can easily write code generators (i.e. macros) that are
handed a data representation of some code, or parts of code, and have
only to return a new data structure representing the generated code.
This is such a useful technique that it's built into the compiler--it
will run our code generators when it compiles our code so we don't
have to screw around figuring out how to generate code at runtime and
get it loaded into our program. *That's* why we don't mind, and, in
fact, actively like, Lisp's syntax.

The point is not that the syntax, taking in total isolation from the
rest of the language, is necessarily the best of all possible syntaxi.
The point is that the syntax makes other things possible that *way*
outweigh whatever negatives the syntax may have.

I'd humbly suggest that if you can't see *any* reason why someone
would prefer Lisp's syntax, then you're not missing some fact about
the syntax itself but about how other language features are supported
by the syntax.

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Carlo v. Dango
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwpq36n8myya52@news.kadnet.dom>
> I'd humbly suggest that if you can't see *any* reason why someone
> would prefer Lisp's syntax, then you're not missing some fact about
> the syntax itself but about how other language features are supported
> by the syntax.

sure, but it seems like noone was able to let CLOS have
(virtual) inner classes,
methods inside methods,
virtual methods (yeah I know about those stupid generic functions :),
method overloading,
A decent API (I tried playing with it.. it doesn't even have a freaking 
date library as standard ;-p

Yes I agree with the compile time macro expansion is a nice thing. 
However, if I want to do some serious changes to the structure of objects 
and classes (i.e. create a new kind of objects) then I have to spend a 
long time finding out how the CLOS people hacked together their 
representation of classes, methods, method call etc... it has been far 
easier for me to just do some small changes using __getattribute__ and 
metaclasses in python. So in that respect Im not really sure the macro 
idea is advantageous for other than 'straight away' macros...

yes this mail is provocative.. please count slowly to 10 before replying 
if you disagree with my point of view (and I know Pascal will disagree ;-) 
... not that I ever seen him angry ;-)


Carlo van Dango

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F83CE5A.28C719F8@setf.de>
"Carlo v. Dango" wrote:
> 
> > I'd humbly suggest that if you can't see *any* reason why someone
> > would prefer Lisp's syntax, then you're not missing some fact about
> > the syntax itself but about how other language features are supported
> > by the syntax.
> 
> sure, but it seems like noone was able to let CLOS have
> (virtual) inner classes,
> methods inside methods,
> virtual methods (yeah I know about those stupid generic functions :),
> method overloading,
> A decent API (I tried playing with it.. it doesn't even have a freaking
> date library as standard ;-p
> 
> Yes I agree with the compile time macro expansion is a nice thing.
> However, if I want to do some serious changes to the structure of objects
> and classes (i.e. create a new kind of objects) then I have to spend a
> long time finding out how the CLOS people hacked together their
> representation of classes, methods, method call etc... it has been far
> easier for me to just do some small changes using __getattribute__ and
> metaclasses in python. So in that respect Im not really sure the macro
> idea is advantageous for other than 'straight away' macros...
> 
> yes this mail is provocative.. please count slowly to 10 before replying
> if you disagree with my point of view (and I know Pascal will disagree ;-)
> ... not that I ever seen him angry ;-)

one might benefit more from reasoned examples, comparisons, and questions than
from vacuous vitriol.

...
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <32Wgb.10$KR3.104@typhoon.nyu.edu>
Carlo v. Dango wrote:

> 
>> I'd humbly suggest that if you can't see *any* reason why someone
>> would prefer Lisp's syntax, then you're not missing some fact about
>> the syntax itself but about how other language features are supported
>> by the syntax.
> 
> 
> sure, but it seems like noone was able to let CLOS have
> (virtual) inner classes,
> methods inside methods,
> virtual methods (yeah I know about those stupid generic functions :),
> method overloading,

 From what you are saying it is obvious that you do not know what you 
are talking about.

True, you do not have "inner" classes, but that has never stopped 
anybody from writing good code.  As for your comments on methods and 
generic functions it is obvious that you do not know what multiple 
dispatching is (yes, there is an ugly hacked up Python library to do 
that floating around; I do not know if it will make it it 3.0), so you 
comment looses value immediately.

> A decent API (I tried playing with it.. it doesn't even have a freaking 
> date library as standard ;-p


Apart form the fact that the language has GET-UNIVERSAL-TIME, 
DECODE-UNIVERSAL-TIME etc etc, you can get a nice and portable (across 
all n > 1.8 CL implementations) date parsing library at

http://www.cliki.net/net-telent-date



> 
> Yes I agree with the compile time

The term "compile" should already make you think.

> macro expansion is a nice thing. 
> However, if I want to do some serious changes to the structure of 
> objects and classes (i.e. create a new kind of objects) then I have to 
> spend a long time finding out how the CLOS people hacked together their 
> representation of classes, methods, method call etc... it has been far 
> easier for me to just do some small changes using __getattribute__ and 
> metaclasses in python. So in that respect Im not really sure the macro 
> idea is advantageous for other than 'straight away' macros...

And how exactly does CLOS forbid you to do the same? You can do that 
using accessor, reader and writer generic functions (ooops, I forgot 
that you do not know enough about them :) ) If that is not enough, the 
CLOS Metaobject Protocol is available in practically all major CL 
implementations (and that is more than the 1.8 Python implementations 
out there).  And it seems to me that

> 
> yes this mail is provocative.. please count slowly to 10 before replying 
> if you disagree with my point of view (and I know Pascal will disagree 
> ;-) ... not that I ever seen him angry ;-)


I counted until 42 :)

Cheers
--
Marco
From: David Mertz
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <mailman.1065642859.16213.python-list@python.org>
Marco Antoniotti <·······@cs.nyu.edu> wrote previously:
|As for your comments on methods and generic functions it is obvious
|that you do not know what multiple dispatching is (yes, there is an ugly
|hacked up Python library to do that floating around; I do not know if it
|will make it it 3.0), so you comment looses value immediately.

This is absolutely replete with ignorance.  The multimethods module I
present at:

  http://www-106.ibm.com/developerworks/linux/library/l-pydisp.html

Is neither ugly nor hacked, and is just as general as what you would do
in Lisp (but with nicer looking syntax).  Neel Krishnaswami, and
probably other folks, have written similar modules before I did; I don't
claim to be all that original--it's not that difficult to do, after all.

You can grab it directly, btw, at:

  http://www.gnosis.cx/download/gnosis/magic/multimethods.py

Now OF COURSE, multimethods.py will not "make it into 3.0"--it's not in
2.3 or any other version either.  It's a 3rd party library... and it
will continue to work just fine whenever 3.0 comes out.  Most likely
with no changes, but I'll update it if needed (unless I get hit by a
bus, I suppose, but someone else could easily do the same).

Yours, David...

--
 ·····@   _/_/_/_/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY:_/_/_/_/ v i
gnosis  _/_/                    Postmodern Enterprises         _/_/  s r
.cx    _/_/  MAKERS OF CHAOS....                              _/_/   i u
      _/_/_/_/_/ LOOK FOR IT IN A NEIGHBORHOOD NEAR YOU_/_/_/_/_/    g s
From: Thomas F. Burdick
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <xcvfzi3r2ge.fsf@famine.OCF.Berkeley.EDU>
"Carlo v. Dango" <····@soetu.eu> writes:

> > I'd humbly suggest that if you can't see *any* reason why someone
> > would prefer Lisp's syntax, then you're not missing some fact about
> > the syntax itself but about how other language features are supported
> > by the syntax.
> 
> sure, but it seems like noone was able to let CLOS have
> (virtual) inner classes,

This is kind of like saying we weren't able to have setjmp/longjmp;
yeah, but doing so makes no sense.

> methods inside methods,

There was a proposal to add lexically-scoped methods, but it got
tossed because no one liked it.

> virtual methods (yeah I know about those stupid generic functions :),

As has been already stated, we only have "virtual methods".

> method overloading,

How could you have both noncongruent argument lists, and multiple
dispatch?  With an either/or like that, Lisp chose the right one.

> A decent API (I tried playing with it.. it doesn't even have a freaking 
> date library as standard ;-p

Who does?  Have all that stuff standard, I mean.  Python doesn't even
have a standard.  We have some date support in ANSI --  get the rest from your
vendor (commercial or free).

> yes this mail is provocative..

Seems more ignorant, to me.  I guess when you're conversing on an
archived forum, that can seem like the same thing, though.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0810031201410001@k-137-79-50-101.jpl.nasa.gov>
In article <···············@famine.OCF.Berkeley.EDU>,
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:

> > method overloading,
> 
> How could you have both noncongruent argument lists, and multiple
> dispatch?

C++ seems to manage it somehow.

#include <stdio.h>

void foo(int x, int y) { printf("1\n"); }
void foo(double x, int y) { printf("2\n"); }
void foo(char* x) { printf("3\n"); }

main() {
  foo(1,2);
  foo(1.2,2);
  foo("foo");
}

compiles and runs without complaint.

E.
From: Vis Mike
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm32a3$iti$1@bob.news.rcn.net>
"Erann Gat" <··························@jpl.nasa.gov> wrote in message
················································@k-137-79-50-101.jpl.nasa.go
v...
> In article <···············@famine.OCF.Berkeley.EDU>,
> ···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:
>
> > > method overloading,
> >
> > How could you have both noncongruent argument lists, and multiple
> > dispatch?
>
> C++ seems to manage it somehow.
>
> #include <stdio.h>
>
> void foo(int x, int y) { printf("1\n"); }
> void foo(double x, int y) { printf("2\n"); }
> void foo(char* x) { printf("3\n"); }
>
> main() {
>   foo(1,2);
>   foo(1.2,2);
>   foo("foo");
> }
>
> compiles and runs without complaint.
>
> E.

Ahh, but overloading only works at compile time:

void foo( SomeBaseObject* object );
void foo( SomeDerivedObject* object );

doesn't work if you're using a base class pointer for all your derived
classes.

Mike
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0910030844080001@192.168.1.51>
In article <············@bob.news.rcn.net>, "Vis Mike"
<···········@_nospam_hotmail.com> wrote:

> "Erann Gat" <··························@jpl.nasa.gov> wrote in message
> ················································@k-137-79-50-101.jpl.nasa.go
> v...
> > In article <···············@famine.OCF.Berkeley.EDU>,
> > ···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:
> >
> > > > method overloading,
> > >
> > > How could you have both noncongruent argument lists, and multiple
> > > dispatch?
> >
> > C++ seems to manage it somehow.
> >
> > #include <stdio.h>
> >
> > void foo(int x, int y) { printf("1\n"); }
> > void foo(double x, int y) { printf("2\n"); }
> > void foo(char* x) { printf("3\n"); }
> >
> > main() {
> >   foo(1,2);
> >   foo(1.2,2);
> >   foo("foo");
> > }
> >
> > compiles and runs without complaint.
> >
> > E.
> 
> Ahh, but overloading only works at compile time:

That's irrelevant.  When it happens doesn't change the fact that this
proves it (multiple dispatch with non-congruent arglists) is possible. 
Nothing prevents you from using the same algorithm at run time.

E.
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <65iynsw4.fsf@ccs.neu.edu>
··························@jpl.nasa.gov (Erann Gat) writes:

> In article <············@bob.news.rcn.net>, "Vis Mike"
> <···········@_nospam_hotmail.com> wrote:
>
>> 
>> Ahh, but overloading only works at compile time:
>
> That's irrelevant.  When it happens doesn't change the fact that this
> proves it (multiple dispatch with non-congruent arglists) is possible. 
> Nothing prevents you from using the same algorithm at run time.
>

In fact, on a project I'm working on I have to handle overloaded
functions.  I used the MOP to adjust how method combination worked
and now the generic functions first perform an arity-based dispatch.
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm3ros$al7$2@news-int2.gatech.edu>
> Ahh, but overloading only works at compile time:
> 
> void foo( SomeBaseObject* object );
> void foo( SomeDerivedObject* object );
> 
> doesn't work if you're using a base class pointer for all your derived
> classes.
I think that the point was that the overload resolution rules can handle the
situation. Nothing in these rules prevents them from being applied to a
dynamically dispatched case.
From: Christopher C. Stacy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <u4qyjto7y.fsf@dtpq.com>
>>>>> On 08 Oct 2003 11:47:45 -0700, Thomas F Burdick ("Thomas") writes:
 Thomas> How could you have both noncongruent argument lists, and multiple
 Thomas> dispatch?  With an either/or like that, Lisp chose the right one.

This reason that Common Lisp made this choice is not because non-congruent
multiple-dispatch methods are impossible. To dispatch: instead of just
matching the types of the args, consider only those handler entries that
have the correct shape (length) as well.

JAVA has multi-methods with non-congruent arglist.
(It doesn't have multiple inheritence, but that doesn't 
matter to dynamic type dispatching, except maybe in how 
you implement searching your handler tables.)  In JAVA, 
the correspondance of the "signature" of the function call
and the method definition are what's important;
and there are no restricting "generic functions".

public class RandomAccessFile extends Object,implements DataOutput {
  public void write(byte[] b) throws IOException;
  public void write(byte[] b, int off, int len) throws IOException;
  ...
}

CLOS imposes an aesthetic design restriction on the programmer:
methods with the same name should be conceptually doing the
same function, and therefore should be all taking the same args.
The generic function is the documentation of that mono protocol.
This is one of the few places that Lisp takes a facist attitude.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm20rh$2t$1@newsreader2.netcologne.de>
Christopher C. Stacy wrote:

> JAVA has multi-methods with non-congruent arglist.
> (It doesn't have multiple inheritence, but that doesn't 
> matter to dynamic type dispatching, except maybe in how 
> you implement searching your handler tables.)  In JAVA, 
> the correspondance of the "signature" of the function call
> and the method definition are what's important;
> and there are no restricting "generic functions".
> 
> public class RandomAccessFile extends Object,implements DataOutput {
>   public void write(byte[] b) throws IOException;
>   public void write(byte[] b, int off, int len) throws IOException;
>   ...
> }

Maybe this is just a terminological issue, but in my book these are not 
multi-methods. In Java, methods with the same name but different 
signatures are selected at compile time, and this is rather like having 
the parameter types as part of the method name.

This can lead to subtle bugs. Here is an example in Java:

public class test {

     static void m(Object o) {
       System.out.println("m/Object");
     }

     static void m(String s) {
       System.out.println("m/String");
     }

     static void n(Object o) {
       m(o);
     }

     public static void main(String[] args) {
       n("test");
     }

}

This prints "m/Object", instead of "m/String" as you might expect. (This 
is one of the reasons why the Visitor pattern is relatively tedious to 
implement in Java.)


Pascal
From: Erann Gat
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <my-first-name.my-last-name-0810031534530001@k-137-79-50-101.jpl.nasa.gov>
In article <···········@newsreader2.netcologne.de>, Pascal Costanza
<········@web.de> wrote:

> Christopher C. Stacy wrote:
> 
> > JAVA has multi-methods with non-congruent arglist.
> > (It doesn't have multiple inheritence, but that doesn't 
> > matter to dynamic type dispatching, except maybe in how 
> > you implement searching your handler tables.)  In JAVA, 
> > the correspondance of the "signature" of the function call
> > and the method definition are what's important;
> > and there are no restricting "generic functions".
> > 
> > public class RandomAccessFile extends Object,implements DataOutput {
> >   public void write(byte[] b) throws IOException;
> >   public void write(byte[] b, int off, int len) throws IOException;
> >   ...
> > }
> 
> Maybe this is just a terminological issue, but in my book these are not 
> multi-methods. In Java, methods with the same name but different 
> signatures are selected at compile time,

When the selection is done is immaterial.  The point is that it's done at
all.  There's no reason why the same algorithm that is used to select
methods at compile time can't also be used to select methods at run time. 
The claim that congruent argument lists are necessary for multi-method
dispatch is clearly false.

> and this is rather like having 
> the parameter types as part of the method name.

No.  It's the "system" keeping track of the types, not the user.  That's
the key.  The fact that C++ and Java just happen to do it at compile time
rather than at run time is a red herring.

> 
> This can lead to subtle bugs. Here is an example in Java:

These "subtle bugs" are a reflection of the limitation of compile-time
type inference in Java, not a limitation of multi-method dispatch with
non-congruent argument lists.

E.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm262l$6ng$1@newsreader2.netcologne.de>
Erann Gat wrote:

> In article <···········@newsreader2.netcologne.de>, Pascal Costanza
> <········@web.de> wrote:
> 
> 
>>Christopher C. Stacy wrote:
>>
>>
>>>JAVA has multi-methods with non-congruent arglist.
>>>(It doesn't have multiple inheritence, but that doesn't 
>>>matter to dynamic type dispatching, except maybe in how 
>>>you implement searching your handler tables.)  In JAVA, 
>>>the correspondance of the "signature" of the function call
>>>and the method definition are what's important;
>>>and there are no restricting "generic functions".
>>>
>>>public class RandomAccessFile extends Object,implements DataOutput {
>>>  public void write(byte[] b) throws IOException;
>>>  public void write(byte[] b, int off, int len) throws IOException;
>>>  ...
>>>}
>>
>>Maybe this is just a terminological issue, but in my book these are not 
>>multi-methods. In Java, methods with the same name but different 
>>signatures are selected at compile time,
> 
> 
> When the selection is done is immaterial.  The point is that it's done at
> all.  There's no reason why the same algorithm that is used to select
> methods at compile time can't also be used to select methods at run time. 
> The claim that congruent argument lists are necessary for multi-method
> dispatch is clearly false.
> 
> 
>>and this is rather like having 
>>the parameter types as part of the method name.
> 
> 
> No.  It's the "system" keeping track of the types, not the user.  That's
> the key.  The fact that C++ and Java just happen to do it at compile time
> rather than at run time is a red herring.
> 
> 
>>This can lead to subtle bugs. Here is an example in Java:
> 
> 
> These "subtle bugs" are a reflection of the limitation of compile-time
> type inference in Java, not a limitation of multi-method dispatch with
> non-congruent argument lists.

OK, you're right. It seems to me that the common terminology uses 
"multiple dispatch" for method selection at runtime and "method 
overloading" for method selection at compile time. (for example, see 
http://www.wikipedia.org/wiki/Multiple_dispatch )

However, maybe it would be better to instead talk about static and 
dynamic dispatch, which also reflects the analogy to static and dynamic 
typing.

According to this proposed terminology, Java would be a language that 
uses single dynamic dispatch and multiple static dispatch. C++ would be 
a language that generally uses multiple static dispatch but allows for 
single dynamic dispatch. Smalltalk uses single dynamic dispatch and no 
multiple dispatch whatsoever.

Sounds good. ;)


Pascal
From: Thomas A. Russ
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <ymivfqyl627.fsf@sevak.isi.edu>
··························@jpl.nasa.gov (Erann Gat) writes:

> In article <···········@newsreader2.netcologne.de>, Pascal Costanza
> <········@web.de> wrote:
> 
> > 
> > Maybe this is just a terminological issue, but in my book these are not 
> > multi-methods. In Java, methods with the same name but different 
> > signatures are selected at compile time,
> 
> When the selection is done is immaterial.  The point is that it's done at
> all.  There's no reason why the same algorithm that is used to select
> methods at compile time can't also be used to select methods at run time. 
> The claim that congruent argument lists are necessary for multi-method
> dispatch is clearly false.

While strictly true, this does not mean that one could easily add such a 
feature to Common Lisp.  The problems with non-congruent argument lists
arise when one makes use of things like the &optional or &rest argument
list options.  They can then make the proper choice of method ambiguous, 
which would be a bad thing.

For example:

(defmethod foo ((a1 X) (a2 Y)) ...)
(defmethod foo ((a1 X) &optional o1 o2) ...)
(defmethod foo ((a1 X) &rest r1) ...)

Which method should be called for:

  (foo (make-instance 'X) (make-instance 'Y))

how about for

  (foo (make-instance 'X) 2 3)

You would have to have some sort of precedence rule for determining how
matching of arguments proceeds when there are ambiguous matches between
the parameters.  The CL solution is to not let you write code like
this.  It is clearly not the only solution, but it does have the benefit 
of simplifying both the algorithm used by the language and making it
easier to comprehend and predict what the code will do.

There is also a philosophical and design issue involved.  One can argue
that "methods" with different "signatures" are, in fact, different
functions rather than different methods of a single function.  The test
that one would apply is whether just changing the types of the existing
arguments is sufficient to get a different method.  If yes, then you
really have methods.  As a practical matter, if you have a different
calling sequence for the function, then it really is like having a
different function that just happens to share the name.

On the other hand, it also seems to me that a lot of the function
overloading that I have seen in Java programs is just there to make up
for the lack of optional or keyword arguments.  This seems especially
true in constructors, where the main constructor has all the arguments
and the overloaded ones allow the omission of certain arguments, which
then get default values.  This is handled, IMHO, much more cleanly with
the keyword arguments and default values used in CL.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm0t40$614$1@newsreader2.netcologne.de>
Carlo v. Dango wrote:

> 
>> I'd humbly suggest that if you can't see *any* reason why someone
>> would prefer Lisp's syntax, then you're not missing some fact about
>> the syntax itself but about how other language features are supported
>> by the syntax.
> 
> 
> sure, but it seems like noone was able to let CLOS have
> (virtual) inner classes,
> methods inside methods,
> virtual methods (yeah I know about those stupid generic functions :),
> method overloading,

+ Inner classes only make sense when the language requires you to put 
method definitions inside of class definitions. It doesn't make a lot of 
sense to put a class definition inside another class when it only 
consists of field definitions, as is the case in CLOS. (Except for 
having the benefit of additional namespaces, but namespaces are handled 
differently in Common Lisp.)

+ So what you want is method definitions inside of other methods. Of 
course, this is possible. Here is a little toy example that sketches how 
you can achieve this:

(defclass person ()
   ((name :accessor name :initarg :name)
    (address :accessor address :initarg :address)))

(defun make-out-method (person)
   (with-slots (name address) person
     (defmethod out ((p (eql person)))
       (format t "Name: ~A; address: ~A~%" name address))))

(defvar *pascal* (make-instance 'person :name "Pascal" :address "Bonn"))

(make-out-method *pascal*)

(out *pascal*)

=> Name: Pascal; address: Bonn

+ All methods in CLOS are virtual. What do you mean?

+ Method overloading is a way to have static dispatch, and this doesn't 
fit well with a dynamic language. (Apart from that, static dispatch is a 
source for some nasty bugs.)

What you probably really mean here is that there are some strict 
compatibility requirements wrt the lambda lists of methods that belong 
to the same generic function. I don't think Common Lispers have serious 
issues with these requirements.

In general, dynamic type checking in Common Lisp makes these things much 
easier than you might think in case you have only considered statically 
typed languages so far.

> A decent API (I tried playing with it.. it doesn't even have a freaking 
> date library as standard ;-p

No language with an official standard (ANSI, ISO, etc.) defines 
everything you might ever need in its standard. That's simply not 
possible. Standardized languages rely on vendor support, and more often 
than not, community-driven de-facto standards emerge.

Single-vendor languages follow a totally different approach in this 
regard. You are comparing apples and oranges here.

One can have a debate about language standards vs. single-vendor 
languages, but that's a different issue altogether.

Baseline: If you are looking for a decent date library, check out what 
Common Lisp vendors have to offer and/or what is available from third 
parties.

> Yes I agree with the compile time macro expansion is a nice thing. 
> However, if I want to do some serious changes to the structure of 
> objects and classes (i.e. create a new kind of objects) then I have to 
> spend a long time finding out how the CLOS people hacked together their 
> representation of classes, methods, method call etc... it has been far 
> easier for me to just do some small changes using __getattribute__ and 
> metaclasses in python. So in that respect Im not really sure the macro 
> idea is advantageous for other than 'straight away' macros...

Are you sure that you are not confusing macros and the CLOS MOP here? 
(Your remarks are too general to be able to comment on this.)

> yes this mail is provocative.. please count slowly to 10 before replying 
> if you disagree with my point of view (and I know Pascal will disagree 
> ;-) ... not that I ever seen him angry ;-)

grrr

;)


Pascal
From: Joe Marshall
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <y8vvbggv.fsf@ccs.neu.edu>
"Carlo v. Dango" <····@soetu.eu> writes:

>> I'd humbly suggest that if you can't see *any* reason why someone
>> would prefer Lisp's syntax, then you're not missing some fact about
>> the syntax itself but about how other language features are supported
>> by the syntax.
>
> Sure, but it seems like no one was able to let CLOS have
> (virtual) inner classes,

Um.  What on earth would that mean?  I know what it means in Java
and such, but since CLOS classes are not conflated with lexical
scope, there's nothing to be `inner' to.

> methods inside methods,

What would one do with one of those?  How would that differ
from, say, FLET or LABELS?

> virtual methods (yeah I know about those stupid generic functions :),

Since all CLOS is dynamic dispatch (i.e. virtual), what are you
talking about?

> method overloading,

Now I'm *really* confused.  I thought method overloading involved
having a method do something different depending on the type of
arguments presented to it.  CLOS certainly does that.

> A decent API (I tried playing with it.. it doesn't even have a
> freaking date library as standard ;-p

I was unaware that a date library was so critical to an
object-oriented implementation.

> yes this mail is provocative.. please count slowly to 10 before
> replying if you disagree with my point of view (and I know Pascal will
> disagree ;-)

I'll wait until you have a coherent point of view to disagree with.
From: Christopher C. Stacy
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <uvfqzs7qr.fsf@dtpq.com>
>>>>> On Wed, 08 Oct 2003 16:51:44 -0400, Joe Marshall ("Joe") writes:
 Joe> "Carlo v. Dango" <····@soetu.eu> writes:

 >> method overloading,

 Joe> Now I'm *really* confused.  I thought method overloading involved
 Joe> having a method do something different depending on the type of
 Joe> arguments presented to it.  CLOS certainly does that.

He probably means "operator overloading" -- in languages where
there is a difference between built-in operators and functions,
their OOP features let them put methods on things like "+".

Lisp doesn't let you do that, because it turns out to be a bad idea.
When you go reading someone's program, what you really want is for
the standard operators to be doing the standard and completely 
understood thing.   Most commonly, the operators that people in C++
like to overload are the mathematical ones, like "*" and "+".
Lisp has carefully defined those operations to do all the things
that are both well-understood (like complex numbers) and missing
from languages like C++.    And in Lisp if you want to do some 
other kind of arithmetic, you must make up your names for those
operators.  This is considered to be a good feature.

Not surprisingly, the designers of JAVA understood this as well:
JAVA doesn't let you overload operators, either.
From: Matthias
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <36wbrsqkcnr.fsf@chagall.ti.uni-mannheim.de>
······@dtpq.com (Christopher C. Stacy) writes:

> He probably means "operator overloading" -- in languages where
> there is a difference between built-in operators and functions,
> their OOP features let them put methods on things like "+".
> [...] 
> And in Lisp if you want to do some 
> other kind of arithmetic, you must make up your names for those
> operators.  This is considered to be a good feature.

In comp.lang.lisp there was recently a thread discussing why not all
CL-types were also CL-classes and all functions CLOS-methods (so that
operator overloading would be possible).  I think the outcome was more
or less "it happened by historic accident and it's easier to write
fast compilers then".  In general, taking away flexibility from the
programmer is not in the spirit of Lisp, though.
From: james anderson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3F852FB9.126B3EC3@setf.de>
Matthias wrote:
> 
> ······@dtpq.com (Christopher C. Stacy) writes:
> 
> > He probably means "operator overloading" -- in languages where
> > there is a difference between built-in operators and functions,
> > their OOP features let them put methods on things like "+".
> > [...]
> > And in Lisp if you want to do some
> > other kind of arithmetic, you must make up your names for those
> > operators.  This is considered to be a good feature.
> 
> In comp.lang.lisp there was recently a thread discussing why not all
> CL-types were also CL-classes and all functions CLOS-methods (so that
> operator overloading would be possible).  I think the outcome was more
> or less "it happened by historic accident and it's easier to write
> fast compilers then".

that is not an accurate restatement of the conclusion which i recall. i
suggest that more accurate summary would be:

1. should one need operators which "look" like the standard operators, but
which have a different defined semantics, one places their names in a package
which is isolated from :common-lisp, and either codes with reference to that
package or exports them from that package and codes with reference to a
package which inherits those symbols in preference to those exported from the
:common-lisp package.

2. one does not want to specialize the standard operators other than in the
ways which the standard permits, as not only other applications, but also the
implementation itself may depend on that they have the semantics which the
standard specifies.


>    In general, taking away flexibility from the
> programmer is not in the spirit of Lisp, though.

one might argue, that the standard should have specified that a conforming
implementation not depend on the definitions named by symbols in the
:common-lisp package itself, but instead use it's internal functions. in order
to be convincing, the argument would need to identify use cases which option
(1.) does not support.

one can even rename the :common-lisp package and provide their one. one should
not, however, expect all programs to tolerate such a change.

...
From: Ingvar Mattsson
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <873ce2k6fa.fsf@gruk.tech.ensign.ftech.net>
······@dtpq.com (Christopher C. Stacy) writes:

> >>>>> On Wed, 08 Oct 2003 16:51:44 -0400, Joe Marshall ("Joe") writes:
>  Joe> "Carlo v. Dango" <····@soetu.eu> writes:
> 
>  >> method overloading,
> 
>  Joe> Now I'm *really* confused.  I thought method overloading involved
>  Joe> having a method do something different depending on the type of
>  Joe> arguments presented to it.  CLOS certainly does that.
> 
> He probably means "operator overloading" -- in languages where
> there is a difference between built-in operators and functions,
> their OOP features let them put methods on things like "+".
> 
> Lisp doesn't let you do that, because it turns out to be a bad idea.
> When you go reading someone's program, what you really want is for
> the standard operators to be doing the standard and completely 
> understood thing.

Though if one *really* wants to have +, -, * and / as generic
functions, I imagine one can use something along the lines of:

(defpackage "GENERIC-ARITHMETIC"
  (:shadow "+" "-" "/" "*")
  (:use "COMMON-LISP"))

(in-package "GENERIC-ARITHMETIC")
(defgeneric arithmetic-identity (op arg))

(defmacro defarithmetic (op)
  (let ((two-arg
           (intern (concatenate 'string "TWO-ARG-" (symbol-name op))
                   "GENERIC-ARITHMETIC"))
        (cl-op (find-symbol (symbol-name op) "COMMON-LISP")))
    `(progn
      (defun ,op (&rest args)
         (cond ((null args) (arithmetic-identity ,op nil))
               ((null (cdr args))
                (,two-arg (arithmetic-identity ,op (car args))
                          (car args)))
               (t (reduce (function ,two-arg)
                          (cdr args)
                          :initial-value (car args)))))
      (defgeneric ,two-arg (arg1 arg2))
      (defmethod ,two-arg ((arg1 number) (arg2 (number)))
        (,cl-op arg1 arg2)))))

Now, I have (because I am lazy) left out definitions of the generic
function ARITHMETIC-IDENTITY (general idea, when fed an operator and
NIL, it returns the most generic identity, when fed an operator and an
argument, it can return a value that is more suitable) and there's
probably errors in the code, too.

But, in principle, that should be enough of a framework to build from,
I think.

//Ingvar
-- 
My posts are fair game for anybody who wants to distribute the countless
pearls of wisdom sprinkled in them, as long as I'm attributed.
	-- Martin Wisse, in a.f.p
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm293u$kn3$1@news-int.gatech.edu>
> Lisp doesn't let you do that, because it turns out to be a bad idea.
Only if you subscribe to the Java-mentality that power is bad. Operator
overloading is a must in languages that strive to make user-defined types
fully equal to built-in types (like Dylan, and Goo, maybe CLOS). Besides,
prohibiting operator-overloading is not orthogonal in languages with
generic dispatch, because it creates a pointless schism between built-in
operators and user-defined types. 

> When you go reading someone's program, what you really want is for
> the standard operators to be doing the standard and completely
> understood thing.  
Why? Usually, you cannot overload operators on built-in types. So an integer
plus an integer will always have a specific meaning. However a matrix plus
a matrix can have a user-defined meaning, assuming matricies are
user-defined types. Now, a programmer could go ahead and make an overload
of operator+ that actually subtracted matricies, but he could just as well
write a function "add-matrix" that actually subtracted matricies. And
assuming that the programmer isn't trying to lie to you, its much easier to
understand

(+ m1 m2 m3)

than

(add-matrix m1 m2 m3)

because '+' carries with it an expected set of semantics, while the reader
has to go to the definiton of add-matrix to fully understand its semantics.

> Lisp has carefully defined those operations to do all the things
> that are both well-understood (like complex numbers) and missing
> from languages like C++.  
Actually, C++ has a complex number class in its standard library. Why not in
the language proper? There is no need for it to be in the language, because
it can be implemented in the library just as easily. Its the same reason
'loop' is a macro and not built into the language. Besides, what do you do
when you need quaternions? Wait for the next version of the standard?
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87ekxn2ps4.fsf@thalassa.informatimago.com>
Rayiner Hashem <·······@mail.gatech.edu> writes:
> (+ m1 m2 m3)
> 
> than
> 
> (add-matrix m1 m2 m3)
> 
> because '+' carries with it an expected set of semantics, while the reader
> has to go to the definiton of add-matrix to fully understand its semantics.

You've choosen a bad example. Try: (* m1 m2 m3) vs. (mul-matrix m1 m2 m3)

The problem with (* m1 m2 m3), is that for normal numbers, 

    (=  (* m1 m2 m3) (* m2 m1 m3))

but in general for matrices:

    (/= (* m1 m2 m3) (* m2 m1 m3))


This shows you that * and mul-matrix ARE different classes of operators.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsy8vud4ln.fsf@black132.ex.ac.uk>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> This shows you that * and mul-matrix ARE different classes of operators.

Which is why * should perform element-wise multiplication (as in APL/J and
python's Numeric/numarray packages).

'as
From: Pascal Bourguignon
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87y8vu1gyj.fsf@thalassa.informatimago.com>
Alexander Schmolck <··········@gmx.net> writes:
> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
> > This shows you that * and mul-matrix ARE different classes of operators.
> 
> Which is why * should perform element-wise multiplication (as in APL/J and
> python's Numeric/numarray packages).
> 
> 'as

Right.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <a3995c0d.0310130016.1c9070da@posting.google.com>
> > Which is why * should perform element-wise multiplication (as in APL/J and
> > python's Numeric/numarray packages).
Well, that depends entirely on what the container type is. APL is a
vector-oriented language, and (in computers, anyway) vector operations
are defined element-wise. However, I see little utility in defining *
being element-wise for matricies, because that's simply mathematically
incorrect. It would be better to not provide a * operator at all than
trap the poor programmer with such an unusual definition of it.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfsn0c56vx8.fsf@black132.ex.ac.uk>
·······@mindspring.com (Rayiner Hashem) writes:

> > > Which is why * should perform element-wise multiplication (as in APL/J and
> > > python's Numeric/numarray packages).
> Well, that depends entirely on what the container type is. APL is a
> vector-oriented language, and (in computers, anyway) vector operations
> are defined element-wise.  However, I see little utility in defining *
> being element-wise for matricies, because that's simply mathematically
> incorrect. 

Uhm, are you *sure* you're no talking complete nonsense?

'as
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <a3995c0d.0310131146.1c265597@posting.google.com>
> Uhm, are you *sure* you're no talking complete nonsense?

Pretty sure. Exactly what are you taking exception to? That APL is a
vector (well, array) oriented language, or that defining
matrix-multiplication to be element-wise is mathematically wrong?
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfswub868ka.fsf@black132.ex.ac.uk>
·······@mindspring.com (Rayiner Hashem) writes:

> > Uhm, are you *sure* you're no talking complete nonsense?
> 
> Pretty sure. 

OK, so I'll go into detail then (requoting the post in question below)

> Exactly what are you taking exception to? 

Pretty much everything you wrote, hence my question.

[your last post follows]
> Well, that depends entirely on what the container type is. APL is a
> vector-oriented language, 

Make that array (as you seem to do above).

> and (in computers, anyway) vector operations are defined element-wise.

Is that so? And given that a vector in this context clearly is a (special case
of a) matrix (which in turn is a special case of an array), how would this be
any more "mathematically" correct? How do you propose to achieve
self-consistency?

> However, I see little utility > in defining * being element-wise 
> for matricies,  because that's simply mathematically incorrect.

May I quote, e.g. http://www.bath.ac.uk/~ma1flfs/cm20168/?

  In the 60's Kenneth Iverson devised a new notation with the aim of
  clarifying the teaching of applied mathematics. The new notation proved to
  be quite powerful so in 1962 Iverson transferred his ideas into a
  programming language, which he originally entitled "A Programming Language".

Had you told Ken that "defining * [as] element-wise for matrices [...] [is]
simply mathematically incorrect", he sure could have saved himself a lot of
trouble (the poor guy's still at it, 40 years later -- sort of one makes one
wonder what they teach their math phds at Harvard -- coming up with a notation
for teaching math that's mathematically incorrect).

Apart from your strange statement about "mathematical incorrectness" of a
notational definition, I think there actually is plenty of utility (and
sense). Both simply computationally (e.g. matrix multiplication with diagonal
matrices is really not the most time and space efficient way to scale matrix
elements -- not necessarily the most perspicuous either) and conceptually (I'm
too tired now, so I suggest you just have a look at J).

'as
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmfgvk$dis$1@news-int2.gatech.edu>
>> and (in computers, anyway) vector operations are defined element-wise.
> 
> Is that so? 
There are two definitions of the word vector here. In computers (as in
vector processors or SIMD/MIMD architecture) vector multiplication is
defined element-wise. Its not the mathematically correct definition of
vector multiplication (in common, not specialized mathematics!), but it
serves well in the problem domain. Note that APL is an array language, and
is built on these semantics, and is common on vector processors. For APL,
element-wise multiplication makes perfect sense.

> How do you propose to achieve
> self-consistency?
Because CL is not a specialized array language. We were talking about
generic matrix objects and you suggested that * should be defined
element-wise. In the general case, that definition is not correct for
matricies. 

<pointless sarcasm deleted>
It really makes no sense to argue about a general case like this in terms of
a specialized theory. I'm not a mathematician. When I look up "matrix
multiplication" in MathWorld, I get a specific definition of the operation.
I expect the generic matrix objects I use in a general purpose language to
perform matrix multiplication in the same way. If I wanted a specialized
form of the operation, I'd go use a specialized library designed for it.
From: Gareth McCaughan
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <87y8vo9n5k.fsf@g.mccaughan.ntlworld.com>
Rayiner Hashem wrote:

> There are two definitions of the word vector here. In computers (as in
> vector processors or SIMD/MIMD architecture) vector multiplication is
> defined element-wise. Its not the mathematically correct definition of
> vector multiplication (in common, not specialized mathematics!), but it
> serves well in the problem domain. Note that APL is an array language, and
> is built on these semantics, and is common on vector processors. For APL,
> element-wise multiplication makes perfect sense.
...
> Because CL is not a specialized array language. We were talking about
> generic matrix objects and you suggested that * should be defined
> element-wise. In the general case, that definition is not correct for
> matricies. 
...
> It really makes no sense to argue about a general case like this in terms of
> a specialized theory. I'm not a mathematician. When I look up "matrix
> multiplication" in MathWorld, I get a specific definition of the operation.
> I expect the generic matrix objects I use in a general purpose language to
> perform matrix multiplication in the same way. If I wanted a specialized
> form of the operation, I'd go use a specialized library designed for it.

Well, I *am* a mathematician, and I see no reason why *
shouldn't operate elementwise on arrays. An array is not
the same as a matrix. A matrix is an array *used in a
particular way*, and there are other ways of using arrays
too.

I also don't see any very compelling reason why it
*shouldn't* do matrix multiplication, for what it's
worth.

-- 
Gareth McCaughan
.sig under construc
From: Hartmann Schaffer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <3f8c2e4d@news.sentex.net>
In article <··············@g.mccaughan.ntlworld.com>,
	Gareth McCaughan <················@pobox.com> writes:
> ...
>> It really makes no sense to argue about a general case like this in terms of
>> a specialized theory. I'm not a mathematician. When I look up "matrix
>> multiplication" in MathWorld, I get a specific definition of the operation.
>> I expect the generic matrix objects I use in a general purpose language to
>> perform matrix multiplication in the same way. If I wanted a specialized
>> form of the operation, I'd go use a specialized library designed for it.
> 
> Well, I *am* a mathematician, and I see no reason why *
> shouldn't operate elementwise on arrays. An array is not
> the same as a matrix. A matrix is an array *used in a
> particular way*, and there are other ways of using arrays
> too.
> 
> I also don't see any very compelling reason why it
> *shouldn't* do matrix multiplication, for what it's
> worth.

it seems we are getting here a little bit off topic here (python vs
lisp syntax).  the problem you are discussing here is how to deal with
two data types that happen to have the same representation.  i think
both languages offer ways of dealing with this, but this goes a little
bit beyond the thread subject

hs

-- 

ceterum censeo SCO esse delendam
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmhecj$482$1@news-int2.gatech.edu>
> Well, I *am* a mathematician, and I see no reason why *
> shouldn't operate elementwise on arrays. An array is not
> the same as a matrix. A matrix is an array *used in a
> particular way*, and there are other ways of using arrays
> too.
Um, neither do I. I'm saying that * should do matrix multiplication for
matricies. What is termed a vector in computer languages is almost always
actually used as an array, so giving it vector semantics would be
confusing. Defining * element-wise for arrays might be nice, but I think
that's specialized enough of a use that we might be getting into "operator
overloading abuse" territory.
From: Alexander Schmolck
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <yfs8ynm64om.fsf@black132.ex.ac.uk>
Rayiner Hashem <·······@mail.gatech.edu> writes:

> >> and (in computers, anyway) vector operations are defined element-wise.
> > 
> > Is that so? 
> There are two definitions of the word vector here. In computers (as in
> vector processors or SIMD/MIMD architecture) vector multiplication is
> defined element-wise. 

But how is this *hardware* issue in any way relevant to the meaning of '*' in
programming languages? It's not that you'd forgo the hardware support for
elementwise multiplication if you assigned '*' to do inner products (in fact
that very operation would most likely utilize it).

> Its not the mathematically correct definition of vector multiplication (in
> common, not specialized mathematics!), but it serves well in the problem
> domain.

I'd rather do my matrix algebra having elementwise multiplication as '*'. In
fact I do.

> Note that APL is an array language, and is built on these semantics, and is
> common on vector processors. For APL, element-wise multiplication makes
> perfect sense.

I'd like to point out that one of the significant uses of APL/J to me would
seem to be to do linear algebra, viz. manipulate matrices and that APL/J was
not constrained by some preexisting hardware choices (in fact APL *predates*
vector computers).

 
> > How do you propose to achieve
> > self-consistency?
> Because CL is not a specialized array language. We were talking about
> generic matrix objects and you suggested that * should be defined
> element-wise. 
> In the general case, that definition is not correct for
> matricies. 
> 
> <pointless sarcasm deleted>

OK, no sarcasm this time. But I think you should word what you write a bit
more carefully. I don't think calling a *denotational choice* "simply
mathematically incorrect" makes much sense if all you mean is that it deviates
from common mathematical notation (as does lisp's prefix notation, BTW).

Mathematical notation is neither stable nor sacrosant and often unduly
influenced by historical accidents.

> It really makes no sense to argue about a general case like this in terms of
> a specialized theory. 

But there is no "specialized theory" involved here.

> I'm not a mathematician. 

My mathematical credentials are pretty pathetic, if that's any consolation -
but I do write my fair share of matrix related code.

> When I look up "matrix multiplication" in MathWorld, I get a specific
> definition of the operation. I expect the generic matrix objects I use in a
> general purpose language to perform matrix multiplication in the same way.

Well, you looked up matrix-multiplication and not '*', right?

> If I wanted a specialized form of the operation, I'd go use a specialized
> library designed for it.

But elementwise multiplication of matrix elements is not a specialized version
of matrix-multiplication! If anything the opposite is the case!

There are IMO several reasons why using * for scalar- and
elementwise-multiplication (rather than matrix-multiplication) is a better
choice:

1. A function written with matrices in mind will still work on scalars when
   using matrix-multiplication, but not the other way around. It will work
   both ways if the operations are defined elementwise. Having a separate
   matrix-multiplication symbol also makes it easier to figure out what a
   function does if you don't know the type of all its arguments.

2. Matrix multiplication is just one of many useful inner operations on
   matrices. E.g. you can define it in J as

     x =. +/ . *    .NB read: the sum ('+/' i.e. '+' reduced '/') of inner
                    .NB ('.') multiplication ('*')

   But you also might want to computer inner powers (^/ . *) etc, so this
   composition is both illustrative and powerful.

3. You'll need elementwise operations, including multiplication even if you
   work only on matrices (Note the ugly dummy var constructs mathematicians
   often have to use). Given the above it seems far more sensible to use '*'
   to mean elementwise multiplication rand introduce a different symbol for
   matrix-multiplicaton rather than doing it the matlab way and using a new
   symbol for the elementwise operation.
 
4. This scheme also seems to generalize well to ranks > 2.

I now hand over to the mathematically clued.

'as
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmk7d9$kcd$1@news-int.gatech.edu>
> But how is this *hardware* issue in any way relevant to the meaning of '*'
> in programming languages? 
Programming language designers are a part of the computer world and affected
by its jargon. If you ask a physicist about the correct semantics of vector
multiplication, there would be no ambiguity. If you ask a programmer, he
will have to consider what definition of "vector" you are using. When the
designers of "VectorC" named their language, the certainly weren't thinking
of the mathematical definition of vector.

> APL/J was not constrained by some preexisting hardware choices (in fact
> APL *predates* vector computers).
Right, which is why I said that it was common on vector processors (because
its semantics prove useful) not that it was inspired by vector processors.


> OK, no sarcasm this time. But I think you should word what you write a bit
> more carefully. I don't think calling a *denotational choice* "simply
> mathematically incorrect" makes much sense if all you mean is that it
> deviates from common mathematical notation (as does lisp's prefix
> notation, BTW).
You're right that I shouldn't have used the term "mathematically incorrect"
but its a bit of a strech to take that statement and assume that I was
somehow disparaging 40-years of the guy's work...

> But there is no "specialized theory" involved here.
Its specialized in the sense that it is not the common definition of matrix
multiplication.

I think I see your point advantages of defining * element-wise, but I simply
thing that it would be one of those abuses of operator overloading. * is
the multiplication operator. If the parameters are of type 'matrix', then
it should do matrix multiplication. If you look up matrix multiplication in
a math textbook, you get a specific definition. It really is as simple as
that. Also, I think your advantages don't apply to everybody. Most of my
matrix-related code involves geometric transformations (either for OpenGL
or physical simulation), and for that purpose, you want the inner-product
version. Given that the advantages of element-wise multiplication don't
generalize to all cases, I'd argue that its best to stick to the commonly
understood definition of the operation.
From: Gareth McCaughan
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <8765inuiy8.fsf@g.mccaughan.ntlworld.com>
Rayiner Hashem wrote:

> I think I see your point advantages of defining * element-wise, but I simply
> thing that it would be one of those abuses of operator overloading. * is
> the multiplication operator. If the parameters are of type 'matrix', then
> it should do matrix multiplication. If you look up matrix multiplication in
> a math textbook, you get a specific definition. It really is as simple as
> that.

What if they are of type 'array', which is what most
languages actually provide?

If you have a specific *matrix* type or class, then
indeed * should act on those by matrix multiplication.
I didn't think that was what the discussion was about;
maybe I missed a crucial point somewhere.

-- 
Gareth McCaughan
.sig under construc
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bmqqa7$o7p$1@news-int.gatech.edu>
> If you have a specific *matrix* type or class, then
> indeed * should act on those by matrix multiplication.
> I didn't think that was what the discussion was about;
> maybe I missed a crucial point somewhere.
> 
We were talking about specific matrix classes. The discussion started with
talking about the merits of operator overloading, which kind of implies
classes. At least, its highly unusual to override the operators of a
built-in type.
From: rif
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <wj0ad7yobh5.fsf@five-percent-nation.mit.edu>
I don't have any beef in this argument either way, but as another
point of reference, in the language R, which is widely used for
statistical computing, * will multiply matrices element-wise, and %*%
will do "matrix multiplication".

I'm sure most people are aware that in Matlab (and octave) * will do
"matrix multiplication" and .* will multiply matrices element-wise.
So it seems that even within the domain of small languages designed
for mathematical manipulation, different design choices for matrix
multiplication are possible.

Cheers,

rif
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm3rkq$al7$1@news-int2.gatech.edu>
> 
> This shows you that * and mul-matrix ARE different classes of operators.
> 
But they're not. Its immediately obvious to someone familiar with
mathematics that * when applied to matricies carries a certain set of
constraints, a different set than * applied to integers. You have to assume
that the programmer is well-versed in his problem domain. The key thing is
that by using "*" you immediately convey exactly what those contraints are,
while by using mul-matrix, there is an element of uncertainty until you
check out the definiton of the function. 
From: Jon S. Anthony
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <m34qyi77bg.fsf@rigel.goldenthreadtech.com>
"Carlo v. Dango" <····@soetu.eu> writes:

> yes this mail is provocative.. please count slowly to 10 before

Nah, it's not provocative - it's simply stupid.

/Jon
From: Rayiner Hashem
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm2b8v$lj4$1@news-int.gatech.edu>
> sure, but it seems like noone was able to let Cconceivable(virtual) inner
classes,
That's because Lisp has closures, and because CL doesn't mandate access
protections for classes. 

> methods inside methods,
You can use a lambda to accomplish the same thing.

> virtual methods (yeah I know about those stupid generic functions :),
Generic functions are just virtual methods generalized to multiple dispatch.

> method overloading
Method overloading is just a special case of generic dispatch in situations
where the types of the dispatch arguments are known at compile-time. In
situations where method overloading could be applicable, GF dispatch
doesn't even have a performance hit over static method overloading because
the compiler can optimize-out the generic dispatch.

> A decent API (I tried playing with it.. it doesn't even have a freaking
> date library as standard ;-p
Google for one! What's the point of having every conceivable library in the
language?

> 
> Yes I agree with the compile time macro expansion is a nice thing.
> However, if I want to do some serious changes to the structure of objects
> and classes (i.e. create a new kind of objects) then I have to spend a
> long time finding out how the CLOS people hacked together their
> representation of classes, methods, method call etc...
There is a MOP provided expressly for this purpose.
From: David Rush
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <oprwpu150f3seq94@news.nscp.aoltw.net>
On Tue, 07 Oct 2003, Peter Seibel <·····@javamonkey.com> wrote:
> But Lisp's syntax is not the way it is to make the compiler writer's
> job easier. <macros> *That's* why we don't mind, and, in
> fact, actively like, Lisp's syntax.

In fact, I have also noticed that programming in nearly all other languages
(Smalltalk, APL, and FORTH are the exceptions) tends to degenerate towards 
a fully-parenthesized prefix notation in direct proportion to the size of
the code. This fully-parenthesized prefix notation is just everyday
function calls, BTW. Method invocations aren't really any different.

So if you're going to write in parenthesized prefix notation *anyway*, you
might as well get some benefit out of it -> s-expressions and macros

david rush
-- 
(\x.(x x) \x.(x x)) -> (s i i (s i i))
        -- aki helin (on comp.lang.scheme)
From: Mario S. Mommer
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <fzk77g3ygs.fsf@cupid.igpm.rwth-aachen.de>
Peter Seibel <·····@javamonkey.com> writes:
> ··············@attbi.com (Corey Coughlin) writes:
> 
> > Using parentheses and rpn everywhere makes lisp very easy to parse,
> > but I'd rather have something easy for me to understand and hard for
> > the computer to parse.

Intrestingly enough, I think this is a question of getting used to
it. The notation is so relentlessly regular that once you got it,
there are no more syntactical ambiguities. None. Ever.

It is the difference (for me) between reading roman numerals (that
would be the baroque-ish syntax of other languages, full of
irregularities, special cases, and interference patterns), and arabic
numerals (that would be lisp). I never have a doubt about what the
S-expr. representation encodes.
From: Pascal Costanza
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <blvgg6$6ft$1@newsreader2.netcologne.de>
Corey Coughlin wrote:
> I was never very fond of lisp.  I guess I mean scheme technically, I
> took the Ableson and Sussman course back in college, so that's what I
> learned of scheme, lisp in general I've mostly used embedded in other
> things.  In general, it always seemed to me that a lot of the design
> choices in lisp are driven more by elegance and simplicity than
> usability.

You should give Common Lisp a try. Many Lispers think that that's 
exactly one of the advantages of Common Lisp over Scheme: it focuses 
more on usability than on elegance.

Of course, mileages vary, but you shouldn't draw conclusions about 
Common Lisp from your experience with Scheme, and vice versa. Common 
Lisp and Scheme are as similar as, say, C++ and Pascal.


Pascal
From: ·············@comcast.net
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <isn062a3.fsf@comcast.net>
Pascal Costanza <········@web.de> writes:

> Corey Coughlin wrote:
>> I was never very fond of lisp.  I guess I mean scheme technically, I
>> took the Ableson and Sussman course back in college, so that's what I
>> learned of scheme, lisp in general I've mostly used embedded in other
>> things.  In general, it always seemed to me that a lot of the design
>> choices in lisp are driven more by elegance and simplicity than
>> usability.
>
> You should give Common Lisp a try. Many Lispers think that that's
> exactly one of the advantages of Common Lisp over Scheme: it focuses
> more on usability than on elegance.

S&ICP (Abelson and Sussman) use Scheme to illustrate basic concepts by
stripping away things to get at the core of what's going on.  But I
think too many people assume that the stripped-down version is
supposed to be `better' in some sense.  (Other than the pedagogic
sense, that is.)

It is like learning about internal combustion engines by disassembling
a lawnmower.  It is a very simple illustration of everything important
about 4-stroke engines.  However, no one would suggest you actually
build a car that way!
From: Albert Lai
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <4ullrtrdoq.fsf@vex.net>
··············@attbi.com (Corey Coughlin) writes:

> (Not to mention car, cdr, cadr, and
> so on vs. index notation, sheesh.)

Yes, that is a real regret.  It should have been useful to support
a kind of (nth 10 mylist) straight from the Scheme standard library.

> Using parentheses and rpn everywhere makes lisp very easy
> to parse, but I'd rather have something easy for me to understand and
> That's why I prefer python, you
> get a nice algebraic syntax with infix and equal signs, and it's easy
> understand.
> Python is
> intuitive to me out of the box, and it just keeps getting better, so I
> think I'll stick with it.

First, a minor correction: Lisp/Scheme is like (* 1 2) and that is
Polish Notation or prefix; Reverse Polish Notation or postfix would be
like (1 2 *).

From what I heard about the Japanese language I have formed the
possibly oversimplified impression that it is largely postfix.
Whereas in English we say "I beat you", they may say something like "I
you beat".  So I suppose all of the existing programming notations -
Lisp's and Cobol's (* 1 2) and MULTIPLY 1 BY 2, Fortran's "intuitive"
1+2, and OO's one.add(two) - are very counterintuitive to them, and
they would really like the way of HP calculators, no?

And I suppose the ancient Romans (and even the modern Vaticans) would
laugh at this entire dilemma (or trilemma?) between ___fixes.

Intuition is acquired.  It is purely a product of education or
brainwashing.  There is nothing natural about it.  And since it is
acquired, you may as well keep acquiring new intuitions and see more
horizons, rather than keep reinforcing old intuitions and stagnate.
Appreciating a foreign language such as Japanese some day is not a bad
idea.
From: Bill Birch
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <6f7fa60c.0310071958.7c60a45@posting.google.com>
·······@ziplip.com wrote in message news:<········································@ziplip.com>...
> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while 
> keeping its amazing syntax, and if it could be possible to
> add Pythonistic syntax to Lisp or Scheme, while keeping all
> of the functionality and convenience. If the answer is yes,
> would many Python programmers switch to Lisp or Scheme if
> they were offered identation-based syntax?

I don't know if many programmers would switch. But I put a
pre-processor in my Lisp implementation which gives indentation-based
syntax. e.g.:

defun csv.read (filename &optional retval)
     setq fdx (open filename :direction :input)
     cond
        (not  fdx)
             error "could not open file"  filename
     do-while  (not (equal  *eof* (setq  line (parse-csv fdx "|"  
"\n" ))))
         setq retval (cons  line retval)
    close fdx
    reverse retval

I use it almost every day. 

There are some lessons:
* Cond looks better!
* Most text editors I use have auto-indent, and indent functions which
makes code changes easy (no more chasing parens)
* Because by default every line is a list you have to do something
special for atoms:

     progn
         (* 2 3)
         99         ; fails because (99) is not a valid function call

So you need to do:
     progn
         (* 2 3)
         ^ 99       ; where (defun ^ (x) x) ; the identity function

* Sometimes you just have to line-wrap long expressions. I have added
a line continuation character \ (like make) and recently added a rule
which says if an expression is unmatched switch off indentation. Not
sure which is the best yet.

* If you get the indentation wrong, your program behaves weirdly, just
like when you mess up a Lisp paren.


TTFN
From: Marco Antoniotti
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <c4Wgb.11$KR3.104@typhoon.nyu.edu>
Bill Birch wrote:

> ·······@ziplip.com wrote in message news:<········································@ziplip.com>...
> 
>>I think everyone who used Python will agree that its syntax is
>>the best thing going for it. It is very readable and easy
>>for everyone to learn. But, Python does not a have very good
>>macro capabilities, unfortunately. I'd like to know if it may
>>be possible to add a powerful macro system to Python, while 
>>keeping its amazing syntax, and if it could be possible to
>>add Pythonistic syntax to Lisp or Scheme, while keeping all
>>of the functionality and convenience. If the answer is yes,
>>would many Python programmers switch to Lisp or Scheme if
>>they were offered identation-based syntax?
> 
> 
> I don't know if many programmers would switch. But I put a
> pre-processor in my Lisp implementation which gives indentation-based
> syntax. e.g.:
> 
> defun csv.read (filename &optional retval)
>      setq fdx (open filename :direction :input)
>      cond
>         (not  fdx)
>              error "could not open file"  filename
>      do-while  (not (equal  *eof* (setq  line (parse-csv fdx "|"  
> "\n" ))))
>          setq retval (cons  line retval)
>     close fdx
>     reverse retval
> 
> I use it almost every day. 
> 
> There are some lessons:
> * Cond looks better!
> * Most text editors I use have auto-indent, and indent functions which
> makes code changes easy (no more chasing parens)
> * Because by default every line is a list you have to do something
> special for atoms:
> 
>      progn
>          (* 2 3)
>          99         ; fails because (99) is not a valid function call
> 
> So you need to do:
>      progn
>          (* 2 3)
>          ^ 99       ; where (defun ^ (x) x) ; the identity function


Why not

	progn
		(* 2 3)
		identity 99


--
Marco
From: Vis Mike
Subject: Re: Python syntax in Lisp and Scheme
Date: 
Message-ID: <bm70uu$3l3$1@bob.news.rcn.net>
<·······@ziplip.com> wrote in message
·············································@ziplip.com...
> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while
> keeping its amazing syntax, and if it could be possible to
> add Pythonistic syntax to Lisp or Scheme, while keeping all
> of the functionality and convenience. If the answer is yes,
> would many Python programmers switch to Lisp or Scheme if
> they were offered identation-based syntax?

What about an editor that simply hides outer parenthesis and displays them
as
tabs, for Scheme for example.  Then you could edit in any program, or use an
editor designed for it.  Kind of like editing raw HTML or using an HTML
editor.

I might just adapt this idea for my pet language which uses indentation for
blocks.  I like code to flow like an outline, with as few extraneous symbols
and junk as possible.

Mike