LINUX.ORG.RU

Lisp, loop


0

0
(loop for a in '(a b c d)
   and b in '("1" "2" "3" "4") 
   with cons = (concatenate 'string
			    (symbol-name a)
			    b)
   do (format t "~a ~a ~a~%" a b cons)
   collect cons)

Печатает на экран

A 1 NIL
B 2 NIL
C 3 NIL
D 4 NIL

Возвращает список из «NIL». А хотелось бы список («a1» «b2» «c3» «d4»)

(loop for a in '(a b c d)
and b in '("1" "2" "3" "4")
with cons
do (setf cons (concatenate 'string
(symbol-name a)
b))
collect cons)

Вот так вот оно работает как и требуется. Но может быть есть более лаконичный способ?

ryukzak
() автор топика

"with" инциализируется перед стартом цикла.
Замени with на for.
Вообще, кстати говоря, "and" в "loop" это то же самое, что for, но используя параллельное присваивание. Многие путают. Поэтому лучше везде, где именно параллельно присваивание не требуется, лучше использовать for.

(loop for a in '(a b c d) 
      for b in '(1 2 3 4) 
      for cons = (format nil "~a ~a ~0@*~a~a" a b)
      do (write-line cons) 
      collect cons)

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

А вообще надо пользоваться iterate-keywords 

http://sourceforge.net/projects/iteratekeywords/

потому что более лиспово, можно расширять, можно пользоваться лиспом 
внутри iterate, в т.ч., использовать макросы.

(defmacro let1 (var val &body body)
  (let ((,var ,val)) ,@body))

