Peter Siebel - Practical Common Lisp
Здесь есть возможность читать онлайн «Peter Siebel - Practical Common Lisp» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2005, ISBN: 2005, Издательство: Apress, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.
- Название:Practical Common Lisp
- Автор:
- Издательство:Apress
- Жанр:
- Год:2005
- ISBN:1-59059-239-5
- Рейтинг книги:4 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 80
- 1
- 2
- 3
- 4
- 5
Practical Common Lisp: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Practical Common Lisp»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
Practical Common Lisp — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Practical Common Lisp», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
Finally, one last macro-defining special operator is SYMBOL-MACROLET , which defines a special kind of macro called, appropriately enough, a symbol macro . Symbol macros are like regular macros except they can't take arguments and are referred to with a plain symbol rather than a list form. In other words, after you've defined a symbol macro with a particular name, any use of that symbol in a value position will be expanded and the resulting form evaluated in its place. This is how macros such as WITH-SLOTS and WITH-ACCESSORS are able to define "variables" that access the state of a particular object under the covers. For instance, the following WITH-SLOTS form:
(with-slots (x y z) foo (list x y z)))
might expand into this code that uses SYMBOL-MACROLET :
(let ((#:g149 foo))
(symbol-macrolet
((x (slot-value #:g149 'x))
(y (slot-value #:g149 'y))
(z (slot-value #:g149 'z)))
(list x y z)))
When the expression (list x y z)is evaluated, the symbols x, y, and zwill be replaced with their expansions, such as (slot-value #:g149 'x). [209] It's not required that WITH-SLOTS be implemented with SYMBOL-MACROLET —in some implementations, WITH-SLOTS may walk the code provided and generate an expansion with x , y , and z already replaced with the appropriate SLOT-VALUE forms. You can see how your implementation does it by evaluating this form: (macroexpand-1 '(with-slots (x y z) obj (list x y z))) However, walking the body is much easier for the Lisp implementation to do than for user code; to replace x , y , and z only when they appear in value positions requires a code walker that understands the syntax of all special operators and that recursively expands all macro forms in order to determine whether their expansions include the symbols in value positions. The Lisp implementation obviously has such a code walker at its disposal, but it's one of the few parts of Lisp that's not exposed to users of the language.
Symbol macros are most often local, defined with SYMBOL-MACROLET , but Common Lisp also provides a macro DEFINE-SYMBOL-MACRO that defines a global symbol macro. A symbol macro defined with SYMBOL-MACROLET shadows other symbol macros of the same name defined with DEFINE-SYMBOL-MACRO or enclosing SYMBOL-MACROLET forms.
Local Flow of Control
The next four special operators I'll discuss also create and use names in the lexical environment but for the purposes of altering the flow of control rather than defining new functions and macros. I've mentioned all four of these special operators in passing because they provide the underlying mechanisms used by other language features. They're BLOCK , RETURN-FROM , TAGBODY , and GO . The first two, BLOCK and RETURN-FROM , are used together to write code that returns immediately from a section of code—I discussed RETURN-FROM in Chapter 5 as a way to return immediately from a function, but it's more general than that. The other two, TAGBODY and GO , provide a quite low-level goto construct that's the basis for all the higher-level looping constructs you've already seen.
The basic skeleton of a BLOCK form is this:
(block name
form *)
The name is a symbol, and the forms are Lisp forms. The forms are evaluated in order, and the value of the last form is returned as the value of the BLOCK unless a RETURN-FROM is used to return from the block early. A RETURN-FROM form, as you saw in Chapter 5, consists of the name of the block to return from and, optionally, a form that provides a value to return. When a RETURN-FROM is evaluated, it causes the named BLOCK to return immediately. If RETURN-FROM is called with a return value form, the BLOCK will return the resulting value; otherwise, the BLOCK evaluates to NIL .
A BLOCK name can be any symbol, which includes NIL . Many of the standard control construct macros, such as DO , DOTIMES , and DOLIST , generate an expansion consisting of a BLOCK named NIL . This allows you to use the RETURN macro, which is a bit of syntactic sugar for (return-from nil ...), to break out of such loops. Thus, the following loop will print at most ten random numbers, stopping as soon as it gets a number greater than 50:
(dotimes (i 10)
(let ((answer (random 100)))
(print answer)
(if (> answer 50) (return))))
Function-defining macros such as DEFUN , FLET , and LABELS , on the other hand, wrap their bodies in a BLOCK with the same name as the function. That's why you can use RETURN-FROM to return from a function.
TAGBODY and GO have a similar relationship to each other as BLOCK and RETURN-FROM : a TAGBODY form defines a context in which names are defined that can be used by GO . The skeleton of a TAGBODY is as follows:
(tagbody
tag-or-compound-form *)
where each tag-or-compound-form is either a symbol, called a tag , or a nonempty list form. The list forms are evaluated in order and the tags ignored, except as I'll discuss in a moment. After the last form of the TAGBODY is evaluated, the TAGBODY returns NIL . Anywhere within the lexical scope of the TAGBODY you can use the GO special operator to jump immediately to any of the tags, and evaluation will resume with the form following the tag. For instance, you can write a trivial infinite loop with TAGBODY and GO like this:
(tagbody
top
(print 'hello)
(go top))
Note that while the tag names must appear at the top level of the TAGBODY , not nested within other forms, the GO special operator can appear anywhere within the scope of the TAGBODY . This means you could write a loop that loops a random number of times like this:
(tagbody
top
Интервал:
Закладка:
Похожие книги на «Practical Common Lisp»
Представляем Вашему вниманию похожие книги на «Practical Common Lisp» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Practical Common Lisp» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.