Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > pt.comp.programacao > #280 > unrolled thread

mais sobre loops em common lisp

Started byPatricia Ferreira <pferreira@example.com>
First post2024-03-10 19:28 -0300
Last post2024-03-11 20:36 -0300
Articles 4 — 2 participants

Back to article view | Back to pt.comp.programacao


Contents

  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

#280 — mais sobre loops em common lisp

FromPatricia Ferreira <pferreira@example.com>
Date2024-03-10 19:28 -0300
Subjectmais 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]


#281

FromPatricia Ferreira <pferreira@example.com>
Date2024-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]


#282

FromDaniel Cerqueira <dan.list@lispclub.com>
Date2024-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]


#283

FromPatricia Ferreira <pferreira@example.com>
Date2024-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