COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### What's List Comprehension and Why is it Harmful?

• Email
• Follow

```here's a article about list comprehension.

=E2=80=A2 =E3=80=88What's List Comprehension and Why is it Harmful?=E3=80=
=89
http://xahlee.org/comp/list_comprehension.html

i wrote it from a recent debate.

I hope those of you computer scientists and language designers think

plain text version follows.

--------------------------------------------------
What's List Comprehension and Why is it Harmful?

Xah Lee, 2010-10-14

several languages, with my opinion on why the jargon and concept of
=E2=80=9Clist comprehension=E2=80=9D are unnecessary, redundant, and harmfu=
l to
functional programing.
What is List Comprehension?

Here's a example of LC in python:

S =3D [2*n for n in range(0,9) if ( (n % 2) =3D=3D 0)]
print S
# prints [0, 4, 8, 12, 16]

It generates a list from 0 to 9, then remove the odd numbers by =E3=80=8C( =
(n
% 2) =3D=3D 0), then multiply each element by 2 in =E3=80=8C2*n=E3=80=8D, t=
hen returns a
list.

Python's LC syntax has this form:

[myExpression for myVar in myList if myPredicateExpression]

In summary, it is a special syntax for generating a list, and allows
programers to also filter and apply a function to the list, but all
done using expressions.

In functional notation, list comprehension is doing this:

map( f, filter(list, predicate))

Other languages's LC are similiar. Here are some examples from
Wikipedia. In the following, the filter used is =E3=80=8Cx^2 > 3=E3=80=8D, =
and the
=E3=80=8C2*x=E3=80=8D is applied to the result.
javascript

Number.prototype.__iterator__ =3D function() { for (let i =3D 0; i < this;
i++) yield i}
var s =3D [2*i for (i in 100) if (i*i > 3)]

s =3D [ 2*x | x <- [0..], x^2 > 3 ]

F#

seq { for x in 0..100 do if x*x > 3 then yield 2*x } ;;

OCaml

[? 2 * x | x <- 0 -- max_int ; x * x > 3 ?];;

Clojure

(take 20 (for [x (iterate inc 0) :when (> (* x x) 3)] (* 2 x)))

Common Lisp

(loop for x from 1 to 20 when (> (* x x) 3) collect (* 2 x))

Erlang

S =3D [2*X || X <- lists:seq(0,100), X*X > 3].

Scala

val s =3D for (x <- Stream.from(0); if x*x > 3) yield 2*x

Here's how Wikipedia explains List comprehension. Quote:

A list comprehension is a syntactic construct available in some
programming languages for creating a list based on existing lists.

The following features makes up LC:

* (1) A flat list generator, with the ability to do filtering and
applying a function.
* (2) Usually, a special syntax in the language.
* (3) The syntax uses expressions, as opposed to using functions
as parameters.

Why is List Comprehension Harmful?

=E2=80=A2 List Comprehension is a bad jargon; thus harmful to functional
programing or programing in general. It hampers communication, and
encourage mis-understanding.

=E2=80=A2 List Comprehension is a redundant concept in programing. What Lis=
t
Comprehension does is simply =E3=80=8Cmap(func, filter(list, predicate))=E3=
=80=8D.

=E2=80=A2 The special syntax of List Comprehension as it exists in many lan=
gs,
are not necessary. If a special purpose function for it is preferred,
then it can simply be a plain function, e.g =E3=80=8CLC(function, list,
predicate)=E3=80=8D.
Map + Filter =3D List Comprehension Semantics

The LC's semantics is not necessary. A better way and more in sync
with functional lang spirit, is simply to combine plain functions:

map( f, filter(list, predicate))

Here's the python syntax:

map(lambda x: 2*x , filter( lambda x:x%2=3D=3D0, range(9) ) )
# result is [0, 4, 8, 12, 16]

In Mathematica, this can be written as:

Map[ #*2 &, Select[Range@9, EvenQ]]

In Mathematica, a arithemetic operation can be applied to list
directely without using Map explicitly, so the above can be written
as:

Select[Range@9, EvenQ] * 2

in my coding style, i usually write it in the following syntactically
equivalent forms:

(#*2 &) @ (Select[#, EvenQ]&) @ Range @ 9

or

9 // Range  // (Select[#, EvenQ]&)  // (#*2 &)

In the above, we sequence functions together, as in unix pipe. We
start with 20, then apply =E2=80=9CRange=E2=80=9D to it to get a list from =
1 to 9,
then apply a function that filters out all numbers not greater than 3,
then we apply a function to multiply each number by 2. The =E2=80=9C//=E2=
=80=9D sign
is a postfix notation, analogous to bash's =E2=80=9C|=E2=80=9D, and =E2=80=
=9C@=E2=80=9D is a prefix
notation that's the reverse of =E2=80=9C|=E2=80=9D.

(See: Short Intro of Mathematica For Lisp Programers.)
List Comprehension Function Without Special Syntax

Suppose we want some =E2=80=9Clist comprehension=E2=80=9D feature in a func=
tional
lang. Normally, by default this can be done by

map(func, filter(inputList, Predicate))

but perhaps this usage is so frequent that we want to create a new
function 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 3 function combinations. Common Lisp vs Scheme
Lisp are the typical example of extreme opposites.

Note, there's no new syntax involved.

Suppose, someone argues that

For instance, this is far more convenient:

[x+1 for x in [1,2,3,4,5] if x%2=3D=3D0]

than this:

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

LC(func, inputList, P)

compared to

[func for myVar in inputList if P]

the functional form is:

* Shorter
* Not another idiosyncratic new syntax

Issues and Decisions on Creating a New Function

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 it.
Because, any combination of list related functions could potentially
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 actually 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 sequencing 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.

So the question is, is generating a list really that much needed? And,
if so, why should we create a special syntax such as =E3=80=8C[ expr for va=
r
in list if P]=E3=80=8D than =E3=80=8C LC(func, list, P)=E3=80=8D?

Also note, that LC is not capable of generating arbitrary nested list.
For a example of a much powerful list generator that can generate
arbitrary nested tree, see:

* http://reference.wolfram.com/mathematica/ref/Table.html
* Tree Functions: Table

For those who find imperative lang good, then perhaps =E2=80=9Clist
comprehension=E2=80=9D is good, because it adds another idiosyncratic synta=
x
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 =E2=80=9C[... for ... in ...]=E2=80=9D.
Bad Jargon and How To Judge a Jargon

Someone wrote:

The term =E2=80=9Clist comprehension=E2=80=9D is intuitive, it's based =
on math set
notation.

The jargon =E2=80=9Clist comprehension=E2=80=9D is opaque. It hampers commu=
nication
and increases misunderstanding. A better name is simply =E2=80=9Clist
generator=E2=80=9D.

What's your basis in saying that =E2=80=9CList Comprehension=E2=80=9D is in=
tuitive?
Any statics, survey, research, references?

To put this in context, are you saying that lambda, is also intuitive?
=E2=80=9Clet=E2=80=9D is intuitive? =E2=80=9Cfor=E2=80=9D is intuitive? =E2=
=80=9Cwhen=E2=80=9D is intuitive? I mean,
give your evaluation of some common computer language terminologies,
and tell us which you think are good and which are bad, so we have
some context to judge your claim.

For example, let us know, in your view, how good are terms: currying,
lisp1 lisp2, tail recursion, closure, subroutine, command, object. Or,
perhaps expound on the comparative merits and meaning on the terms
module vs package vs add-on vs library. I would like to see your view
on this with at least few paragraphs of analysis on each. If you, say,
write a essay that's at least 1k words on this topic, then we all can
make some judgment of your familiarity and understanding in this area.

Also, =E2=80=9Cbeing intuitive=E2=80=9D is not the only aspect to consider =
whether a
term is good or bad. For example, emacs's uses the term =E2=80=9Cframe=E2=
=80=9D. It's
quite intuitive, because frame is a common english word, everyone
understands. You know, door frame, window frame, picture frame, are
all analogous to emacs's =E2=80=9Cframe=E2=80=9D on a computer. However, by=
some turn
of history, in computer software we call such as =E2=80=9Cwindow=E2=80=9D n=
ow, and by
happenstance the term =E2=80=9Cwindow=E2=80=9D also has a technical meaning=
in emacs,
what we call =E2=80=9Csplit window=E2=80=9D or =E2=80=9Cframe=E2=80=9D toda=
y. So, in emacs, the term
=E2=80=9Cframe=E2=80=9D and =E2=80=9Cwindow=E2=80=9D is confusing, because =
emacs's =E2=80=9Cframe=E2=80=9D is what we
call =E2=80=9Cwindow=E2=80=9D, while emacs's =E2=80=9Cwindow=E2=80=9D is wh=
at we call a frame. So
here, is a example, that even when a term is intuitive, it can still

As another example, common understanding by the target group the term
is to be used is also a important aspect. For example, the term
=E2=80=9Clambda=E2=80=9D, which is a name of greek char, does not convey we=
ll what we
use it for. The word's meaning by itself has no connection to the
concept of function. The char happens to be used by a logician as a
shorthand notation in his study of what's called =E2=80=9Clambda
calculus=E2=80=9D (the =E2=80=9Ccalculus=E2=80=9D part is basically 1700's =
terminology for a
systematic science, especially related to mechanical reasoning).
However, the term =E2=80=9Clambda=E2=80=9D used in this way in computer sci=
ence and
programing has been long and wide, around 50 years in recent history
(and more back if we trace origins). So, because of established use,
here it may decrease the level of what we might think of it as a bad
jargon, by the fact that it already become a standard usage or
understanding. Even still, note that just because a term has establish
use, if the term itself is very bad in many other aspects, it may
still warrant a need for change. For one example of a reason, the
argon will be a learning curve problem for all new generations.

You see, when you judge a terminology, you have to consider many
aspects. It is quite involved. When judging a jargon, some question

=E2=80=A2 Does the jargon convey its meaning by the word itself? (i.e. whet=
her
the jargon as a word is effective in communication)

=E2=80=A2 How long has been the jargon in use?

=E2=80=A2 Do people in the community understand the jargon? (e.g. more
scientifically: what percentage?)

Each of these sample questions can get quite involved. For example, it
calls for expertise in linguistics (many sub-fields are relevant:
pragmatics, history of language, etymology), practical experience in
the field (programing or computer science), educational expertise
(e.g. educators, professors, programing book authors/teachers),
scientific survey, social science of communication...

Also, you may not know, there are bodies of professional scientists
who work on terminologies for publication. It is not something like =E2=80=
=9CO
think it's good, becus it is intuitive to me.=E2=80=9D.

Xah =E2=88=91 http://xahlee.org/ =E2=98=84
```
 0
