Is there a nicer way to gather the pairs than that?
Cheers
Brad
LOOP destructures. Try this:
(loop for (start end) on (all-matches ...) by #'cddr do ...)
Zach
Also, to really start a hot thread,
(loop :for (start end) :on (....) :do) ; keywords
(loop for (start end) on (...) do) ; no keywords
which is better and why? :-)
Brad
> Zach Beane wrote:
>> "bradb" <brad.be...@gmail.com> writes:
>>
>> > I'm using CL-PPCRE, and some functions return lists of start and end
>> > matches, so a return might be
>> > (0 2 4 7 10 15), three matches.
>> > Right now I loop over the matches like
>> > (loop :for match :on (all-matches scanner text :start start) :by
>> > #'cddr
>> > :do (let ((start (first match))
>> > (end (second match)))
>> > (subseq text start end))
>> >
>> > Is there a nicer way to gather the pairs than that?
>>
>> LOOP destructures. Try this:
>>
>> (loop for (start end) on (all-matches ...) by #'cddr do ...)
>>
>> Zach
> Ah, that is much much nicer. It is a shame that loop doesn't defualt
> to looping by the natural size of the destructure, so you don't need
> the BY #'CDDR.
(defmacro loop* (&rest stuff)
...
:for ,destructuring-stuff :on ,list by (lambda (list)
(nth-cdr ,(length destructuring-stuff)
> Also, to really start a hot thread,
> (loop :for (start end) :on (....) :do) ; keywords
> (loop for (start end) on (...) do) ; no keywords
> which is better and why? :-)
>
> Brad
>
--
__Pascal Bourguignon__ http://www.informatimago.com/
In a World without Walls and Fences,
who needs Windows and Gates?
> Zach Beane wrote:
>> "bradb" <brad.be...@gmail.com> writes:
>>
>> > I'm using CL-PPCRE, and some functions return lists of start and end
>> > matches, so a return might be
>> > (0 2 4 7 10 15), three matches.
>> > Right now I loop over the matches like
>> > (loop :for match :on (all-matches scanner text :start start) :by
>> > #'cddr
>> > :do (let ((start (first match))
>> > (end (second match)))
>> > (subseq text start end))
>> >
>> > Is there a nicer way to gather the pairs than that?
>>
>> LOOP destructures. Try this:
>>
>> (loop for (start end) on (all-matches ...) by #'cddr do ...)
>>
>> Zach
> Ah, that is much much nicer. It is a shame that loop doesn't defualt
> to looping by the natural size of the destructure, so you don't need
> the BY #'CDDR.
It's but a defmacro away:
(defmacro loop* (&rest stuff)
...
`(cl:loop
...
:for ,destructuring-stuff :on ,list
:by (lambda (list) (nthcdr ,(length destructuring-stuff) list))
...))
> Also, to really start a hot thread,
> (loop :for (start end) :on (....) :do) ; keywords
> (loop for (start end) on (...) do) ; no keywords
> which is better and why? :-)
Try this at your REPL to see which is better, and why.
http://paste.lisp.org/display/28420
--
__Pascal Bourguignon__ http://www.informatimago.com/
In a World without Walls and Fences,
who needs Windows and Gates?
"bradb" <brad.be...@gmail.com> writes:
> Try this at your REPL to see which is better, and why.
>
> http://paste.lisp.org/display/28420
So just treat LOOP keywords as if they were in COMMON-LISP and expect
the same mayhem you would from exporting your own DEFUN.
No it's not possible, since COMMON-LISP doesn't export WHILE.
And it's much simplier to use keywords (from the KEYWORD package) than
to use SHADOW at the right places and qualify UTILITY:WHILE.
--
__Pascal Bourguignon__ http://www.informatimago.com/
"A TRUE Klingon warrior does not comment his code!"
> "bradb" <brad.be...@gmail.com> writes:
>> Also, to really start a hot thread,
>> (loop :for (start end) :on (....) :do) ; keywords
>> (loop for (start end) on (...) do) ; no keywords
>> which is better and why? :-)
>
> Try this at your REPL to see which is better, and why.
>
> http://paste.lisp.org/display/28420
That code defines a package EXAMPLE2, causes WHILE to be interned
to it by using it as a loop keyword, and then tries to use the
MYLOOP package which exports another WHILE:
* (use-package "MYLOOP")
debugger invoked on a SB-INT:NAME-CONFLICT in thread #<THREAD "initial thread" {9003399}>:
USE-PACKAGE #<PACKAGE "MYLOOP"> causes name-conflicts in
#<PACKAGE "EXAMPLE2"> between the following symbols:
MYLOOP:WHILE, WHILE
See also:
The ANSI Standard, Section 11.1.1.2.5
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [RESOLVE-CONFLICT] Resolve conflict.
1: [ABORT ] Exit debugger, returning to top level.
(SB-INT:NAME-CONFLICT #<PACKAGE "EXAMPLE2"> USE-PACKAGE #<PACKAGE "MYLOOP">)
0] 0
Select a symbol to be made accessible in package EXAMPLE2:
1. MYLOOP:WHILE
2. WHILE
Enter an integer (between 1 and 2): 1
T
*
Resolving the conflict doesn't seem very difficult or cumbersome;
prepending colons to all loop keywords would require more typing.
And if this were in a program rather than in the REPL, then you'd
surely avoid USE-PACKAGE and instead put MYLOOP in the DEFPACKAGE
form you already had for EXAMPLE2.
There are other loop keywords for which you could construct
similar conflicts; for example SUM. That one is also more likely
to occur as the name of a variable than WHILE is. Which you
cannot solve by using keywords instead.
(loop :for i :from 1 :to 100 :sum i) ; perfectly solved, thank you.
--
__Pascal Bourguignon__ http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
As a side note, what is wrong with using cl-ppcre:do-matches or
cl-ppcre:do-matches-as-strings or cl-ppcre:all-matches-as-strings ?
(defun collect-subseqs (text list)
(loop while list collect
(subseq text (pop list) (pop list))))
CL-USER 3 > (collect-subseqs "test 123" '())
NIL
CL-USER 4 > (collect-subseqs "test 123" '(2))
("st 123")
CL-USER 5 > (collect-subseqs "test 123" '(2 7))
("st 12")
CL-USER 6 >
Wade
The problem with any such automatic sizing is LOOPs like this:
(loop for (a b c . rest) on list by #'cdddr ...)
or even this:
(flet ((stepper (list)
(case (car list)
((:one) (cddr list))
((:two) (cdddr list))
((:three) (cdddr list))
(otherwise (cdr list)))))
(loop for (key a b c) on list by #'stepper ...))
which can parse lists like this:
(:one 123 :two 234 453 :three 7 5 8 :special :other 99 22 :two 34 54)
-Rob
-----
Rob Warnock <rp...@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
> Kalle Olavi Niemitalo <k...@iki.fi> writes:
>> There are other loop keywords for which you could construct
>> similar conflicts; for example SUM. That one is also more likely
>> to occur as the name of a variable than WHILE is. Which you
>> cannot solve by using keywords instead.
>
> (loop :for i :from 1 :to 100 :sum i) ; perfectly solved, thank you.
That uses neither SUM nor :SUM as the name of a variable.
> Kalle Olavi Niemitalo <k...@iki.fi> writes:
> > There are other loop keywords for which you could construct
> > similar conflicts; for example SUM. That one is also more likely
> > to occur as the name of a variable than WHILE is. Which you
> > cannot solve by using keywords instead.
>
> (loop :for i :from 1 :to 100 :sum i) ; perfectly solved, thank you.
But it still doesn't solve:
(let ((sum (loop :for ...)))
(print sum))
(use "SOME-PACKAGE-EXPORTING-SUM")
--
Thomas A. Russ, USC/Information Sciences Institute
The fundamental difference, is that you can rename sum either in your
let, or in the SOME-PACKAGE-EXPORTING-SUM, but you cannot rename the
LOOP keywords.
--
__Pascal Bourguignon__ http://www.informatimago.com/
"You question the worthiness of my code? I should kill you where you
stand!"
Using Scheme:
(define str "DOLL IS A COB TOP LONG")
(define ind '(18 20 15 17 4 8 10 13 1 3))
(define (subs str lst) (apply substring str (take lst 2)))
(let recur ((lst ind))
(if (pair? lst)
(begin (display (subs str lst))
(recur (cddr lst)))))
==> LOOP IS COBOL
Arc:
arc> (= str "DOLL? IS A COB TOP LONG"?)
"DOLL IS A COB TOP LONG"
arc> (string (map [apply cut str _] (pair '(18 20 15 17 4 8 10 13 1 3))))
"LOOP IS COBOL"