(and scheme lisp) x Python and modern langs [was Re: gossip, Guy Steel, Lojban, Racket]

Xah Lee xahlee at gmail.com
Mon Sep 27 15:06:50 EDT 2010


2010-09-27

> For instance, this is far more convenient:

> [x+1 for x in [1,2,3,4,5] if x%2==0]

> than this:

> map(lambda x:x+1,filter(lambda x:x%2==0,[1,2,3,4,5]))

How about this:

 LC(func, inputList, P)

compared to

 [func for myVar in inputList if P]

the functional form is:

• shorter
• not another idiysyncratic new syntax

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

now, a separate issue. Suppose we want some “list comprehension”
feature in a functional lang.
Normally, by default this can be done by

 filter( map(func, inputList), Predicate)

but perhaps this usage is so frequent that we want to create a new
fuction for it, to make it more convenient, and perhaps easier to make
the compiler to optimize more. e.g.

 LC(func, inputList, Predicate)

this is about whether a lang should create a new convenient function
that otherwise require 2 function combinations. Common Lisp vs Scheme
Lisp are the typical example of extreme opposites.

note, there's no new syntax involved.

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

Now, let's consider another separated issue related to so-called “list
comprehension”.
Suppose we decided that generating list by a filter is so frequently
used that it worth it to create a new func for it.

 LC(func, inputList, Predicate)

Now, in functional langs, in general a design principle is that you
want to reduce the number of function unless you really need. Because,
any combination of list related functions could potentionally be a new
function in your lang. So, if we really think LC is useful, we might
want to generalize it. e.g. in

 LC(func, inputList, Predicate)

is it worthwhile say to add a 4th param, that says return just the
first n? (here we presume the lang doesn't support list of infinite
elements) e.g.

 LC(func, inputList, Predicate, n)

what about partition the list to m sublists?

 LC(func, inputList, Predicate, n, m)

what about actualy more generalized partition, by m sublist then by m1
sublist then by m2 sublist?

 LC(func, inputList, Predicate, n, list(m,m1,m2,...))

what about sorting? maybe that's always used together when you need a
list?

 LC(func, inputList, Predicate, n, list(m,m1,m2,...), sortPredcate)

what if actually frequently we want LC to map parallel to branches?
e.g.

 LC(func, inputList, Predicate, n, list(m,m1,m2,...), sortPredcate,
mapBranch:True)

what if ...

you see, each of these or combination of these can be done by default
in the lang by sequenceing one or more functions (i.e. composition).
But when we create a new function, we really should think a lot about
its justification, because otherwise the lang becomes a bag of
functions that are non-essential, confusing.

In summary:

• “list comprehension” is a bad jargon.

• The concept of “list comprehension” is redundant. There's no
justification for the concept to exist except historical.

• The syntax of “list comprehension” in most lang is ad hoc syntax.

for those who find imperative lang good, then perhaps “list
comprehension” is good, because it adds another idiosyncratic syntax
to the lang, but such is with the tradition of imperative langs. The
ad hoc syntax aids in reading code by various syntactical forms and
hint words such as “[... for ... in ...]”.

 Xah ∑ xahlee.org ☄



More information about the Python-list mailing list