Reply xahlee (1035) 10/18/2010 9:11:07 AM

See related articles to this posting

```One question: why contain your pages always this junk? (red marked):
http://img256.imageshack.us/img256/7618/xahleehtmljunk.jpg

regards
Marc

```
 0

```On Oct 18, 2:34=C2=A0am, Marc Mientki <mien...@nonet.com> wrote:
> One question: why contain your pages always this junk? (red marked):
> =C2=A0 =C2=A0http://img256.imageshack.us/img256/7618/xahleehtmljunk.jpg
>
> regards
> Marc

ug. what browser + OS are you using?

those are unicode =E3=80=8C=E3=80=8D
LEFT CORNER BRACKET x300c
RIGHT CORNER BRACKET x300d

you might be missing font

=E2=80=A2 =E3=80=88Best Fonts for Unicode=E3=80=89
http://xahlee.org/emacs/emacs_unicode_fonts.html

or you might need to tweak your browser's encoding/decoding and font.
you can see the same article at these locations,

e736b#
http://xahlee.blogspot.com/2010/10/whats-list-comprehension-and-why-is-it.h=
tml
http://xahlee.org/comp/list_comprehension.html

possibly your browser will display correctly in one but not other...
these days it's complicated to trace the cause.

thanks for your screenshot. That's good to know. Please let me know

Xah =E2=88=91 http://xahlee.org/ =E2=98=84
```
 0
