Python syntax in Lisp and Scheme

H

Hartmann Schaffer

...
[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
 
B

Bengt Richter

|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 foo(x): return x+1
... bar = lambda x: x+1
... return foo,bar
... 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 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 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:
... 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
 
P

Pascal Bourguignon

Jacek Generowicz said:
HOFs are not a special Lisp thing. Haskell does them much better,
for example... and so does Python.

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...
 
H

Hartmann Schaffer

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
 
P

Pascal Bourguignon

Alexander Schmolck said:
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...
 
H

Hartmann Schaffer

...
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
 
D

David Mertz

the alpha and omega of HOFs is that functions are first class
objects that can be passed and returned.

|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:
... x += 3
... x *= 2
... return x
... ... y -= 4
... return y
... <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...
 
P

Pascal Bourguignon

|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?
 
D

David Mertz

|> 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.

|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...
 
J

Jacek Generowicz

Tim Hochberg said:
Nope, with python in 2010 -- at that point, Python will be about as
old as Lisp was in '81.

Excellent analogy ... if I want to write programs to solve difficult
problems, I can either use Common Lisp today ... or I can wait until
2032 at which point Python should have caught up.

:)
 
J

Jacek Generowicz

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
 
D

David Mertz

|> 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.

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...

--
mertz@ | 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!
-------------------------------------------------------------------------
 
P

Pascal Costanza

Jacek said:
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
 
K

ketil+news

Raffael Cavallaro said:
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?

Obviously true, no?

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.

Surely this is true? Has anybody seen code where all names were
descriptive and unabmigous, yet short and concise?
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
 
L

Luke Gorrie

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
 
A

Alexander Schmolck

Pascal Costanza said:

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.

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).

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.
 
P

Pascal Bourguignon

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.[/QUOTE]

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...
 
T

Terry Reedy

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
 
P

Pascal Costanza

Alexander said:
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.
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".
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.
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.
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
 
K

Kenny Tilton

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).

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top