Что действительно 'параметризует', делают в DrScheme?

IMO это - идеальный пример того, какой переключатель проваливается, был сделан для.

6
задан Eli Barzilay 8 June 2010 в 20:52
поделиться

3 ответа

parameterize используется для получения значений с «динамической областью действия». Вы получаете параметр с make-parameter . Сам параметр ведет себя как функция: вызовите его без входов, и вы получите его значение, вызовите его с одним значением, и он установит значение. Например:

> (define p (make-parameter "blah"))
> (p)
"blah"
> (p "meh")
> (p)
"meh"

Многие функции (включая многие примитивные) используют параметры как способ настройки своего поведения. Например, printf будет печатать данные, используя порт, который является значением параметра current-output-port . Теперь предположим, что у вас есть функция, которая что-то печатает:

> (define (foo x) (printf "the value of x is ~s\n"))

Обычно вы вызываете эту функцию и видите что-то напечатанное на экране, но в некоторых случаях вы хотите использовать ее для печати чего-либо в файл или чего-то еще. Вы можете сделать это:

(define (bar)
  (let ([old-stdout (current-output-port)])
    (current-output-port my-own-port)
    (foo some-value)
    (current-output-port old-stdout)))

Одна из проблем в том, что это утомительно, но это легко решается с помощью макроса. (Фактически, в PLT все еще есть конструкция, которая делает это на некоторых языках: fluid-let .) Но здесь есть другие проблемы: что произойдет, если вызов foo приведет к ошибка выполнения? Это может оставить систему в плохом состоянии, когда весь вывод идет на ваш порт (и вы даже не увидите проблемы, поскольку он ничего не печатает). Решение для этого (которое также использует fluid-let ) - защитить сохранение / восстановление параметра с помощью dynamic-wind , который гарантирует, что в случае ошибки (и т. , если вы знаете о продолжениях), то значение все равно восстанавливается.

Итак, вопрос в том, какой смысл иметь параметры вместо использования глобальных переменных и fluid-let ? Есть еще две проблемы, которые нельзя решить только с помощью глобальных переменных. Один из них - то, что происходит, когда у вас есть несколько потоков - в этом случае установка значения временно повлияет на другие потоки, которые все еще могут захотеть распечатать на стандартный вывод. Параметры решают эту проблему, задавая конкретное значение для каждого потока. Что происходит, так это то, что каждый поток «наследует» значение от потока, который его создал, и изменения в одном потоке видны только в этом потоке.

Другая проблема более тонкая. Предположим, у вас есть параметр с числовым значением, и вы хотите сделать следующее:

(define (foo)
  (parameterize ([p ...whatever...])
    (foo)))

В схеме "хвостовые вызовы" важны - они являются основным инструментом для создания петель и многого другого. parameterize творит чудеса, позволяя ему временно изменять значение параметра, но при этом сохранять эти хвостовые вызовы. Например, в приведенном выше случае вы получите бесконечный цикл, а не ошибку переполнения стека - что происходит, так это то, что каждое из этих выражений параметризация может каким-то образом определять наличие более ранняя параметризация , которая больше не нуждается в очистке.

Наконец, параметризация фактически использует две важные части PLT для выполнения своей работы: он использует ячейки потока для реализации каждого значения потока, и он использует метки продолжения, чтобы иметь возможность сохранять хвостовые вызовы. Каждая из этих функций полезна сама по себе.

parameterize творит чудеса, позволяя ему временно изменять значение параметра, но при этом сохранять эти хвостовые вызовы. Например, в приведенном выше случае вы получите бесконечный цикл, а не ошибку переполнения стека - что происходит, так это то, что каждое из этих выражений параметризация может каким-то образом определять наличие более ранняя параметризация , которая больше не нуждается в очистке.

Наконец, параметризация фактически использует две важные части PLT для выполнения своей работы: он использует ячейки потока для реализации каждого значения потока, и он использует метки продолжения, чтобы иметь возможность сохранять хвостовые вызовы. Каждая из этих функций полезна сама по себе.

parameterize творит чудеса, позволяя ему временно изменять значение параметра, но при этом сохранять эти хвостовые вызовы. Например, в приведенном выше случае вы получите бесконечный цикл, а не ошибку переполнения стека - что происходит, так это то, что каждое из этих выражений параметризация может каким-то образом определять наличие более ранняя параметризация , которая больше не нуждается в очистке.

Наконец, параметризация фактически использует две важные части PLT для выполнения своей работы: он использует ячейки потока для реализации каждого значения потока, и он использует метки продолжения, чтобы иметь возможность сохранять хвостовые вызовы. Каждая из этих функций полезна сама по себе.

вместо того, чтобы получить ошибку переполнения стека - происходит то, что каждое из этих параметризованных выражений может каким-то образом определять наличие более ранней параметризованной , которая больше не нуждается в очистке.

Наконец, parameterize фактически использует две важные части PLT для выполнения своей работы: он использует ячейки потока для реализации значений каждого потока и использует метки продолжения, чтобы иметь возможность сохранять хвостовые вызовы. Каждая из этих функций полезна сама по себе.

вместо того, чтобы получить ошибку переполнения стека - происходит то, что каждое из этих параметризованных выражений может каким-то образом определять наличие более ранней параметризованной , которая больше не нуждается в очистке.

Наконец, parameterize фактически использует две важные части PLT для выполнения своей работы: он использует ячейки потока для реализации значений каждого потока и использует метки продолжения, чтобы иметь возможность сохранять хвостовые вызовы. Каждая из этих функций полезна сама по себе.

и он использует знаки продолжения, чтобы иметь возможность сохранять хвосты. Каждая из этих функций полезна сама по себе.

и он использует знаки продолжения, чтобы иметь возможность сохранять хвосты. Каждая из этих функций полезна сама по себе.

13
ответ дан 8 December 2019 в 12:20
поделиться

параметризация устанавливает определенные параметры для определенных значений на время блока, не влияя на их значения вне его.

3
ответ дан 8 December 2019 в 12:20
поделиться

Parameterize is a means by which you can dynamically re-bind values within an existing function, without using lambda to do so. In practice sometimes it is a lot easier to use parameterize to re-bind values within a function rather than being required to pass arguments and bind them using lambda.

For example, say that a library that you use emits HTML to stdout but for sake of convenience you want to capture that value to a string and perform further operations on it. The library designer has at least two choices to make that easy for you: 1) accept an output port as a argument to the function or 2) parameterize the current-output-port value. 1 is ugly and a hassle. 2 is nicer since the most likely behavior is to print to stdout, but in case you want to print to a string-port you can just parameterize the call to that function.

3
ответ дан 8 December 2019 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: