Path: csiph.com!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Patricia Ferreira Newsgroups: pt.comp.programacao Subject: Re: mais sobre loops em common lisp Date: Mon, 11 Mar 2024 20:36:06 -0300 Organization: A noiseless patient Spider Lines: 111 Message-ID: <87msr4ibo9.fsf@example.com> References: <87frwxoh5l.fsf@example.com> <87o7bk1ror.fsf@lispclub.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: dont-email.me; posting-host="9b6ae4c119a848c5523b3ec3ef64008c"; logging-data="4090324"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/ntQoAkCq13ZNuYaUSegdDvGVwXqyrl0M=" Cancel-Lock: sha1:IhbJJWmnl67EqO4pXVgfFrNz934= sha1:lgfe2kYQstu+njtBrdRdwrb2lLc= Xref: csiph.com pt.comp.programacao:283 Daniel Cerqueira writes: > Patricia Ferreira 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/.)