Node:Процедуры в качестве значений, Next:, Up:О процедурах

[Показать/скрыть оригинал] [Показать/скрыть перевод] [Переключить перевод и оригинал]


14.2.1 Procedures as Values

14.2.1 Процедуры в качестве значений

One of the great simplifications of Scheme is that a procedure is just another type of value, and that procedure values can be passed around and stored in variables in exactly the same way as, for example, strings and lists. When we talk about a built-in standard Scheme procedure such as open-input-file, what we actually mean is that there is a pre-defined top level variable called open-input-file, whose value is a procedure that implements what R5RS says that open-input-file should do.

Одно из существеннейших упрощений Scheme заключается в идее, что процедуры - лишь другой тип значений и что "процедурные" значения могут передаваться и храниться в переменный так же, как, например, строки или списки. Например, когда мы говорим о встроенных в Scheme стандартных процедурах (таких, как open-input-file), мы на самом деле имеем в виду, что существует такая переменная верхнего уровня, называющаяся open-input-file, которая содержит в себе значение - процедуру, реализующую предписания стандарта R5RS для open-input-file.

Note that this is quite different from many dialects of Lisp -- including Emacs Lisp -- in which a program can use the same name with two quite separate meanings: one meaning identifies a Lisp function, while the other meaning identifies a Lisp variable, whose value need have nothing to do with the function that is associated with the first meaning. In these dialects, functions and variables are said to live in different namespaces.

Обратите внимание, что существует существенное отличие от многих диалектов Lisp'а (включая Emacs Lisp). Во этих диалектах используется два различных пространства имён, пространство имён функций и пространство имён переменных. Другими словами, функция никак не связана с переменной, у которой может быть совпадающее с функцией имя.

In Scheme, on the other hand, all names belong to a single unified namespace, and the variables that these names identify can hold any kind of Scheme value, including procedure values.

В отличие от этих диалектов в Scheme все имена относятся к общему пространству имён (namespace) и переменные с именами из этого пространства могут содержать любое значение, поддерживаемое Scheme, включая процедуры (которые в Scheme так же являются значениями).

One consequence of the "procedures as values" idea is that, if you don't happen to like the standard name for a Scheme procedure, you can change it.

Одно из следствий идеи "процедуры - это значения" возможность переименовать имя стандартной процедуры на ваше собственное.

For example, call-with-current-continuation is a very important standard Scheme procedure, but it also has a very long name! So, many programmers use the following definition to assign the same procedure value to the more convenient name call/cc.

Например, call-with-current-continuation очень важная стандартная процедура в Scheme. Но его имя уж очень длинное. Так что многие программисты используют следующее определение да задачи той же самой процедуре куда более компактного имени call/cc

(define call/cc call-with-current-continuation)

Let's understand exactly how this works. The definition creates a new variable call/cc, and then sets its value to the value of the variable call-with-current-continuation; the latter value is a procedure that implements the behaviour that R5RS specifies under the name "call-with-current-continuation". So call/cc ends up holding this value as well.

Разберёмся внимательнее как работает это выражение. Определение define создаёт новую перменную call/cc и устанавливает её значение в значение call-with-current-continuation, значение которой содержит процедуру, поведение которой описано в спецификации R5RS под именем "call-with-current-continuation". В итоге Call/cc содержит то же самое значение.

Now that call/cc holds the required procedure value, you could choose to use call-with-current-continuation for a completely different purpose, or just change its value so that you will get an error if you accidentally use call-with-current-continuation as a procedure in your program rather than call/cc. For example:

После присвоения call/cc содержит соответствующее "процедурное" значение (т.е. саму процедуру), так что вы можете использовать имя call-with-current-continuation для совершенно иных целей, например, выдавать ошибку при вызове, если вы случайно (забыв о новом имени) вызовете call-with-current-continuation вместо call/cc:

(set! call-with-current-continuation "Not a procedure any more!")

Or you could just leave call-with-current-continuation as it was. It's perfectly fine for more than one variable to hold the same procedure value.

Ну, или, как вариант, вы можете просто оставить call-with-current-continuation без изменений. Это вполне нормально, когда несколько переменных содержат одну и ту же процедуру.


> > далее > >