Reply xahlee (1035) 10/18/2010 9:59:42 AM

```Am 18.10.2010 11:59, schrieb Xah Lee:
> On Oct 18, 2:34 am, Marc Mientki<mien...@nonet.com>  wrote:
>> One question: why contain your pages always this junk? (red marked):
>>     http://img256.imageshack.us/img256/7618/xahleehtmljunk.jpg
>>
>> regards
>> Marc
>
> ug. what browser + OS are you using?

Firefox 3.6.10 on windows XP + SP3.

> those are unicode 「」
> LEFT CORNER BRACKET x300c
> RIGHT CORNER BRACKET x300d

Is there need for unicode for such trivial things like {[]}?

regards
Marc

```
 0

```On Oct 18, 3:03=C2=A0am, Marc Mientki <mien...@nonet.com> wrote:
> Am 18.10.2010 11:59, schrieb Xah Lee:
>
> > On Oct 18, 2:34 am, Marc Mientki<mien...@nonet.com> =C2=A0wrote:
> >> One question: why contain your pages always this junk? (red marked):
> >> =C2=A0 =C2=A0http://img256.imageshack.us/img256/7618/xahleehtmljunk.jp=
g
>
> >> regards
> >> Marc
>
> > ug. what browser + OS are you using?
>
> Firefox 3.6.10 on windows XP + SP3.
>
> > those are unicode =E3=80=8C=E3=80=8D
> > LEFT CORNER BRACKET x300c
> > RIGHT CORNER BRACKET x300d
>
> Is there need for unicode for such trivial things like {[]}?

short story is no but am a unicode geek :)

long story is... i need a way to quote code...  the corner bracket was
choosen because it's standard chinese punctuation thus almost all
computer today bought in the past 5 years can display it, and because
it's different than ascii so it avoids ambiguity and complications.
e.g. when the quoted text also contains the char that you use for
quoting....

the other thing is that those markers are very useful when you think
about info processing and automation. e.g. in the future i can
trivially write a script list all inline code i have on my site, or to
htmlize/css all quoted code. e.g.

=E2=80=A2 =E3=80=88Unix Shell Text Processing Tutorial (grep, cat, awk, sor=
t, uniq)=E3=80=89
http://xahlee.org/UnixResource_dir/unix_shell_text_processing.html

in that page, does the char show up correctly? The chars are not in
the html text, but is added by CSS due to markup. And the code are all
colored red.

PS: the most popular example of studious use of quoting in a tech doc
is emacs manual or any manual from FSF. e.g.

=E2=80=A2 =E3=80=88Constant-Variables=E3=80=89
http://xahlee.org/elisp/Constant-Variables.html

but however, they use ascii hack of the 1970s, e.g. like `this' and
``this''.

Xah =E2=88=91 http://xahlee.org/ =E2=98=84
```
 0
Reply xahlee (1035) 10/18/2010 10:29:12 AM

```On Mon, 18 Oct 2010 12:03:12 +0200, Marc Mientki wrote:

>> ug. what browser + OS are you using?
>
> Firefox 3.6.10 on windows XP + SP3.

FWIW, I'm using FF 3.6.4 on XP+SP3, and I have no problems with that page.

You should check your font settings.

```
 0
Reply nobody (5153) 10/18/2010 2:14:08 PM

```On Mon, 18 Oct 2010 02:11:07 -0700, Xah Lee wrote:

> • List Comprehension is a redundant concept in programing. What List
> Comprehension does is simply 「map(func, filter(list, predicate))」.

You're assuming a single generator. Once you have multiple generators,
map + filter + concat starts getting ugly rather quick.

FWIW, I this:

[(x,y) | x <- [1..5], y <- [1..x]]

clearer than either this:

concat (map (\x -> map ((,) x) [1..x]) [1..5])

or this:

concat (map (\x -> map (\y -> (,) x y) [1..x]) [1..5])

```
 0
Reply nobody (5153) 10/18/2010 2:32:57 PM

```In comp.lang.lisp Xah Lee <xahlee@gmail.com> wrote:
> here's a article about list comprehension.
>
> ? ?What's List Comprehension and Why is it Harmful??
> http://xahlee.org/comp/list_comprehension.html
>
> i wrote it from a recent debate.
>
> I hope those of you computer scientists and language designers think

I agree with Xah, but I don't think he goes far enough. :) I think
list comprehensions in most languages are too "first order" and
constrain thinking into a little box.

