Вопрос

Я читал где -то, где сказал Рич Хикки:

«Я думаю, что продолжения могут быть аккуратными в теории, но не на практике»

Я не знаком с Clojure.
1. Есть ли у Clojure продолжение?
2. Если нет, разве вам не нужны продолжения? Я видел много хороших примеров, особенно из этот парень. Анкет Какая альтернатива?
3. Если да, есть ли документация?

Это было полезно?

Решение

Когда вы будете говорить о продолжениях, вам придется различать два разных вида из них:

  • Первоклассные продолжения-поддержка продолжения, которая глубоко интегрирована в язык (схема или рубин). Clojure не поддерживает первоклассные продолжения.

  • Продолжение в стиле (CPS).

Примеры:

-- Standard function
double :: Int -> Int
double x = 2 * x

-- CPS-function – We pass the continuation explicitly
doubleCPS :: Int -> (Int -> res) -> res
doubleCPS x cont = cont (2 * x)
; Call
print (double 2)

; Call CPS: Continue execution with specified anonymous function
double 2 (\res -> print res)

Читать продолжение на Википедии.

Я не думаю, что продолжения необходимы для хорошего языка, но особенно первоклассные продолжения и CPS на функциональных языках, таких как Haskell, могут быть весьма полезными (Интеллектуальный пример возврата).

Другие советы

Я написал порт Clojure в CL-конне, который добавляет продолжения Common LISP.

https://github.com/swannodette/delimc

Является ли продолжение необходимой функцией на языке?

Нет. Множество языков не имеют продолжения.

Если нет, вам не нужны продолжения? Я видел много хороших примеров, особенно от этого парня. Какая альтернатива?

Стек вызовов

Абстрактные продолжения

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

Продолжения описывают эффекты управления, такие как вызов/возврат функций, обработка исключений и даже GotoS. Хорошо основанный язык будет, среди прочего, будет спроектирован с абстракциями, которые основаны на продолжениях (например, исключениях). (То есть хорошо обоснованный язык будет состоять из управляющих операторов, которые были разработаны с учетом продолжений. Конечно, вполне разумно для языка, чтобы раскрывать продолжения как Только Управляйте абстракцией, позволяя пользователям создавать свои собственные абстракции сверху.)

Первые классовые продолжения

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

Проблемы с первоклассными продолжениями

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

  • Различные абстракции, построенные на вершине продолжения, могут привести к неожиданному / неинтуитивному поведению при составлении. Например, finally Блок может быть пропущен, если я использую продолжение, чтобы прервать вычисление.
  • Если текущее продолжение может быть запрошено в любое время, то время выполнения языка должно быть структурировано, чтобы в любое время можно было создать некоторое представление структуры данных текущего продолжения. Это накладывает некоторую степень бремени на время выполнения для функции, которая, к лучшему или к худшему, часто считается «экзотикой». Если язык размещен (например, Clojure размещен на JVM), то это представление должно быть в состоянии соответствовать в рамках, предоставленной платформой хостинга. Также могут быть и другие функции, которые я язык хотел бы поддерживать (например, C -Interop), которые ограничивают пространство решения. Подобные проблемы увеличивают потенциал «несоответствия импенций» и могут серьезно усложнить развитие эффективного решения.

Добавление первоклассных продолжений к языку

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

Например, Дэвид Нолен делимк Библиотека реализует разграниченные продолжения участков программы Clojure через серию макро -преобразований. В аналогичном духе я написал шкир.cps, который представляет собой макро компилятор, который преобразует код в CPS, наряду с библиотекой времени выполнения для поддержки более основных функций Clojure (таких как обработка исключений), а также взаимодействие с нативным кодом Clojure.

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

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

На языке с достаточно сильной системой типа (например, Haskell) можно использовать систему типа для инкапсуляции вычислений, которые могут использовать операции управления (то есть продолжения) из функционально чистого кода.

Резюме

Теперь у нас есть информация, необходимая для непосредственного ответа на ваши три вопроса:

  1. Clojure не поддерживает первоклассные продолжения из-за практических соображений.
  2. Все языки основаны на продолжениях в теоретическом смысле, но лишь немногие языки раскрывают продолжения как первоклассные объекты. Тем не менее, можно добавить продолжение любого языка через, например, преобразование в CPS.
  3. Проверьте документацию для делимк и/или шкир.cps.

Общее использование продолжений заключается в реализации контрольных структур для: возврата от функции, вырываемой из цикла, обработке исключений и т. Д. Большинство языков (такие как Java, C ++ и т. Д.) Предоставляют эти функции как часть основного языка. Некоторые языки не (например, схема). Вместо этого эти языки выявляют непрерывные объекты как объекты первого класса и позволяют программисту определять новые управляющие структуры. Таким образом, схема следует рассматривать как инструментарий для языка программирования, а не полный язык сам по себе.

В Clojure нам почти никогда не нужно использовать продолжения напрямую, потому что почти все контрольные структуры обеспечиваются комбинацией языка/виртуальной машины. Тем не менее, продолжения первого класса могут быть мощным инструментом в руках компетентного программиста. Особенно в схеме продолжения лучше, чем эквивалентные аналоги на других языках (например, пара SetJmp/Longjmp в C). Этот Статья имеет более подробную информацию об этом.

Кстати, будет интересно узнать, как богатый Хикки оправдывает свое мнение о продолжениях. Есть ссылки для этого?

Кожура (или, скорее, clojure.contrib.monads) имеет продолжение монады; Вот статья, которая описывает его использование и мотивацию.

Ну ... Клоюр -> реализует то, что вы хотите ... но с макросом вместо этого

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top