Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: the "loop" macro

158 views
Skip to first unread message

WJ

unread,
Mar 15, 2012, 9:21:20 AM3/15/12
to
Kent M Pitman wrote:

> Looking at such an example, one might ask why WHEN is there at
> all. But the answer turns out to be that it's *very* hard to
> write a macro in CL that has a "detached" piece of syntax. So
> you need to have a way to get to the collect point, and it's
> often in a conditional. Consider:
>
> (loop for x in y
> when (f x)
> collect (g x))
>
> This one you can't write as
>
> (dolist (x y)
> (when (f x)
> (collect (g x))))

Clojure:

user=> (keep #(if (odd? %) (* % %)) [1 2 3 4])
(1 9)

> The ability in loop to do even complex things like:
>
> (loop for x in '(1 2 3 4 5 6 7)
> when (evenp x)
> collect x into evens
> else
> collect x into odds
> finally
> (return (values evens odds)))
> => (2 4 6), (1 3 5 7)
>
> is considerably easier and clearer than some other alternatives.

That doesn't look very Lispy to me, Kent.

Clojure:

user=> (replace (group-by even? (range 1 8)) [true false])
[[2 4 6] [1 3 5 7]]


> Also, being able to vary the collection is handy. Consider:
>
> (loop for x in '(a b (c d) e f)
> when (atom x)
> collect x
> else
> append x)
> => (A B C D E F)

That doesn't look very Lispy to me, Kent.

Clojure:

user=> (flatten '(a b (c d) e f))
(a b c d e f)

WJ

unread,
Mar 15, 2012, 9:36:52 AM3/15/12
to
WJ wrote:

> Kent M Pitman wrote:
>
> > Looking at such an example, one might ask why WHEN is there at
> > all. But the answer turns out to be that it's very hard to
Kent M. Pitman wrote:

> It's unfortunate that the ability to define other loop-paths was
> omitted from the standard, since most implementations have such
> a thing. Some things I think you have to just code longhand.
>
> (loop with best-foo = nil ;untested
> for foo in (list foo1 foo2)
> when (or (not best-foo)
> (> (weight foo) (weight best-foo)))
> do (setq best-foo foo)
> finally (return best-foo))
>
> All in all, I think this is still pretty readable, though I'd accept
> the classic
>
> (let ((best-foo nil)) ;untested
> (dolist (foo (list foo1 foo2))
> (when (or (not best-foo)
> (> (weight foo) (weight best-foo)))
> (setq best-foo foo)))
> best-foo)

That doesn't look very Lispy to me, Kent.

Clojure:

user=> (max-key count "ah" "sleipnir" "see" "zebra")
"sleipnir"
user=> (apply max-key count ["ah" "sleipnir" "see" "zebra"])
"sleipnir"



WJ

unread,
Mar 15, 2012, 9:54:15 AM3/15/12
to
MatzLisp (Ruby):

["ah","sleipnir","see","zebra"].max_by{|s| s.size}
==>"sleipnir"

WJ

unread,
Mar 31, 2012, 4:46:53 AM3/31/12
to
WJ wrote:

> Kent M Pitman wrote:
>
> > Looking at such an example, one might ask why WHEN is there at
> > all. But the answer turns out to be that it's very hard to
> > write a macro in CL that has a "detached" piece of syntax. So
> > you need to have a way to get to the collect point, and it's
> > often in a conditional. Consider:
> >
> > (loop for x in y
> > when (f x)
> > collect (g x))
> >
> > This one you can't write as
> >
> > (dolist (x y)
> > (when (f x)
> > (collect (g x))))
>
> Clojure:
>
> user=> (keep #(if (odd? %) (* % %)) [1 2 3 4])
> (1 9)

(def f number?)
(defn g [n] (* n n))

(reduce #(if (f %2)(cons (g %2) %1) %1) '() '(a 2 c 4))
==> (16 4)

WJ

unread,
May 3, 2012, 5:04:31 AM5/3/12
to
WJ wrote:

> Kent M Pitman wrote:
>
> > Looking at such an example, one might ask why WHEN is there at
> > all. But the answer turns out to be that it's very hard to
> > write a macro in CL that has a "detached" piece of syntax. So
> > you need to have a way to get to the collect point, and it's
> > often in a conditional. Consider:
> >
> > (loop for x in y
> > when (f x)
> > collect (g x))
> >
> > This one you can't write as
> >
> > (dolist (x y)
> > (when (f x)
> > (collect (g x))))
>
> Clojure:
>
> user=> (keep #(if (odd? %) (* % %)) [1 2 3 4])
> (1 9)


Racket:

(filter-map (lambda(n) (and (odd? n) (* n n))) '[1 2 3 4])
=> '(1 9)

>
> > The ability in loop to do even complex things like:
> >
> > (loop for x in '(1 2 3 4 5 6 7)
> > when (evenp x)
> > collect x into evens
> > else
> > collect x into odds
> > finally
> > (return (values evens odds)))
> > => (2 4 6), (1 3 5 7)
> >
> > is considerably easier and clearer than some other alternatives.
>
> That doesn't look very Lispy to me, Kent.
>
> Clojure:
>
> user=> (replace (group-by even? (range 1 8)) [true false])
> [[2 4 6] [1 3 5 7]]


Racket:

(partition even? '[1 2 3 4 5 6 7])
=> '(2 4 6)
'(1 3 5 7)


>
>
> > Also, being able to vary the collection is handy. Consider:
> >
> > (loop for x in '(a b (c d) e f)
> > when (atom x)
> > collect x
> > else
> > append x)
> > => (A B C D E F)
>
> That doesn't look very Lispy to me, Kent.
>
> Clojure:
>
> user=> (flatten '(a b (c d) e f))
> (a b c d e f)


Racket:

(flatten '(a b (c d) e f))
=> '(a b c d e f)

WJ

unread,
Apr 10, 2013, 4:43:03 PM4/10/13
to
WJ wrote:

> Kent M Pitman wrote:
>
> > Looking at such an example, one might ask why WHEN is there at
> > all. But the answer turns out to be that it's very hard to
> > write a macro in CL that has a "detached" piece of syntax. So
> > you need to have a way to get to the collect point, and it's
> > often in a conditional. Consider:
> >
> > (loop for x in y
> > when (f x)
> > collect (g x))
> >
> > This one you can't write as
> >
> > (dolist (x y)
> > (when (f x)
> > (collect (g x))))

Instead of CL, tCL.

namespace path {::tcl::mathop ::tcl::mathfunc}

lmap n {2 3 4 5} {if [& 1 $n] {** $n 2} {continue}}
==>
9 25

WJ

unread,
Jul 7, 2013, 9:36:33 PM7/7/13
to
WJ wrote:

> WJ wrote:
>
> > Kent M Pitman wrote:
> >
> > > Looking at such an example, one might ask why WHEN is there at
> > > all. But the answer turns out to be that it's very hard to
> > > write a macro in CL that has a "detached" piece of syntax. So
> > > you need to have a way to get to the collect point, and it's
> > > often in a conditional. Consider:
> > >
> > > (loop for x in y
> > > when (f x)
> > > collect (g x))
> > >
> > > This one you can't write as
> > >
> > > (dolist (x y)
> > > (when (f x)
> > > (collect (g x))))
>

Julia:

julia> map(square, filter(isodd, [1:22]))
11-element Int32 Array:
1
9
25
49
81
121
169
225
289
361
441

WJ

unread,
Nov 8, 2013, 6:50:24 AM11/8/13
to
Nonsense.

Arc:

(accum collect
(each x '(2 3 4 5)
(when (odd x)
(collect (sqrt x)))))

===>

(1.7320508075688772 2.23606797749979)


It's better to use a filtering-mapping function:

(trues
[and (odd _) (sqrt _)]
'(2 3 4 5))

WJ

unread,
Nov 8, 2013, 7:02:21 AM11/8/13
to
WJ wrote:

> WJ wrote:
>
> > WJ wrote:
> >
> > > Kent M Pitman wrote:
> > >
> > > > Looking at such an example, one might ask why WHEN is there at
> > > > all. But the answer turns out to be that it's very hard to
> > > > write a macro in CL that has a "detached" piece of syntax. So
> > > > you need to have a way to get to the collect point, and it's
> > > > often in a conditional. Consider:
> > > >
> > > > (loop for x in y
> > > > when (f x)
> > > > collect (g x))
> > > >
> > > > This one you can't write as
> > > >
> > > > (dolist (x y)
> > > > (when (f x)
> > > > (collect (g x))))
> >
> > Instead of CL, tCL.
> >
> > namespace path {::tcl::mathop ::tcl::mathfunc}
> >
> > lmap n {2 3 4 5} {if [& 1 $n] {** $n 2} {continue}}
> > ==>
> > 9 25
>
> Nonsense.


I meant that this was nonsense:

> > > > This one you can't write as
> > > >
> > > > (dolist (x y)
> > > > (when (f x)
> > > > (collect (g x))))




>

WJ

unread,
Nov 15, 2014, 11:08:12 AM11/15/14
to
WJ wrote:

> WJ wrote:
>
> > Kent M Pitman wrote:
> >
> > > Looking at such an example, one might ask why WHEN is there at
> > > all. But the answer turns out to be that it's very hard to
> > > write a macro in CL that has a "detached" piece of syntax. So
> > > you need to have a way to get to the collect point, and it's
> > > often in a conditional. Consider:
> > >
> > > (loop for x in y
> > > when (f x)
> > > collect (g x))
> > >
> > > This one you can't write as
> > >
> > > (dolist (x y)
> > > (when (f x)
> > > (collect (g x))))

Gauche Scheme:

(filter-map
(^x (and (odd? x) (square x)))
(iota 9))

===>
(1 9 25 49)

WJ

unread,
Nov 16, 2014, 3:16:30 AM11/16/14
to
> in the end, I couldn't justify to new users why they shouldn't just write
> the more obvious:
>
> (loop for item in list
> collect (f item))
>
> And sure, you could also write
>
> (mapcar #'f list)
>
> but the point is that if you want to change the accumulation from collect
> to max or min, you can't make a trivial edit to fix that, whereas with the
> loop one you can do
>
> (loop for item in list
> maximize (f item))


Gauche Scheme:

gosh> (map abs '(2 0 9 -7 3))
(2 0 9 7 3)
gosh> (reduce max #f '(2 0 9 -7 3))
9

WJ

unread,
Dec 24, 2015, 12:58:53 AM12/24/15
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
WJ wrote:

> > in the end, I couldn't justify to new users why they shouldn't just write
> > the more obvious:
> >
> > (loop for item in list
> > collect (f item))

MatzLisp (Ruby):

[-8,0,3].map &:abs
==>[8, 0, 3]

> >
> > And sure, you could also write
> >
> > (mapcar #'f list)
> >
> > but the point is that if you want to change the accumulation from collect
> > to max or min, you can't make a trivial edit to fix that, whereas with the
> > loop one you can do
> >
> > (loop for item in list
> > maximize (f item))

[-8,0,3].max
==>3
[-8,0,3].max_by &:abs
==>-8

--
[A]n unholy alliance of leftists, capitalists, and Zionist supremacists has
schemed to promote immigration and miscegenation with the deliberate aim of
breeding us out of existence in our own homelands.... [T]he real aim stays the
same: the biggest genocide in human history.... --- Nick Griffin
(https://www.youtube.com/watch?v=K0hD7IffTJs)

WJ

unread,
Dec 24, 2015, 3:46:06 PM12/24/15
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
MatzLisp (Ruby):

(0..8).grep->(x){x.odd?}{|x| x*x}
===>
[1, 9, 25, 49]

--
Elie [Wiesel] thus could have remained at Birkenau to await the Russians.
Although his father had permission to stay with him as a hospital patient or
orderly, father and son talked it over and decided to move out with the
Germans. --- Robert Faurisson

WJ

unread,
Apr 24, 2016, 5:03:12 PM4/24/16
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
WJ wrote:

> > > in the end, I couldn't justify to new users why they shouldn't just write
> > > the more obvious:
> > >
> > > (loop for item in list
> > > collect (f item))
>
> MatzLisp (Ruby):
>
> [-8,0,3].map &:abs
> ==>[8, 0, 3]

OCaml:

List.map abs [-8;0;3];;
===>
[8; 0; 3]

--
Europe is about to abolish itself. Civilizations cannot survive, when they no
longer secure their borders and uncontrollably accept hundreds of thousands,
even millions, of un-integratable strangers. The megalomaniac "We can do it"
mentality has, throughout European history, caused disasters.
europeancivilwar.com/europe-abolishes-itself-as-first-planeloads-of-syrians-imported-into-germany-from-turkey-swiss-mp-predicts-war

WJ

unread,
Jul 23, 2016, 10:34:46 PM7/23/16
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
WJ wrote:

> WJ wrote:
>
> > > in the end, I couldn't justify to new users why they shouldn't just write
> > > the more obvious:
> > >
> > > (loop for item in list
> > > collect (f item))
>
> MatzLisp (Ruby):
>
> [-8,0,3].map &:abs
> ==>[8, 0, 3]

R:

> abs(c(0,-2,-8,7))
[1] 0 2 8 7

>
> > >
> > > And sure, you could also write
> > >
> > > (mapcar #'f list)
> > >
> > > but the point is that if you want to change the accumulation from collect
> > > to max or min, you can't make a trivial edit to fix that, whereas with the
> > > loop one you can do
> > >
> > > (loop for item in list
> > > maximize (f item))
>
> [-8,0,3].max
> ==>3
> [-8,0,3].max_by &:abs
> ==>-8

R:

> Reduce(max, c(3,2,8,5))
[1] 8

> range(c(3,2,8,5))[2]
[1] 8

--
In the United States in 2005, 37,460 white females were sexually assaulted or
raped by a black man, while between zero and ten black females were sexually
assaulted or raped by a white man. What this means is that every day in the
United States, over one hundred white women are raped or sexually assaulted by
a black man. -- http://archive.frontpagemag.com/readArticle.aspx?ARTID=26368
0 new messages