Let's see if I can trudge ahead...

The base list comprehension in CL:
(map func (filter predicate list))

This is where a language with specialized list comprehensions usually
stops. But we can go on.

A slightly better higher order abstraction of it, corresponding to
Xah's LC function:
(action func predicate list)

How about we make it easier?
(defaction action1 (func1 predicate1))
(defaction action3 (func2 predicate2))
(defaction action4 (func3 predicate3))
(defaction action5 (func4 predicate4))

And now make our action function a little smarter:
(action action1 list)

Now, lets make it so we can compose a bunch of actions at once, in
order. Each later actions may process the results form a possible
application an earlier action in the sequence. The composition of the
actions can work to reduce the answer to have less elements that the
original list due to the filtering.

(compose-actions list
action3
action4
action1
...
)

The above would return two values, the first is the list of
result (what you expect from the composition of the actions). Exploded
example of how the first list is produced:
(...
(map func1
(filter predicate1
(map func4
(filter predicate4
(map func3
(filter predicate3 list)))))))

The second value is a list which will be the same size as the original
input list. What it does is provide a record of what happened to each
element in the list as the composition was being applied. Some careful
bookeeping must be done to keep track of the original positions of
the elements as they evolve through smaller and smaller result lists.

(
;; actions chosen for element 0 going backwards in time steps
(0 element[0] action1
(-1 element[0] action4
(-2 element[0] action3
...)))

;; actions chosen for element 1 going backwards in time steps
(0 element[1] action1
(-1 element[1] action4
(-2 element[1] action3
...)))

;; actions chosen for element 2 going backwards in time
;; Suppose this got wiped out by action 4 and action1 never saw it.
;; We don't have an entry for time step 0 and just keep carrying this
;; record along with us as is as we continue processing the composition.
(-1 element[2] (action4 'failed)
(-2 element[2] action3
...)))

;; actions chosen for element 1 going backwards in time steps
;; Notice it slid from index 3 to 2 because element 2 got removed in the
;; previous step, but we still recorded where its original place was.
(0 element[2] action1
(-1 element[3] action4
(-2 element[3] action3
...)))

....)

Using the above, we can likely analyze why certain decisions to act
might have failed on a per-element basis. Suppose like this:

(why-failed expert-rules (compose-actions list action3 action4 action1 ...))

Since this is all higher order codes, the implementation of any of
these functions can choose a parallel or multi machine implementation.
This isn't really available to you (to my 5 minutes of thinking
about it) in languages with list comprehension since the syntax and
implementation is hidden from you.

Later,
-pete

```
 0

```On Oct 18, 4:11\xA0am, Xah Lee <xah...@gmail.com> wrote:
> here's a article about list comprehension.
>

>
> Here's a example of LC in python:
>
> S = [2*n for n in range(0,9) if ( (n % 2) == 0)]
> print S
> # prints [0, 4, 8, 12, 16]
>

Ruby:

(0..9).select{|n| n.even?}.map{|n| 2*n}
==>[0, 4, 8, 12, 16]

shorter:

(0..9).select( &:even? ).map{|n| 2*n}
==>[0, 4, 8, 12, 16]

>
> The jargon "list comprehension" is opaque. It hampers communication
> and increases misunderstanding. A better name is simply "list
> generator".
>

+1

```
 0

```On Oct 18, 11:50=C2=A0am, w_a_x_man <w_a_x_...@yahoo.com> wrote:
> On Oct 18, 4:11\xA0am, Xah Lee <xah...@gmail.com> wrote:
>
> > here's a article about list comprehension.
>
> > Here's a example of LC in python:
>
> > S =3D [2*n for n in range(0,9) if ( (n % 2) =3D=3D 0)]
> > print S
> > # prints [0, 4, 8, 12, 16]
>
> Ruby:
>
> (0..9).select{|n| n.even?}.map{|n| 2*n}
> =C2=A0 =C2=A0 =3D=3D>[0, 4, 8, 12, 16]
>
> shorter:
>
> (0..9).select( &:even? ).map{|n| 2*n}
> =C2=A0 =C2=A0 =3D=3D>[0, 4, 8, 12, 16]
>
>
>
> > The jargon "list comprehension" is opaque. It hampers communication
> > and increases misunderstanding. A better name is simply "list
> > generator".
>
> +1

over the past few years, you've posted lots snippets of ruby code, and
i find them quite interesting, and those snippets gave me quite a
positive view of ruby.

btw, is unicode still a problem with ruby? i really need robust
unicode for my use.

also, if you can tell me, what's the main discussion group for ruby?
is it just comp.lang.ruby or is it web based forum?

Xah =E2=88=91 http://xahlee.org/ =E2=98=84
```
 0
Reply xahlee (1035) 10/19/2010 12:29:04 AM

```hi Peter,

thanks for the thoughts.

It seems to me your action is simply composition, which is available
in many functional langs.

you added a sorta trace functionality to composition. In Mathematica,
any lisp function (say named xyz), usually have a xyzList version,
which returns all the steps as a list. This is somewhat similar to
your trace. Some functional lang has this too i think. But in general,
i don't see the utility of your trace action kinda thing. It seems
like a domain specific lang's need.

Xah =E2=88=91 http://xahlee.org/ =E2=98=84

On Oct 18, 10:00=C2=A0am, Peter Keller <psil...@cs.wisc.edu> wrote:
> In comp.lang.lisp Xah Lee <xah...@gmail.com> wrote:
>
> > here's a article about list comprehension.
>
> > ? ?What's List Comprehension and Why is it Harmful??
> >http://xahlee.org/comp/list_comprehension.html
>
> > i wrote it from a recent debate.
>
> > I hope those of you computer scientists and language designers think
>
> I agree with Xah, but I don't think he goes far enough. :) I think
> list comprehensions in most languages are too "first order" and
> constrain thinking into a little box.
>
> Let's see if I can trudge ahead...
>
> The base list comprehension in CL:
> (map func (filter predicate list))
>
> This is where a language with specialized list comprehensions usually
> stops. But we can go on.
>
> A slightly better higher order abstraction of it, corresponding to
> Xah's LC function:
> (action func predicate list)
>
> How about we make it easier?
> (defaction action1 (func1 predicate1))
> (defaction action3 (func2 predicate2))
> (defaction action4 (func3 predicate3))
> (defaction action5 (func4 predicate4))
>
> And now make our action function a little smarter:
> (action action1 list)
>
> Now, lets make it so we can compose a bunch of actions at once, in
> order. Each later actions may process the results form a possible
> application an earlier action in the sequence. The composition of the
> actions can work to reduce the answer to have less elements that the
> original list due to the filtering.
>
> (compose-actions list
> =C2=A0 action3
> =C2=A0 action4
> =C2=A0 action1
> =C2=A0 ...
> =C2=A0 )
>
> The above would return two values, the first is the list of
> result (what you expect from the composition of the actions). Exploded
> example of how the first list is produced:
> (...
> =C2=A0 (map func1
> =C2=A0 =C2=A0 =C2=A0 =C2=A0(filter predicate1
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(map func4
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (fi=
lter predicate4
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 (map func3
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(filter predicate3 list)))))))
>
> The second value is a list which will be the same size as the original
> input list. What it does is provide a record of what happened to each
> element in the list as the composition was being applied. Some careful
> bookeeping must be done to keep track of the original positions of
> the elements as they evolve through smaller and smaller result lists.
>
> (
> ;; actions chosen for element 0 going backwards in time steps
> (0 element[0] action1
> =C2=A0 (-1 element[0] action4
> =C2=A0 =C2=A0 (-2 element[0] action3
> =C2=A0 =C2=A0 =C2=A0 ...)))
>
> ;; actions chosen for element 1 going backwards in time steps
> (0 element[1] action1
> =C2=A0 (-1 element[1] action4
> =C2=A0 =C2=A0 (-2 element[1] action3
> =C2=A0 =C2=A0 =C2=A0 ...)))
>
> ;; actions chosen for element 2 going backwards in time
> ;; Suppose this got wiped out by action 4 and action1 never saw it.
> ;; We don't have an entry for time step 0 and just keep carrying this
> ;; record along with us as is as we continue processing the composition.
> (-1 element[2] (action4 'failed)
> =C2=A0 (-2 element[2] action3
> =C2=A0 =C2=A0 =C2=A0...)))
>
> ;; actions chosen for element 1 going backwards in time steps
> ;; Notice it slid from index 3 to 2 because element 2 got removed in the
> ;; previous step, but we still recorded where its original place was.
> (0 element[2] action1
> =C2=A0 (-1 element[3] action4
> =C2=A0 =C2=A0 (-2 element[3] action3
> =C2=A0 =C2=A0 =C2=A0 ...)))
>
> ...)
>
> Using the above, we can likely analyze why certain decisions to act
> might have failed on a per-element basis. Suppose like this:
>
> (why-failed expert-rules (compose-actions list action3 action4 action1 ..=
..))
>
> Since this is all higher order codes, the implementation of any of
> these functions can choose a parallel or multi machine implementation.
> This isn't really available to you (to my 5 minutes of thinking
> about it) in languages with list comprehension since the syntax and
> implementation is hidden from you.
>
> Later,
> -pete
```
 0
Reply xahlee (1035) 10/19/2010 12:39:21 AM

```On Oct 18, 7:29=A0pm, Xah Lee <xah...@gmail.com> wrote:
> On Oct 18, 11:50=A0am, w_a_x_man <w_a_x_...@yahoo.com> wrote:
>
> > On Oct 18, 4:11\xA0am, Xah Lee <xah...@gmail.com> wrote:
>
> > > here's a article about list comprehension.
>
> > > Here's a example of LC in python:
>
> > > S =3D [2*n for n in range(0,9) if ( (n % 2) =3D=3D 0)]
> > > print S
> > > # prints [0, 4, 8, 12, 16]
>
> > Ruby:
>
> > (0..9).select{|n| n.even?}.map{|n| 2*n}
> > =A0 =A0 =3D=3D>[0, 4, 8, 12, 16]
>
> > shorter:
>
> > (0..9).select( &:even? ).map{|n| 2*n}
> > =A0 =A0 =3D=3D>[0, 4, 8, 12, 16]
>
> > > The jargon "list comprehension" is opaque. It hampers communication
> > > and increases misunderstanding. A better name is simply "list
> > > generator".
>
> > +1
>
> thanks a lot wax man. I added your example with credit.
>
> over the past few years, you've posted lots snippets of ruby code, and
> i find them quite interesting, and those snippets gave me quite a
> positive view of ruby.
>
> btw, is unicode still a problem with ruby? i really need robust
> unicode for my use.

Sorry, but I'm clueless about unicode. (It does seem strange that
a language from Japan has not always had great unicode support.)

>
> also, if you can tell me, what's the main discussion group for ruby?
> is it just comp.lang.ruby or is it web based forum?