(iter (:for a in '(a b c d))
      (:for b in '(1 2 3 4))
      (let1 cons (format nil "~a ~a ~0@*~a~a" a b)
        (write-line cons)
        (:collect cons))

(представляю себе, сколько тухлых помидоров можно в меня кинуть
в связи с моими скобкофобскими высказываниями, сделанными в другой 
теме. Но loop - это действительно дерьмо. И iterate был дерьмом, 
пока я его не поправил). 

den73 ★★★★★
()

Печатай не на экран (hint: format nil)

mv ★★★★★
()
Ответ на: комментарий от den73

>Но loop - это действительно дерьмо. И iterate был дерьмом,
Я долго воздерживался от данного высказывания, но рано или поздно, эх.

Ты просто не понял сути лиспа.

guest-3484-2009
()
Ответ на: комментарий от den73

А, для лаконичности:
хм, 
(map 'list (lambda (x y) (format nil "~a~a" x y))
 '(a b c d) 
 '(1 2 3 4))

а в iterate есть (можно выцепить) синтаксис #L (я его 
постоянно использую). С ним получается так:

(map 'list #L(format nil "~a~a" !1 !2) 
  '(a b c d) 
  '(1 2 3 4))

Хотя я больше люблю iter

den73 ★★★★★
()
Ответ на: комментарий от mv

Чё diff, загрузи и сделай diff сам. Там патч получается на 50кб при размере сорсов в 100. Потому что я тесты тоже пропатчил.

den73 ★★★★★
()
Ответ на: комментарий от ryukzak

> А есть ли возможность определить для collect свой метод сборки?
Вот потому-то и надо пользоваться iterate.

den73 ★★★★★
()
Ответ на: комментарий от ryukzak

loop вроде бы не умеет.
Скачай библиотеку iterate.
В ней можно:
(iter
  (for x in '(1 2 3 4 5))
  (accumulate x by #'* :initial-value 1))

guest-3484-2009
()
Ответ на: комментарий от guest-3484-2009

> Ты просто не понял сути лиспа.
Это ты ничего не понял. Попробуй простую вещь:

(defpackage :foo (:use :cl :iterate :cl-utilities))

и станет ясно, в чём проблема. Или, кроме скобок, у тебя ещё нездоровое пристрастие к package qualifiers?

Из всех активных флудеров на c.l.l меня понял только один, который из тех, кто поумнее, Kaz Kulekhu. Он тоже признал, что iterate - это дерьмо. Остальные не поняли. Видимо, ты тоже из этой серии :P

den73 ★★★★★
()
Ответ на: комментарий от den73

Кстати, все вменяемые люди делают сокращение для concatenate 'string. Например, в исходниках ccl оно называется str-cat. У меня оно называется str+ и имеет следующий исходник:

(defun str+ (&rest args)
(apply 'concatenate 'string (mapcar 'string args)))

хотя если ты хочешь действительно понять суть лиспа, то нужно обязательно следовать стандарту и всегда писать concatenate 'string
(как мантру).

den73 ★★★★★
()
Ответ на: комментарий от den73

> хотя если ты хочешь действительно понять суть лиспа, то нужно обязательно следовать стандарту и всегда писать concatenate 'string
(как мантру).

Надеюсь истинная суть лиспа не в скоропечатание...

Лично мне казалось, что суть лиспа - создавать dsl для каждой задачи, или использовать уже написанное ранее. А в чём она по вашему? И как к этому поможет привети столь детальное выполнение стандарта?

ryukzak
() автор топика
Ответ на: комментарий от guest-3484-2009

> shadow отменили?

Заметь, в том же loop я могу использовать keywords или символы из любого пакета. То же и в cl-who - я использую :a, а не cl-who:a. В iterate я обязан использовать символы из пакета iterate, т.е. iterate:for, iterate:collect и ещё туеву хучу таких же популярных слов. Это значит, что, где бы я не попытался сделать use :iterate, гемор практически гарантирован. Если я не делаю use :iterate, то красота тоже теряется.

Да и сами авторы iterate поняли, что налажали и ввели синонимы (через них я и действовал).

Да, в этой части я тоже не понял сути лиспа. Потому что я считаю нелепым перечислять символы по одному (а ведь это был когда-то язык искусственного интеллекта :), когда можно решить вопрос сразу и навсегда. iterate экспортирует слишком много общеупотребительных слов.

А для того, чтобы заюзить iterate-keywords, достаточно проимпортировать один символ iter.

В общем, надоел ты мне, постигший мудрость :) Мне нечему тебя научить, ибо ты просветлён, а я тёмен. Я пошёл ужинать :)

den73 ★★★★★
()
Ответ на: комментарий от den73

>А вообще надо пользоваться iterate-keywords ...

>iterate был дерьмом, пока я его не поправил)


Так и запишем: den73 из дерьма лепит конфетки... =)))))))

yyk ★★★★★
()
Ответ на: комментарий от den73

>И iterate был дерьмом, пока я его не поправил).
Я бы не называл это так)

А что говорят разработчики iterate'а об этом? По-моему, очень полезная вещь. Главное оставить возможность создавать свои кляузы с символами из своих пакетов.

dmitry_vk ★★★
()
Ответ на: комментарий от mv

Ссылка выше.
На iterate-devel я постил, сначала мне посоветовали defsynonym, потом пытался постить патч. Но, поскольку патч очень большой, он не прошёл через какой-то там фильтр. Я завёл проект в sourceforge (надо мной смеялись, но я не знал тогда, как сделать лучше) и выложил ссылку на c.l.l.

Видимо, с продвижением у меня плохо, т.к. скачали его всего раз 6 или 7. Хотя я понимаю, почему :) В общем, мне более-менее пофигу.

Я вообще не уверен, что разработчики iterate существуют в природе на сегодняшний момент.

den73 ★★★★★
()
Ответ на: комментарий от dmitry_vk

> Главное оставить возможность создавать свои кляузы с символами из своих пакетов
Да, это можно. Фактически, я просто перебрал все символы, к-рые экспортирует iterate. Для большинства из них сделал синонимы в пакете keyword. С моей точки зрения, писать в property list символов из пакета keyword - это грех, но я взял его на свою душу - будут меня жарить в масле лишние 5-10 минут, а это ничто против вечных мук.

Для некоторых слов defsynonym не работает. Там уже пришлось патчить сам код iterate.

den73 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.