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?
Cheers
Brad
"bradb" <··············@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
Zach Beane wrote:
> "bradb" <··············@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.
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
"bradb" <··············@gmail.com> writes:
> Zach Beane wrote:
>> "bradb" <··············@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?
Pascal Bourguignon <···@informatimago.com> wrote:
+---------------
| "bradb" <··············@gmail.com> writes:
| > Zach Beane wrote:
| >> "bradb" <··············@gmail.com> writes:
| >> > 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 ...)
| > 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)
+---------------
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 <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
"bradb" <··············@gmail.com> writes:
> Zach Beane wrote:
>> "bradb" <··············@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" <··············@gmail.com> writes:
Pascal Bourguignon <···@informatimago.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.
Bill Atkins <······@rpi.edu> writes:
> Pascal Bourguignon <···@informatimago.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!"
Pascal Bourguignon <···@informatimago.com> writes:
> "bradb" <··············@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.
Kalle Olavi Niemitalo <···@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.
--
__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
Pascal Bourguignon <···@informatimago.com> writes:
> Kalle Olavi Niemitalo <···@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
···@sevak.isi.edu (Thomas A. Russ) writes:
> Pascal Bourguignon <···@informatimago.com> writes:
>
>> Kalle Olavi Niemitalo <···@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")
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!"
Pascal Bourguignon <···@informatimago.com> writes:
> Kalle Olavi Niemitalo <···@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.
bradb wrote:
> 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?
>
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