I believe it's comp.lang.ruby. Posts at www.ruby-forum.com/forum/ruby
are forwarded to the newsgroup.
```
 0
Reply w_a_x_man (3243) 10/19/2010 1:49:35 AM

```On 18 out, 16:50, w_a_x_man <w_a_x_...@yahoo.com> wrote:
> On Oct 18, 4:11\xA0am, Xah Lee <xah...@gmail.com> wrote:
>
> > here's a article about list comprehension.
>
> > Here's a example of LC in python:
>
> > S =3D [2*n for n in range(0,9) if ( (n % 2) =3D=3D 0)]
> > print S
> > # prints [0, 4, 8, 12, 16]
>
> Ruby:
>
> (0..9).select{|n| n.even?}.map{|n| 2*n}
> =A0 =A0 =3D=3D>[0, 4, 8, 12, 16]
>
> shorter:
>
> (0..9).select( &:even? ).map{|n| 2*n}
> =A0 =A0 =3D=3D>[0, 4, 8, 12, 16]

idiomatic python:
[2*n for n in range(9) if n%2=3D=3D0]

custom syntax is always shorter and more convenient in direct style:
that's precisely why they made it into custom syntax in the first
place.

Of course, that's far better in a language that allows user-defined
custom syntax.  waxhead only agreed with you because ruby got no
custom list comprehension syntax nor a way to define one: if it was a
algorithm actually describing how it works, as he always does...
```
 0
Reply namekuseijin (629) 10/19/2010 2:14:19 AM

```In comp.lang.lisp Xah Lee <xahlee@gmail.com> wrote:
> hi Peter,
>
> thanks for the thoughts.
>
> It seems to me your action is simply composition, which is available
> in many functional langs.

That's true, but composition and list comprehensions should go hand in hand,
but with a specific syntax, it is uglier.

> you added a sorta trace functionality to composition. In Mathematica,
> any lisp function (say named xyz), usually have a xyzList version,
> which returns all the steps as a list. This is somewhat similar to
> your trace. Some functional lang has this too i think. But in general,
> i don't see the utility of your trace action kinda thing. It seems
> like a domain specific lang's need.

It is very useful for recording mutations of a tree walker and
extendable to recording mutations of a graph walker. The important
aspect is that if the actions are invertible, you get a piecewise
bijection from the original graph to the resultant one.

Later,
-pete
```
 0

```http://www.reddit.com/r/programming/comments/dw8op/whats_list_comprehension=
_and_why_is_it_harmful/
On Oct 18, 10:00=A0am, Peter Keller <psil...@cs.wisc.edu> wrote:
> In comp.lang.lisp Xah Lee <xah...@gmail.com> wrote:
> > What's List Comprehension and Why is it Harmful

the case hits reddit.

_and_why_is_it_harmful/

sometimes i do find some reddit replies interesting and knowledgable
(like slashdot), but am afraid 99% of it is uninformed garbage. In
this case, i haven't found a interesting argument. Though, it is
informative that many reddit readers didn't find my article
interesting. A
good feed back that i need to edit or expand it, with more examples,
etc.

Xah
```
 0

```On Mon, 18 Oct 2010 03:29:12 -0700 (PDT)
Xah Lee <xahlee@gmail.com> wrote:

> long story is... i need a way to quote code...  the corner bracket was
> choosen because it's standard chinese punctuation thus almost all
> computer today bought in the past 5 years can display it, and because
> it's different than ascii so it avoids ambiguity and complications.
> e.g. when the quoted text also contains the char that you use for
> quoting....

Most people just use typewriter-fixed-width fonts for that...

regards,
Marek
```
 0

```Xah Lee wrote:

>
> Here's a example of LC in python:
>
> S =3D [2*n for n in range(0,9) if ( (n % 2) =3D=3D 0)]
> print S
> # prints [0, 4, 8, 12, 16]
>
> It generates a list from 0 to 9, then remove the odd numbers by =E3=80=8C( =
> (n
> % 2) =3D=3D 0), then multiply each element by 2 in =E3=80=8C2*n=E3=80=8D, t=
> hen returns a
> list.

Arc:

Jarc> (map [* 2 _] (keep even (range 0 9)))
(0 4 8 12 16)

```
 0
Reply w_a_x_man (3243) 5/22/2011 9:30:11 AM

```On May 22, 2:30=A0am, "WJ" <w_a_x_...@yahoo.com> wrote:
> Xah Lee wrote:
>
> > Here's a example of LC in python:
>
> > S =3D3D [2*n for n in range(0,9) if ( (n % 2) =3D3D=3D3D 0)]
> > print S
> > # prints [0, 4, 8, 12, 16]
>
> > It generates a list from 0 to 9, then remove the odd numbers by =3DE3=
=3D80=3D8C( =3D
> > (n
> > % 2) =3D3D=3D3D 0), then multiply each element by 2 in =3DE3=3D80=3D8C2=
*n=3DE3=3D80=3D8D, t=3D
> > hen returns a
> > list.
>
> Arc:
>
> Jarc> (map [* 2 _] (keep even (range 0 9)))
> (0 4 8 12 16)

that's not lisp comprehension. that's just map. lol

Xah
```
 0
Reply xahlee (1035) 5/22/2011 8:18:03 PM

```Xah Lee wrote:

> On May 22, 2:30�am, "WJ" <w_a_x_...@yahoo.com> wrote:
> > Xah Lee wrote:
> >
> > > Here's a example of LC in python:
> >
> > > S =3D [2*n for n in range(0,9) if ( (n % 2) =3D=3D 0)]
> > > print S
> > > # prints [0, 4, 8, 12, 16]
> >
> > > It generates a list from 0 to 9, then remove the odd numbers by
> > > =E3=80=8C( = (n
> > > % 2) =3D=3D 0), then multiply each element by 2 in
> > > =E3=80=8C2*n=E3=80=8D, t= hen returns a
> > > list.
> >
> > Arc:
> >
> > Jarc> (map [* 2 _] (keep even (range 0 9)))
> > (0 4 8 12 16)
>
> that's not lisp comprehension. that's just map. lol
>
>  Xah

map is *better* than list comprehension!

```
 0
Reply w_a_x_man (3243) 5/23/2011 1:43:34 AM

```On May 22, 6:43=A0pm, "WJ" <w_a_x_...@yahoo.com> wrote:
> > > Jarc> (map [* 2 _] (keep even (range 0 9)))
> > > (0 4 8 12 16)
>
> > that's not lisp comprehension. that's just map. lol
>
> > =A0Xah
>
> map is *better* than list comprehension!

yeah, but thats my point in the original article.

