Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > pt.comp.programacao > #280 > unrolled thread
| Started by | Patricia Ferreira <pferreira@example.com> |
|---|---|
| First post | 2024-03-10 19:28 -0300 |
| Last post | 2024-03-11 20:36 -0300 |
| Articles | 4 — 2 participants |
Back to article view | Back to pt.comp.programacao
mais sobre loops em common lisp Patricia Ferreira <pferreira@example.com> - 2024-03-10 19:28 -0300
Re: mais sobre loops em common lisp Patricia Ferreira <pferreira@example.com> - 2024-03-10 19:33 -0300
Re: mais sobre loops em common lisp Daniel Cerqueira <dan.list@lispclub.com> - 2024-03-11 19:42 +0000
Re: mais sobre loops em common lisp Patricia Ferreira <pferreira@example.com> - 2024-03-11 20:36 -0300
| From | Patricia Ferreira <pferreira@example.com> |
|---|---|
| Date | 2024-03-10 19:28 -0300 |
| Subject | mais sobre loops em common lisp |
| Message-ID | <87frwxoh5l.fsf@example.com> |
Eis uma alternativa a loop. Em vez de escrever, por exemplo,
(loop for e in ls
when (> e 3)
collect e)
podemos escrever
(iter (for e in ls)
(when (> e 3)
(collect e))).
Eis uma boa leitura.
https://iterate.common-lisp.dev/doc/Don_0027t-Loop-Iterate.html#Don_0027t-Loop-Iterate
Gostei. É idêntica a loop, mas com vantagens.
[toc] | [next] | [standalone]
| From | Patricia Ferreira <pferreira@example.com> |
|---|---|
| Date | 2024-03-10 19:33 -0300 |
| Message-ID | <878r2pogxf.fsf@example.com> |
| In reply to | #280 |
Patricia Ferreira <pferreira@example.com> writes:
> Eis uma alternativa a loop. Em vez de escrever, por exemplo,
>
> (loop for e in ls
> when (> e 3)
> collect e)
>
> podemos escrever
>
> (iter (for e in ls)
> (when (> e 3)
> (collect e))).
Vamos comparar as expansões. Praticamente idênticas.
ITER> (macroexpand '(loop for e in ls when (> e 3) collect e))
(BLOCK NIL
(LET ((E NIL)
(#:LOOP-LIST-339
(SB-KERNEL:THE* (LIST :USE-ANNOTATIONS T :SOURCE-FORM LS) LS)))
(DECLARE (IGNORABLE #:LOOP-LIST-339)
(IGNORABLE E))
(SB-LOOP::WITH-LOOP-LIST-COLLECTION-HEAD (#:LOOP-LIST-HEAD-340
#:LOOP-LIST-TAIL-341)
(TAGBODY
SB-LOOP::NEXT-LOOP
(WHEN (ENDP #:LOOP-LIST-339) (GO SB-LOOP::END-LOOP))
(SB-LOOP::LOOP-DESETQ E (CAR #:LOOP-LIST-339))
(SB-LOOP::LOOP-DESETQ #:LOOP-LIST-339 (CDR #:LOOP-LIST-339))
(IF (> E 3)
(SB-LOOP::LOOP-COLLECT-RPLACD
(#:LOOP-LIST-HEAD-340 #:LOOP-LIST-TAIL-341) (LIST E)))
(GO SB-LOOP::NEXT-LOOP)
SB-LOOP::END-LOOP
(RETURN-FROM NIL
(SB-LOOP::LOOP-COLLECT-ANSWER #:LOOP-LIST-HEAD-340))))))
T
ITER> (macroexpand '(iterate (for e in ls) (when (> e 3) (collect e))))
(LET* ((#:LIST5 NIL) (E NIL) (#:RESULT4 NIL) (#:END-POINTER6 NIL) (#:TEMP7 NIL))
(BLOCK NIL
(BLOCK #:ITERATE342
(TAGBODY
(PROGN (SETQ #:LIST5 LS))
LOOP-TOP-NIL
(PROGN
(IF (ENDP #:LIST5)
(GO LOOP-END-NIL))
(SETQ E (CAR #:LIST5))
(SETQ #:LIST5 (CDR #:LIST5))
(IF (> E 3)
(PROGN
(SETQ #:TEMP7 (LIST E))
(SETQ #:END-POINTER6
(IF #:RESULT4
(SETF (CDR #:END-POINTER6) #:TEMP7)
(SETQ #:RESULT4 #:TEMP7)))
#:RESULT4)))
(PROGN)
(GO LOOP-TOP-NIL)
LOOP-END-NIL
(PROGN))
#:RESULT4)))
T
[toc] | [prev] | [next] | [standalone]
| From | Daniel Cerqueira <dan.list@lispclub.com> |
|---|---|
| Date | 2024-03-11 19:42 +0000 |
| Message-ID | <87o7bk1ror.fsf@lispclub.com> |
| In reply to | #280 |
Patricia Ferreira <pferreira@example.com> writes: > Eis uma alternativa a loop. Em vez de escrever, por exemplo, > > (loop for e in ls > when (> e 3) > collect e) > > podemos escrever > > (iter (for e in ls) > (when (> e 3) > (collect e))). > > Eis uma boa leitura. > > https://iterate.common-lisp.dev/doc/Don_0027t-Loop-Iterate.html#Don_0027t-Loop-Iterate > > Gostei. É idêntica a loop, mas com vantagens. Estás a gostar do loop :-) . Eu não comento, porque ainda não cheguei à parte do livro que me ensina a usar o loop. Mas, a minha ideia inicial, é de não gostar muito em ter uma nova sintaxe para loop. Vamos ver.
[toc] | [prev] | [next] | [standalone]
| From | Patricia Ferreira <pferreira@example.com> |
|---|---|
| Date | 2024-03-11 20:36 -0300 |
| Message-ID | <87msr4ibo9.fsf@example.com> |
| In reply to | #282 |
Daniel Cerqueira <dan.list@lispclub.com> writes:
> Patricia Ferreira <pferreira@example.com> writes:
>
>> Eis uma alternativa a loop. Em vez de escrever, por exemplo,
>>
>> (loop for e in ls
>> when (> e 3)
>> collect e)
>>
>> podemos escrever
>>
>> (iter (for e in ls)
>> (when (> e 3)
>> (collect e))).
>>
>> Eis uma boa leitura.
>>
>> https://iterate.common-lisp.dev/doc/Don_0027t-Loop-Iterate.html#Don_0027t-Loop-Iterate
>>
>> Gostei. É idêntica a loop, mas com vantagens.
>
> Estás a gostar do loop :-) .
Verdade! Adorando! Achei que não ia gostar.
Mas acho que vou substituí-lo por /iter/.
> Eu não comento, porque ainda não cheguei à parte do livro que me ensina
> a usar o loop. Mas, a minha ideia inicial, é de não gostar muito em ter
> uma nova sintaxe para loop. Vamos ver.
Quase que não é nova, né? A nova sintaxe é essencialmente só os
parênteses. Ajuda os editores a indentar e acho que ajuda minha memória
a lembrar da sintaxe. (Tem vantagens técnicas; coisas a ver com o uso
de macros.)
Eis /todos/ os loops que escrevi até agora. Adoro o fato de que os
loops são expressões e que podemos mandar um /return/ sempre que
quisermos. O loop ``infinito'' é o mais natural que já vi. Vamos
começar por ele:
(defun write-accounts! ()
(let ((name
(loop
(let* ((tmp (random-string 10))
(name (format nil "~a.tmp" tmp)))
(when
(ignore-errors
(with-open-file
(s name
:direction :output
:if-exists :error
:if-does-not-exist :create)
(write *accounts* :stream s)))
(return name))))))
(if (ignore-errors (rename-file name "accounts.lisp"))
(values t *accounts*)
(values nil (format nil "could not rename ~a to accounts.lisp" name)))))
Tem uma /race condition/ aí em cima.
(defun get-account (username)
(loop for u in *accounts*
do (when (string= (str:upcase username) (account-username u))
(return u))))
(defun size-of-longest-username ()
(loop for u in *accounts*
maximizing (length (account-username u))))
(defun list-users ()
(read-accounts!)
(sort
(loop for u in *accounts*
collect (fmt "~v@a, last seen on ~a, invited ~a"
(size-of-longest-username)
(account-username u)
(last-time-seen (account-username u))
(or (account-friends u) "nobody")))
#'string<=))
(defun xover (r from to)
(assert (client-group *client*))
(let* ((g (client-group *client*))
(ls (get-articles g from to)))
(cond ((= 0 (length ls))
(make-response :code 420 :request r :data "no articles in the range"))
(t
(prepend-response-with
"Okay, your overview follows..."
(make-response
:code 224 :request r :multi-line 'yes
:data (str:join
(crlf-string)
(loop for i in ls
collect (xover-format-line
i
(remove-if-not
#'(lambda (h)
(member (car h) (xover-headers)
:test #'string=))
(fetch-headers g i)))))))))))
Senti falta de enumerate de Python.
(defun enumerate (list &optional (first-index 0))
(loop for e in list and i from first-index
collect (cons i e)))
(Tudo bem que não é um /stream/.)
[toc] | [prev] | [standalone]
Back to top | Article view | pt.comp.programacao
csiph-web