[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Accumulator

Paul Prescod <paul@prescod.net> writes:

> "A.Schmolck" wrote:
> At the very least, the name of the operator is brain-dead. We might as
> well add give functions meaningless names like "cdr" and "creat". ;)

You know, I actually think "lambda", "cons" and maybe even "car" and "cdr" are
pretty good names (better than Paul Grahams "fn", for example -- I'd rather
use a greek letter if shortness is that important). They are short,
unambigious (and with the exception of cdr -- for the unitiated :)
pronounceable. I have the feeling that programming languages need two
fundamentally different sorts of names -- names for "primitives" (cons) and
names for "composites" ("makeImageButton"), but that most end up
inappropriately using mainly either one for both. By "primitive" I mean part
of the conceptual machinery of a language -- essentially something new, that
you have to learn from scratch in order to understand the language. Lisp's
"cons" is a prime example. Sticking a name you can find in a dictionary on it
(or a "phrase") doesn't help this learning process in the least, it might even
be unhelpful, because new basic concepts need names and these names should
either novel or *remote* enough metaphors to be unambiguous and clear.

Lispers can for example say that this implementation avoids uncessary cons'ing
(cf. "pairing") and I doubt whether people on a future ll22 mailing list will
ever talk of "fn"s rather than lambdas, even if Paul Grahams arc rules the
programming world in a couple of years :)

On the other hand, I firmly belief that names for things that are not
conceptually primitive should have good descriptive names (which may well be
long, especially if they are not often used) because here it not only helps
guessing what they do but also memorizing and looking them up (emacs,
e.g. would be pretty much unusable without such naming conventions and I rely
deplore tempnam and similar C gruft in many python modules).

> > Yes, I agree that for many cases comprehensions can be clearer, but I also
> > think for many they aren't, notably when you've got more than one sequence:
> > 
> >       map(add, xs, ys)
> > 
> > is, to me, better than:
> > 
> >     [x + y for (x,y) in zip(xs,ys)]
> I think it's just a matter of which you learned first. zip is useful to
> know for other contexts anyhow.

Zip is easily the python function I like best (for one thing, because it
allows elegant uses of infinite sequences), so I would be even willing to
sacrifice map if it would bring more people closer to the wonders of zip :)
I'd suspect that people who like map, reduce and filter will also like zip and
vice versa, though.

> > ...
> > in fact, as long I have a ready-made function, I'd prefer map:
> > 
> >    map(str, args)
> Given that it exists, maybe. If we were creating the language from
> scratch? I don't think so.
> > Also, this style of programming naturally extends to lazy sequences (if you
> > define things like, say xzipWith etc.), dictionaries and other scenarios that
> > you can't accommodate with comprehensions or that are awkward and ugly with
> > loops (e.g. reduce'ing). 
> Python will probably grow dictionary comprehensions and lazy
> comprehensions when there is enough demand.

Well, I hope you don't take it too badly if I tell you that I remember Guido's
latest pronouncement on lazy and dict comprehensions as something along the
lines of: "Not needed -- but maybe I should add _macros_ to the language to
allow people to cook them up themselves" :)

> >...
> > clearer. Of course 'clear' also depends how used one is to a certain style of
> > coding (e.g. do you find ``reduce(operator.getitem, pos, tree)`` clear? I
> > certainly do).
> I never use reduce, so no.
> node = tree
> for curpos in pos:
> 	node = node[pos]
Thanks for demonstrating my point :)
[about loops being more error-prone than functional constructs]

To me, this for loop is in a way a human-compiled version of the above reduce
expression (which maps well at least to my mental conceptualization of the
operation), and humans just aren't very good compilers ;)

> When I write code I always have in the back of my mind whether an
> occasional Python programmer could follow it. I will use an advanced
> feature if it dramatically simplifies the code. Otherwise, I will avoid
> it. Few people would agree with me that that is worth spending effort
> on. I happen to consider both "reduce" and "operator.getitem" advanced
> features.

Depending on the audience of the code this can certainly be a reasonable thing
to do (if you write a symbolic math package, it's presumably not
worthwhile). But I also think there are different kinds of "advanced" features
-- some things are just more or less language specific shortcuts, acronyms if
you want (and Perl is full of them). Other things are powerful *concepts* (and
I personally think reduce qualifies as such) -- they allow you to *see* things
differently, rather than just to write more concise code. Leaving out
shorthands does little harm, apart from a negligible cost in time for you
writing the code and for other expert programmers reading it. But by not using
powerful concepts you are also depriving readers of your code of the chance to
get smarter, so there is at least chance that you unwittingly patronize some
of your readers, rather than doing them a favour (I was really chuffed, for
example when I found out about zip(*foo)).

>  Paul Prescod