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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
In older Lisp dialects that didn't have anything like Common Lisp's condition system, CATCH
and THROW
were used for error handling. However, to keep them manageable, the catch tags were usually just quoted symbols, so you could tell by looking at a CATCH
and a THROW
whether they would hook up at runtime. In Common Lisp you'll rarely have any call to use CATCH
and THROW
since the condition system is so much more flexible.
The last special operator related to controlling the stack is another one I've mentioned in passing before— UNWIND-PROTECT
. UNWIND-PROTECT
lets you control what happens as the stack unwinds—to make sure that certain code always runs regardless of how control leaves the scope of the UNWIND-PROTECT
, whether by a normal return, by a restart being invoked, or by any of the ways discussed in this section. [214] UNWIND-PROTECT is essentially equivalent to try/finally constructs in Java and Python.
The basic skeleton of UNWIND-PROTECT
looks like this:
(unwind-protect protected-form
cleanup-form *)
The single protected-form is evaluated, and then, regardless of how it returns, the cleanup-forms are evaluated. If the protected-form returns normally, then whatever it returns is returned from the UNWIND-PROTECT
after the cleanup forms run. The cleanup forms are evaluated in the same dynamic environment as the UNWIND-PROTECT
, so the same dynamic variable bindings, restarts, and condition handlers will be visible to code in cleanup forms as were visible just before the UNWIND-PROTECT
.
You'll occasionally use UNWIND-PROTECT
directly. More often you'll use it as the basis for WITH-
style macros, similar to WITH-OPEN-FILE
, that evaluate any number of body forms in a context where they have access to some resource that needs to be cleaned up after they're done, regardless of whether they return normally or bail via a restart or other nonlocal exit. For example, if you were writing a database library that defined functions open-connection
and close-connection
, you might write a macro like this: [215] And indeed, CLSQL, the multi-Lisp, multidatabase SQL interface library, provides a similar macro called with-database . CLSQL's home page is at http://clsql.b9.com .
(defmacro with-database-connection ((var &rest open-args) &body body)
`(let ((,var (open-connection ,@open-args)))
(unwind-protect (progn ,@body)
(close-connection ,var))))
which lets you write code like this:
(with-database-connection (conn :host "foo" :user "scott" :password "tiger")
(do-stuff conn)
(do-more-stuff conn))
and not have to worry about closing the database connection, since the UNWIND-PROTECT
will make sure it gets closed no matter what happens in the body of the with-database-connection
form.
Multiple Values
Another feature of Common Lisp that I've mentioned in passing—in Chapter 11, when I discussed GETHASH
—is the ability for a single form to return multiple values. I'll discuss it in greater detail now. It is, however, slightly misplaced in a chapter on special operators since the ability to return multiple values isn't provided by just one or two special operators but is deeply integrated into the language. The operators you'll most often use when dealing with multiple values are macros and functions, not special operators. But it is the case that the basic ability to get at multiple return values is provided by a special operator, MULTIPLE-VALUE-CALL
, upon which the more commonly used MULTIPLE-VALUE-BIND
macro is built.
The key thing to understand about multiple values is that returning multiple values is quite different from returning a list—if a form returns multiple values, unless you do something specific to capture the multiple values, all but the primary value will be silently discarded. To see the distinction, consider the function GETHASH
, which returns two values: the value found in the hash table and a boolean that's NIL
when no value was found. If it returned those two values in a list, every time you called GETHASH
you'd have to take apart the list to get at the actual value, regardless of whether you cared about the second return value. Suppose you have a hash table, *h*
, that contains numeric values. If GETHASH
returned a list, you couldn't write something like this:
(+ (gethash 'a *h*) (gethash 'b *h*))
because +
expects its arguments to be numbers, not lists. But because the multiple value mechanism silently discards the secondary return value when it's not wanted, this form works fine.
There are two aspects to using multiple values—returning multiple values and getting at the nonprimary values returned by forms that return multiple values. The starting points for returning multiple values are the functions VALUES
and VALUES-LIST
. These are regular functions, not special operators, so their arguments are passed in the normal way. VALUES
takes a variable number of arguments and returns them as multiple values; VALUES-LIST
takes a single list and returns its elements as multiple values. In other words:
(values-list x) === (apply #'values x)
The mechanism by which multiple values are returned is implementation dependent just like the mechanism for passing arguments into functions is. Almost all language constructs that return the value of some subform will "pass through" multiple values, returning all the values returned by the subform. Thus, a function that returns the result of calling VALUES
or VALUES-LIST
will itself return multiple values—and so will another function whose result comes from calling the first function. And so on. [216] A small handful of macros don't pass through extra return values of the forms they evaluate. In particular, the PROG1 macro, which evaluates a number of forms like a PROGN before returning the value of the first form, returns that form's primary value only. Likewise, PROG2 , which returns the value of the second of its subforms, returns only the primary value. The special operator MULTIPLE-VALUE-PROG1 is a variant of PROG1 that returns all the values returned by the first form. It's a minor wart that PROG1 doesn't already behave like MULTIPLE-VALUE-PROG1 , but neither is used often enough that it matters much. The OR and COND macros are also not always transparent to multiple values, returning only the primary value of certain subforms.
But when a form is evaluated in a value position, only the primary value will be used, which is why the previous addition form works the way you'd expect. The special operator MULTIPLE-VALUE-CALL
provides the mechanism for getting your hands on the multiple values returned by a form. MULTIPLE-VALUE-CALL
is similar to FUNCALL
except that while FUNCALL
is a regular function and, therefore, can see and pass on only the primary values passed to it, MULTIPLE-VALUE-CALL
passes, to the function returned by its first subform, all the values returned by the remaining subforms.
Интервал:
Закладка:
Похожие книги на «Practical Common Lisp»
Представляем Вашему вниманию похожие книги на «Practical Common Lisp» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Practical Common Lisp» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.