Xah
```
 0
Reply xahlee (1035) 5/23/2011 2:01:39 AM

```> Haskell
>
> s = [ 2*x | x <- [0..], x^2 > 3 ]
This is not list comprehension but a description of a set. Using set notation to describe sets seems reasonable to me. But maybe that's only because I am used to set notation in the first place.
```
 0
Reply thomas.bartscher (77) 5/23/2011 8:10:34 AM

20 Replies
62 Views

Similar Articles

12/6/2013 10:57:43 PM
page loaded in 54030 ms. (0)

Similar Artilces:

S
Hi, I have an annoying problem with Sendmail 8.13; not sure if it's present in 8.14. I'm running the equivalent of this: sendmail -odd -oi -Ac -fsomeone@example.net recipient@example.net <<EOF From: <someone@example.net> To: <recipient@example.net> Cc: <unbalanced1@example.net, <unbalanced2@example.net Subject: A message Message text here. EOF Notice the unbalanced angle brackets on the Cc: line? (Please don't ask *why* I'm trying to submit such a message locally; just trust me when I say there's a valid reason for it. I'll happily discuss it at length off-list.) The problem is that during the client queue run, Sendmail gets upset at the unbalanced addresses in the Cc: line and generates DSNs. I don't want that! I don't want Sendmail to give a hoot about the headers; I only want it to worry about envelope addresses. In my limited testing, Sendmail 8.14 seems to work, but Sendmail 8.13 does not. For various reasons, it's difficult to move some of our customers to Sendmail 8.14, so is there a way in Sendmail 8.13 to suppress the DSNs? Regards, David. David F. Skoll wrote: [...] > sendmail -odd -oi -Ac

regexp for s///
I need to write regexp for s/// subtitution but I can't to thinkup it. Can anybody help me? I have string with possible 3 values: \$string = "A: aaa B: bbb"; or \$string = "A: aaa"; or \$string = "B: bbb"; Now I want to create 2 variables called \$myA and \$myB and want to store values to both variables depend on found or not found A and B in \$string. \$string = "A: aaa B: bbb"; \$myA="aaa"; \$myB="bbb"; or \$string = "A: aaa"; \$myA='aaa'; \$myB=''; or \$string = "B: bbb"; \$myA=''; \$myB='bbb'; Till now I use code bellow, but maybe can be writte as regexp. if(\$string =~ m/A:\s+([^B]+)\s+B:\s+(.+)/) { \$myA = \$1; \$myB = \$2;} elsif(\$string =~ m/A:\s+(.+)/) { \$myA = \$1; \$myB = '';} elseif(\$string =~ m/B:\s+(.+)/) { \$myA = ''; \$myB = \$1;} else {\$myA = \$myB = '';} -- Petr Vileta, Czech republic (My server rejects all messages from Yahoo and Hotmail. Send me your mail from another non-spammer site please.) Please reply to <petr AT practisoft DOT cz> At 2008-03-06 12:30PM, "Petr Vileta"

s///x
I was trying the s///x syntax and got unexpected results. Somebody cares to explain? Simplified example: #!/usr/bin/perl use warnings; use strict; local (\$,, \$\) = ("\t", "\n"); my \$x; \$_ = "abc 123 def 123 ghi"; \$x = s/ # Replace 1 # ONE 2 # TWO 3 # THREE / # by 4 # FOUR 5 # FIVE 6 # SIX /gsx; # global, single line, extended format print 'Made', \$x, 'replacements.'; print; This printed: Made 2 replacements. abc # by 4 # FOUR 5 # FIVE 6 # SIX def # by 4 # FOUR 5 # FIVE 6 # SIX ghi I expected: abc 456 def 456 ghi -- Affijn, Ruud & perl, v5.8.6 built for i386-freebsd-64int "Gewoon is een tijger." Dr.Ruud <rvtol+news@isolution.nl> wrote in comp.lang.perl.misc: > I was trying the s///x syntax and got unexpected results. > Somebody cares to explain? > >

Re: S A S ? #5 640860
Dear SAS-L-ers, Digime posted the following question: > Hi, > > Is this NewsGroup related to the SAS protocol used also for > exchange data in between Gambling Machines? > > thanx > No, and you can bet your bottom dollar on it! Nor, is this newsgroup related to the Special Air Service: http://britishsas.8m.com/ http://www.amazon.com/exec/obidos/tg/detail/-/0060578793/qid=1102712539/sr=1 -2/ref=sr_1_2/002-0803288-7179222?v=glance&s=books http://www.amazon.com/exec/obidos/tg/detail/-/1585740608/ref=pd_sim_b_3/002- 0803288-7179222?%5Fencoding=UTF8&v=glance ....though many of us do practice defensive programming! I hope that this suggestion proves helpful now, and in the future! Of course, all of these opinions and insights are my own, and do not reflect those of my organization or my associates. All SAS code and/or methodologies specified in this posting are for illustrative purposes only and no warranty is stated or implied as to their accuracy or applicability. People deciding to use information in this posting do so at their own risk. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Michael A. Raithel "The man who wrote

Where's java.sun's API?
am I on drugs or does this url as of last night no longer take you to the API: http://java.sun.com/j2se/1.4.2/docs/api/ it takes you to a pg w/links, when I click on top link (supposedly to take you to API) it stays on same page... ????????????????? anybody know what's going on? (I sent them feedback..) Frances "Frances Del Rio" <fdr58@yahoo.com> wrote in message news:2ui4l6F2a6ms8U1@uni-berlin.de... > am I on drugs or does this url as of last night no longer take you to > the API: http://java.sun.com/j2se/1.4.2/docs/api/ > > it takes you to a pg w/links, when I click on top link (supposedly to > take you to API) it stays on same page... ????????????????? > > anybody know what's going on? (I sent them feedback..) > > Frances > > Doesn't work here either, looks like bad linking, or the API is gone (?) K On Sat, 30 Oct 2004 14:25:47 -0400, Frances Del Rio wrote: > am I on drugs or does this url as of last night no longer take you to > the API: http://java.sun.com/j2se/1.4.2/docs/api/ Maybe you should start using the 1.5 docs. <http://java.sun.com/j2se/1.5.0/docs/api/overview-summary.html>

The Why's and Wherefore's of Behaviorism
The Why's and Wherefore's of Behaviorism ------------------- The puzzling thing about behaviorists has always been the extremely superficial ways they explain things. They level charges of duplicity and heap scorn, ridicule, and derision on those who question the doctrinal basis of their discipline but their explanations for what they do and why ring empty and completely devoid of meaning. But the reason for this is just becoming clear. Behaviorists do not deal in explanations. For them explanations are mental fictions devoid of experimental significance. In other words they can't explain any aspect of their discipline except what they have read in books and publications by the founders of behaviorism. Some of you might recall a couple of months ago I politely enquried of GS what the nature of the dependence was between the behaviorist's independent variables of environmental manipulation and dependent variables of behavioral measurement. And it wasn't the first time I had posed this kind of question. Of course he didn't know nor did I really expect him to understand the issue or the failing

What's with the Tcler's Wiki?
Howdy! As of this morning, July 7th, 8AM PDT, the Tcler's Wiki appears to be down. http://wiki.tcl.tk is redirected to http://mini.net/tcl (which is what I'd expect), which gives me a 404 error. Will

char's and int's
, other than the EOF, we > >> > get an unsigned int. > > >> No, other than the EOF we get an int that is the result of a conversion > >> of an unsigned char to an int. > > > Don't you mean "a conversion of a char to an int" ? > > No, I don't mean that. Then could you explain, please? My understanding is that a type char is provided, for storing, well, characters, in the system's favourite format. Functions such as fgetc() are used for reading in characters, but the output they give has to embrace both all real characters and have... is that a type char > is provided, for storing, well, characters, in the system's favourite > format. Functions such as fgetc() are used for reading in characters, > but the output they give has to embrace both all real characters and > have something different to indicate EOF. Hence they return an int. So > I would have assumed that the values they can return, other than EOF, > are the values of characters which in turn are the values a char can > have. I don't see where you have got "unsigned" from. AFAIAA you > should use unsigned char rather than char

s = std::string() vs. s = ""
constructor for strings, versus assigning > the null literal ""? I have found that my code typically uses "" for > returns and default arguments, but I am beginning to think this is poor > style. String() seems more direct. > I think they both almost come down to the same thing, they both call constructors.. s = std::string(); //calls the default constructor, string() s = ""; //calls the overloaded constructor, string(const char*) I guess the default constructor call is a little faster since it does not involve passing around a parameter...; out how much capacity you need, allocate it if necessary, and memcpy the > data in. if (!*str) 3 or 4 non-branching assembly language statements (inlined of course) That's almost certainly not going to be an application's primary bottleneck. <g> -- Pete Becker Dinkumware, Ltd. (http://www.dinkumware.com) [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] "Howard Hinnant" <hinnant@metrowerks.com> wrote in message news:hinnant-16A1AE.14294329092004@syrcnyrdrs-02->

It's not the buttons, it's the wheel!
Okay, I can see a good case for a one button mouse for the less technical user. And as long as one can simulate other buttons by control clicking and whatnot, it's pretty much a non issue if you have to use someone elses computer. But what irritates me is mice/pointers that lack a scroll wheel. It's such a hugely convenient feature, I use it constantly. I like it so much I got a keyboard with a second scroll wheel :) It also seems like of the computers I come into contact with, if they lack a scroll wheel on the mouse, they are most often an older computer, usually with a display resolution smaller than what I'm used to (1280x1024) so they actually need the scroll wheel more than newer computers. Surely Apple could come up with some clever design for a scroll wheel type feature on a one buttom mouse that is both functional and typically stylish. An interesting side note is that of my Mac friends who have late model Macs (G5), at least a couple do prefer the standard Apple mouse. I try to explain the utility of the scroll wheel to them, but I think it's one of those things where you just have to experience to realize how good it is. Like sex :) Lisa