Groups | Search | Server Info | Login | Register


Groups > pt.comp.programacao > #283

Re: mais sobre loops em common lisp

From Patricia Ferreira <pferreira@example.com>
Newsgroups pt.comp.programacao
Subject Re: mais sobre loops em common lisp
Date 2024-03-11 20:36 -0300
Organization A noiseless patient Spider
Message-ID <87msr4ibo9.fsf@example.com> (permalink)
References <87frwxoh5l.fsf@example.com> <87o7bk1ror.fsf@lispclub.com>

Show all headers | View raw


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/.)

Back to pt.comp.programacao | Previous | NextPrevious in thread | Find similar


Thread

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

csiph-web