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

equivalent PERL construct in LISP?

119 views
Skip to first unread message

Mike

unread,
May 1, 2012, 3:18:32 PM5/1/12
to
I'm use clisp. I'm quite experienced with PERL. A common pattern I use is:

my $list = (1, 2, 3, 4, 5, 6);
foreach my $i ($list) {
print "$i\n";
}

The "foreach" loop assigns each value of $list to $i in turn. Is there
a similar construct in LISP? Is this the "mapcar" or "maplist" construct?

Mike

WJ

unread,
May 1, 2012, 3:55:50 PM5/1/12
to
* (mapc #'print '(-2 0 3))

-2
0
3


Using Racket:

> (for-each displayln '(a b c))
a
b
c
> (for-each (lambda(x)(printf "= ~a =\n" x)) '(a b c))
= a =
= b =
= c =
> (for-each (curry printf "= ~a =\n") '(a b c))
= a =
= b =
= c =
> (for* ([i '(200 300)] [j 2]) (displayln (+ i j)))
200
201
300
301


Pascal J. Bourguignon

unread,
May 1, 2012, 3:58:23 PM5/1/12
to
(let ((list '(1 2 3 4 5 6)))
(dolist (i list (terpri))
(print i)))


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

Mike

unread,
May 1, 2012, 4:10:37 PM5/1/12
to
On 2012-05-01, Pascal J. Bourguignon <p...@informatimago.com> wrote:
> Mike <mi...@mac.com> writes:
>
>> I'm use clisp. I'm quite experienced with PERL. A common pattern I use is:
>>
>> my $list = (1, 2, 3, 4, 5, 6);
>> foreach my $i ($list) {
>> print "$i\n";
>> }
>>
>> The "foreach" loop assigns each value of $list to $i in turn. Is there
>> a similar construct in LISP? Is this the "mapcar" or "maplist" construct?
>>
>> Mike
>
> (let ((list '(1 2 3 4 5 6)))
> (dolist (i list (terpri))
> (print i)))
>
>

Thank you.

Mike

Mike

unread,
May 1, 2012, 4:10:57 PM5/1/12
to
On 2012-05-01, WJ <w_a_...@yahoo.com> wrote:
> Mike wrote:
>
>> I'm use clisp. I'm quite experienced with PERL. A common pattern I use is:
>>
>> my $list = (1, 2, 3, 4, 5, 6);
>> foreach my $i ($list) {
>> print "$i\n";
>> }
>>
>> The "foreach" loop assigns each value of $list to $i in turn. Is there
>> a similar construct in LISP? Is this the "mapcar" or "maplist" construct?
>>
>> Mike
>
> * (mapc #'print '(-2 0 3))
>
> -2
> 0
> 3

Thank you.

Mike

Tim Bradshaw

unread,
May 1, 2012, 4:53:58 PM5/1/12
to
On 2012-05-01 19:18:32 +0000, Mike said:

> The "foreach" loop assigns each value of $list to $i in turn. Is there
> a similar construct in LISP? Is this the "mapcar" or "maplist" construct?

There are a lot of constructs which are more-or-less equivalent. For
the specific loop-over-a-list example, dolist (as given by another
person) is probably the simplest. At the other end of the scale is the
hairy loop macro in CL, which you'll rapidly discover is hated by some
but when used with some taste can make for very readable code. Your
example in LOOP would be

(loop for i in <list>
do ...)

Perl does have a hugely powerful syntax however, and I'm not sure even
loop is as expressive as Perl can be. I very often find myself doing
this sort of thing:


RECORD: while (my $x = ...) {
...
foreach (....) {
...
next if (...);
...
next RECORD if (...);
}
}

Of course, Lisp's advantage is that its syntax can easily be extended
(although I've not been able to work out how you could easily add
Perl's lovely 'trailing conditional' thing.


Pascal J. Bourguignon

unread,
May 1, 2012, 5:04:16 PM5/1/12
to
(defun gen-perform (body)
(let ((actual-body (butlast body 2))
(operator (first (last body 2)))
(test (first (last body))))
`(,operator ,test (progn ,@actual-body))))

(defmacro perform (&body body)
(gen-perform body))

(dotimes (i 3)
(perform (print i)
unless (zerop i)))

prints:
1
2

Tim Bradshaw

unread,
May 1, 2012, 6:51:27 PM5/1/12
to
"Pascal J. Bourguignon" <p...@informatimago.com> wrote:

> (defun gen-perform (body)
> (let ((actual-body (butlast body 2))
> (operator (first (last body 2)))
> (test (first (last body))))
> `(,operator ,test (progn ,@actual-body))))
>
> (defmacro perform (&body body)
> (gen-perform body))
>
> (dotimes (i 3)
> (perform (print i)
> unless (zerop i)))
>

Something like that is the best I can think of, and it's obviously not
nearly as nice.

Pascal J. Bourguignon

unread,
May 1, 2012, 6:59:23 PM5/1/12
to
You can shadow defun, defmacro, lambda, let, let*, labels, flet, progn,
progv, etc, to replace the implicit progn by an implicit perform.

XeCycle

unread,
May 2, 2012, 12:25:46 AM5/2/12
to
If you just want to print out contents of the list, `format' can
also be used.

--
Carl Lei (XeCycle)
Department of Physics, Shanghai Jiao Tong University
OpenPGP public key: 7795E591
Fingerprint: 1FB6 7F1F D45D F681 C845 27F7 8D71 8EC4 7795 E591

Tim Bradshaw

unread,
May 2, 2012, 4:56:40 AM5/2/12
to
On 2012-05-01 22:59:23 +0000, Pascal J. Bourguignon said:

> You can shadow defun, defmacro, lambda, let, let*, labels, flet, progn,
> progv, etc, to replace the implicit progn by an implicit perform.

You could (but there are a lot more than that!). But (a) that's a lot
of work and (b) you now can't use anyone else's macros which expand
into an implicit progn, because they'll ue the wrong progn. I think
the only way out of that is to use a code walker, and replace the REPL
/ LOAD / COMPILE-FILE and so on.

Obviously this is all possible: my point is really that doing this is a
lot of work, where something like adding (say) UNLESS if CL did not
have it already is a tiny amount of work. That's probably right
though, because trailing conditionals are a much larger syntactic
change to the language (and I don't even know if they'd work visually
in CL the way they do in Perl, because they'd be so syntactically odd:

(print x) unless ...

has all the peculiar mixed-lisp-and-<something else> that LOOP has,
except worse.

daniel....@excite.com

unread,
May 2, 2012, 5:29:37 PM5/2/12
to
I think it's fair to say that the trailing conditional you've shown is syntactic sugar that fits nicely in traditional context sensitive grammar based syntax, but does not fit in Lisp's S-expression syntax.

Let us appreciate the trailing conditional's beauty and wistfully admit S-expressions (as represented by CL's reader) don't have this particular jewel.

Sean McAfee

unread,
May 2, 2012, 7:16:39 PM5/2/12
to
Mike <mi...@mac.com> writes:
> I'm use clisp. I'm quite experienced with PERL. A common pattern I use is:
>
> my $list = (1, 2, 3, 4, 5, 6);
> foreach my $i ($list) {
> print "$i\n";
> }

You know this just prints "6", right?

I suppose Lisp's PROGN is the closest thing to Perl's comma operator.

Tim Bradshaw

unread,
May 3, 2012, 2:27:39 AM5/3/12
to
<daniel....@excite.com> wrote:

> Let us appreciate the trailing conditional's beauty and wistfully admit
> S-expressions (as represented by CL's reader) don't have this particular jewel.

That's pretty much my conclusion

Pascal J. Bourguignon

unread,
May 4, 2012, 6:00:11 AM5/4/12
to
Well, if you go this way, another thing that's rather difficult to adapt
to Lisp is perligata.

Marco Antoniotti

unread,
May 4, 2012, 8:04:26 AM5/4/12
to
Quare hoc dicis? :)

--
MA

Pascal J. Bourguignon

unread,
May 4, 2012, 8:32:20 AM5/4/12
to
Because, basically, perligata uses latin-like declinations where lisp
uses positions in lists.

Something like:

(verb subject object)
vs.
subjecto verb objecti ; or
verb subjecto objecti ; or
objecti verb subjecto


(buffalo buffalo buffalo)
vs.
buffal buffalo buffali


So the first problem is that several symbols in the sources should
correspond to the same actual lisp symbol, only in its various uses
(symbol-function, symbol-value, symbol-plist, symbol as block name,
symbol as package name, etc. Ie. CL is a lisp-∞ not just a lisp-2).

And the second problem is that this breaks entirely the structure of
lisp sexps, which are ordered lists.

I'm not saying that it's not possible to write a parser that will build
sexps from some lispigata text; what I'm saying is that perligata or a
lispigata language is fundamentally text-based, and needs a full fleshed
parser to generate an abstract syntax tree that is non-homothetic to the
original source text.


(perform … unless …)

fits into lisp sexps. lispigata not so. (But you can always write a
bracketing macros to insert lispigata into lisp sexps).

WJ

unread,
Dec 20, 2014, 12:27:57 AM12/20/14
to
Pascal J. Bourguignon wrote:

> Mike <mi...@mac.com> writes:
>
> > I'm use clisp. I'm quite experienced with PERL. A common pattern I use is:
> >
> > my $list = (1, 2, 3, 4, 5, 6);
> > foreach my $i ($list) {
> > print "$i\n";
> > }
> >
> > The "foreach" loop assigns each value of $list to $i in turn. Is there
> > a similar construct in LISP? Is this the "mapcar" or "maplist" construct?
> >
> > Mike
>
> (let ((list '(1 2 3 4 5 6)))
> (dolist (i list (terpri))
> (print i)))

Gauche Scheme:

gosh> (for-each print (iota 9))
0
1
2
3
4
5
6
7
8


0 new messages