Peter Siebel - Practical Common Lisp

Здесь есть возможность читать онлайн «Peter Siebel - Practical Common Lisp» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2005, ISBN: 2005, Издательство: Apress, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Practical Common Lisp: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Practical Common Lisp»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Practical Common Lisp — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Practical Common Lisp», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Multiple withclauses can appear in a loop; each clause is evaluated independently in the order it appears and the value is assigned before proceeding to the next clause, allowing later variables to depend on the value of already declared variables. Mutually independent variables can be declared in one withclause with an andbetween each declaration.

Destructuring Variables

One handy feature of LOOP I haven't mentioned yet is the ability to destructure list values assigned to loop variables. This lets you take apart the value of lists that would otherwise be assigned to a loop variable, similar to the way DESTRUCTURING-BIND works but a bit less elaborate. Basically, you can replace any loop variable in a foror withclause with a tree of symbols, and the list value that would have been assigned to the simple variable will instead be destructured into variables named by the symbols in the tree. A simple example looks like this:

CL-USER> (loop for (a b) in '((1 2) (3 4) (5 6))

do (format t "a: ~a; b: ~a~%" a b))

a: 1; b: 2

a: 3; b: 4

a: 5; b: 6

NIL

The tree can also include dotted lists, in which case the name after the dot acts like a &rest parameter, being bound to a list containing any remaining elements of the list. This is particularly handy with for/ onloops since the value is always a list. For instance, this LOOP (which I used in Chapter 18 to emit a comma-delimited list):

(loop for cons on list

do (format t "~a" (car cons))

when (cdr cons) do (format t ", "))

could also be written like this:

(loop for (item . rest) on list

do (format t "~a" item)

when rest do (format t ", "))

If you want to ignore a value in the destructured list, you can use NIL in place of a variable name.

(loop for (a nil) in '((1 2) (3 4) (5 6)) collect a) ==> (1 3 5)

If the destructuring list contains more variables than there are values in the list, the extra variables are set to NIL , making all the variables essentially like &optional parameters. There isn't, however, any equivalent to &key parameters.

Value Accumulation

The value accumulation clauses are perhaps the most powerful part of LOOP . While the iteration control clauses provide a concise syntax for expressing the basic mechanics of looping, they aren't dramatically different from the equivalent mechanisms provided by DO , DOLIST , and DOTIMES .

The value accumulation clauses, on the other hand, provide a concise notation for a handful of common loop idioms having to do with accumulating values while looping. Each accumulation clause starts with a verb and follows this pattern:

verb form [ into var ]

Each time through the loop, an accumulation clause evaluates form and saves the value in a manner determined by the verb . With an intosubclause, the value is saved into the variable named by var . The variable is local to the loop, as if it'd been declared in a withclause. With no intosubclause, the accumulation clause instead accumulates a default value for the whole loop expression.

The possible verbs are collect, append, nconc, count, sum, maximize, and minimize. Also available as synonyms are the present participle forms: collecting, appending, nconcing, counting, summing, maximizing, and minimizing.

A collectclause builds up a list containing all the values of form in the order they're seen. This is a particularly useful construct because the code you'd have to write to collect a list in order as efficiently as LOOP does is more painful than you'd normally write by hand. [238] The trick is to keep ahold of the tail of the list and add new cons cells by SETF ing the CDR of the tail. A handwritten equivalent of the code generated by (loop for i upto 10 collect i) would look like this: (do ((list nil) (tail nil) (i 0 (1+ i))) ((> i 10) list) (let ((new (cons i nil))) (if (null list) (setf list new) (setf (cdr tail) new)) (setf tail new))) Of course you'll rarely, if ever, write code like that. You'll use either LOOP or (if, for some reason, you don't want to use LOOP ) the standard PUSH / NREVERSE idiom for collecting values. Related to collectare the verbs appendand nconc. These verbs also accumulate values into a list, but they join the values, which must be lists, into a single list as if by the functions APPEND or NCONC . [239] Recall that NCONC is the destructive version of APPEND —it's safe to use an nconc clause only if the values you're collecting are fresh lists that don't share any structure with other lists. For instance, this is safe: (loop for i upto 3 nconc (list i i)) ==> (0 0 1 1 2 2 3 3) But this will get you into trouble: (loop for i on (list 1 2 3) nconc i) ==> undefined The later will most likely get into an infinite loop as the various parts of the list produced by (list 1 2 3) are destructively modified to point to each other. But even that's not guaranteed—the behavior is simply undefined.

The remaining accumulation clauses are used to accumulate numeric values. The verb countcounts the number of times form is true, sumcollects a running total of the values of form , maximizecollects the largest value seen for form , and minimizecollects the smallest. For instance, suppose you define a variable *random*that contains a list of random numbers.

(defparameter *random* (loop repeat 100 collect (random 10000)))

Then the following loop will return a list containing various summary information about the numbers:

(loop for i in *random*

counting (evenp i) into evens

counting (oddp i) into odds

summing i into total

maximizing i into max

minimizing i into min

finally (return (list min max total evens odds)))

Unconditional Execution

As useful as the value accumulation constructs are, LOOP wouldn't be a very good general-purpose iteration facility if there wasn't a way to execute arbitrary Lisp code in the loop body.

The simplest way to execute arbitrary code within a loop body is with a doclause. Compared to the clauses I've described so far, with their prepositions and subclauses, dois a model of Yodaesque simplicity. [240] "No! Try not. Do . . . or do not. There is no try." — Yoda, The Empire Strikes Back A doclause consists of the word do(or doing) followed by one or more Lisp forms that are all evaluated when the doclause is. The doclause ends at the closing parenthesis of the loop or the next loop keyword.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Practical Common Lisp»

Представляем Вашему вниманию похожие книги на «Practical Common Lisp» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Practical Common Lisp»

Обсуждение, отзывы о книге «Practical Common Lisp» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.