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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

For instance, to print the numbers from one to ten, you could write this:

(loop for i from 1 to 10 do (print i))

Another, more dramatic, form of immediate execution is a returnclause. This clause consists of the word returnfollowed by a single Lisp form, which is evaluated, with the resulting value immediately returned as the value of the loop.

You can also break out of a loop in a doclause using any of Lisp's normal control flow operators, such as RETURN and RETURN-FROM . Note that a returnclause always returns from the immediately enclosing LOOP expression, while a RETURN or RETURN-FROM in a doclause can return from any enclosing expression. For instance, compare the following:

(block outer

(loop for i from 0 return 100) ; 100 returned from LOOP

(print "This will print")

200) ==> 200

to this:

(block outer

(loop for i from 0 do (return-from outer 100)) ; 100 returned from BLOCK

(print "This won't print")

200) ==> 100

The doand returnclauses are collectively called the unconditional execution clauses.

Conditional Execution

Because a doclause can contain arbitrary Lisp forms, you can use any Lisp expressions you want, including control constructs such as IF and WHEN . So, the following is one way to write a loop that prints only the even numbers between one and ten:

(loop for i from 1 to 10 do (when (evenp i) (print i)))

However, sometimes you'll want conditional control at the level of loop clauses. For instance, suppose you wanted to sum only the even numbers between one and ten using a summingclause. You couldn't write such a loop with a doclause because there'd be no way to "call" the sum iin the middle of a regular Lisp form. In cases like this, you need to use one of LOOP 's own conditional expressions like this:

(loop for i from 1 to 10 when (evenp i) sum i) ==> 30

LOOP provides three conditional constructs, and they all follow this basic pattern:

conditional test-form loop-clause

The conditional can be if, when, or unless. The test-form is any regular Lisp form, and loop-clause can be a value accumulation clause ( count , collect , and so on), an unconditional execution clause, or another conditional execution clause. Multiple loop clauses can be attached to a single conditional by joining them with and.

As an extra bit of syntactic sugar, within the first loop clause, after the test form, you can use the variable itto refer to the value returned by the test form. For instance, the following loop collects the non- NIL values found in some-hashwhen looking up the keys in some-list:

(loop for key in some-list when (gethash key some-hash) collect it)

A conditional clause is executed each time through the loop. An ifor whenclause executes its loop-clause if test-form evaluates to true. An unlessreverses the test, executing loop-clause only when test-form is NIL . Unlike their Common Lisp namesakes, LOOP 's ifand whenare merely synonyms—there's no difference in their behavior.

All three conditional clauses can also take an elsebranch, which is followed by another loop clause or multiple clauses joined by and. When conditional clauses are nested, the set of clauses connected to an inner conditional clause can be closed with the word end. The endis optional when not needed to disambiguate a nested conditional—the end of a conditional clause will be inferred from the end of the loop or the start of another clause not joined by and.

The following rather silly loop demonstrates the various forms of LOOP conditionals. The update-analysisfunction will be called each time through the loop with the latest values of the various variables accumulated by the clauses within the conditionals.

(loop for i from 1 to 100

if (evenp i)

minimize i into min-even and

maximize i into max-even and

unless (zerop (mod i 4))

sum i into even-not-fours-total

end

and sum i into even-total

else

minimize i into min-odd and

maximize i into max-odd and

when (zerop (mod i 5))

sum i into fives-total

end

and sum i into odd-total

do (update-analysis min-even

max-even

min-odd

max-odd

even-total

odd-total

fives-total

even-not-fours-total))

Setting Up and Tearing Down

One of the key insights the designers of the LOOP language had about actual loops "in the wild" is that the loop proper is often preceded by a bit of code to set things up and then followed by some more code that does something with the values computed by the loop. A trivial example, in Perl, [241] I'm not picking on Perl here—this example would look pretty much the same in any language that bases its syntax on C's. might look like this:

my $evens_sum = 0;

my $odds_sum = 0;

foreach my $i (@list_of_numbers) {

if ($i % 2) {

$odds_sum += $i;

} else {

$evens_sum += $i;

}

}

if ($evens_sum > $odds_sum) {

print "Sum of evens greater\n";

} else {

print "Sum of odds greater\n";

}

The loop proper in this code is the foreachstatement. But the foreachloop doesn't stand on its own: the code in the loop body refers to variables declared in the two lines before the loop. [242] Perl would let you get away with not declaring those variables if your program didn't use strict . But you should always use strict in Perl. The equivalent code in Python, Java, or C would always require the variables to be declared. And the work the loop does is all for naught without the ifstatement after the loop that actually reports the results. In Common Lisp, of course, the LOOP construct is an expression that returns a value, so there's even more often a need to do something after the loop proper, namely, generate the return value.

So, said the LOOP designers, let's give a way to include the code that's really part of the loop in the loop itself. Thus, LOOP provides two keywords, initiallyand finally, that introduce code to be run outside the loop's main body.

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

Интервал:

Закладка:

Сделать

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

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


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

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