Scheme/Tutorial/6: различия между версиями
Нет описания правки |
м (вычитка) |
||
(не показаны 2 промежуточные версии 2 участников) | |||
Строка 1: | Строка 1: | ||
=== 12 локальные переменные (продолжение) === | === 12 локальные переменные (продолжение) === | ||
Продолжаем неустанно совершенствоваться в Scheme. Вы уже видели в предыдущий раз, что локальные переменные можно объявлять в теле функции, пользуясь тем же самым define | Продолжаем неустанно совершенствоваться в Scheme. Вы уже видели в предыдущий раз, что локальные переменные можно объявлять в теле функции, пользуясь тем же самым <tt>define</tt>: | ||
<pre>(define (func) | <pre>(define (func) | ||
(define a 5) | (define a 5) | ||
(+ a 3))</pre> | (+ a 3))</pre> | ||
Однако есть ещё несколько интересных и полезных приёмов работы. Воспользуемся тем, что параметры | Однако есть ещё несколько интересных и полезных приёмов работы. Воспользуемся тем, что параметры функции — по сути те же локальные переменные. | ||
Тогда пример выше | Тогда пример выше можно было бы сделать следующим образом: | ||
<pre>(define (func) | <pre>(define (func) | ||
((lambda (a) | ((lambda (a) | ||
(+ a 3)) | (+ a 3)) | ||
5))</pre> | 5))</pre> | ||
Попробуем понять что же произошло. Мы создали функцию с параметром, который назвали | Попробуем понять, что же произошло. Мы создали функцию с параметром, который назвали <tt>a</tt>, поместили в неё всё, что нам необходимо — и после этого запустили её, придав параметру требуемое значение <tt>5</tt>. Всё, как говорится, гениальное просто. | ||
Попробуем ещё, вместо: | Попробуем ещё, вместо: | ||
<pre>(define x 5) | <pre>(define x 5) | ||
Строка 24: | Строка 22: | ||
5 | 5 | ||
6)</pre> | 6)</pre> | ||
Данный приём настолько популярен, что имеет общепринятое | Данный приём настолько популярен, что имеет общепринятое сокращение — <tt>let</tt>. | ||
Приведённые выражения в сокращённом виде записываются так: | Приведённые выражения в сокращённом виде записываются так: | ||
<pre>(define (func) | <pre>(define (func) | ||
Строка 39: | Строка 37: | ||
(write a) ; будет напечатано 3</pre> | (write a) ; будет напечатано 3</pre> | ||
У этого приёма есть один существенный недостаток | У этого приёма есть один существенный недостаток: поскольку формальные параметры инициализируются независимо друг от друга и в неопределённом порядке, мы не можем использовать одни из них для инициализации других; например, в примере с двумя параметрами нельзя <tt>у</tt> задать равным <tt>x</tt>. | ||
Но против лома всегда есть другой лом. | Но против лома всегда есть другой лом. | ||
Применим одну маленькую | |||
Применим одну маленькую хитрость — будем связывать переменные по очереди: | |||
<pre>(let ((x 3)) | <pre>(let ((x 3)) | ||
(let ((y x)) | (let ((y x)) | ||
.....</pre> | .....</pre> | ||
Тогда всё получится, на момент определения | Тогда всё получится, на момент определения <tt>y</tt>, <tt>x</tt> уже известен и проинициализирован. | ||
Этот приём тоже очень распространён, а потому тоже имеет общепринятое | Этот приём тоже очень распространён, а потому тоже имеет общепринятое сокращение — <tt>let*</tt>. | ||
<pre>(let* ((x 3) (y x)) | <pre>(let* ((x 3) (y x)) | ||
.....</pre> | .....</pre> | ||
'''[http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html далее>>]''' | |||
{{Category navigation|title=Scheme|category=Scheme|sortkey=Tutorial}} |
Текущая версия от 13:14, 11 мая 2012
12 локальные переменные (продолжение)
Продолжаем неустанно совершенствоваться в Scheme. Вы уже видели в предыдущий раз, что локальные переменные можно объявлять в теле функции, пользуясь тем же самым define:
(define (func) (define a 5) (+ a 3))
Однако есть ещё несколько интересных и полезных приёмов работы. Воспользуемся тем, что параметры функции — по сути те же локальные переменные. Тогда пример выше можно было бы сделать следующим образом:
(define (func) ((lambda (a) (+ a 3)) 5))
Попробуем понять, что же произошло. Мы создали функцию с параметром, который назвали a, поместили в неё всё, что нам необходимо — и после этого запустили её, придав параметру требуемое значение 5. Всё, как говорится, гениальное просто. Попробуем ещё, вместо:
(define x 5) (define y 6) (write x) (+ x (* x y))
мы можем написать:
((lambda (x y) (write x) (+ x (* x y))) 5 6)
Данный приём настолько популярен, что имеет общепринятое сокращение — let. Приведённые выражения в сокращённом виде записываются так:
(define (func) (let ((a 5)) (+ a 3)))
(let ((x 5) (y 6)) (write x) (+ x (* x y)))
Если немного поразмышлять, то мы получили не просто способ объявления локальных переменных, а возможность делать блоки с локальными переменными в произвольном месте кода, например:
(define a 3) (write a) ; будет напечатано 3 (let ((a 5)) (write a)) ; будет напечатано 5 (write a) ; будет напечатано 3
У этого приёма есть один существенный недостаток: поскольку формальные параметры инициализируются независимо друг от друга и в неопределённом порядке, мы не можем использовать одни из них для инициализации других; например, в примере с двумя параметрами нельзя у задать равным x.
Но против лома всегда есть другой лом.
Применим одну маленькую хитрость — будем связывать переменные по очереди:
(let ((x 3)) (let ((y x)) .....
Тогда всё получится, на момент определения y, x уже известен и проинициализирован. Этот приём тоже очень распространён, а потому тоже имеет общепринятое сокращение — let*.
(let* ((x 3) (y x)) .....