Comments 20
http://horna.org.ua/books/All_About_Monads.pdf
> Abuse of the Continuation monad can produce code that is impossible to understand and maintain.
> Abuse of the Continuation monad can produce code that is impossible to understand and maintain.
+4
Было бы классно, если бы имелся какой-нибудь веб-фреймворк для Haskell, использующий продолжения (Is anyone using delimited continuations to do web development in Haskell?)
Продолжения – шикарная вещь для удобного и быстрого построения веб-логики и интерфейса приложения, сохраняющего состояния. В этом плане себя прекрасно показывает веб-сервер языка Racket.
Продолжения – шикарная вещь для удобного и быстрого построения веб-логики и интерфейса приложения, сохраняющего состояния. В этом плане себя прекрасно показывает веб-сервер языка Racket.
0
Не могли бы вы пояснить, что такого шикарного предлагают продолжения веб-разработке?
0
Можно записать логику с показом множества форм как обычную последовательность действий. Примерно так:
Начинаем нечто
call-cc form1
продолжаем имея результаты form1
call-cc form2
продолжаем уже и с form2
framework обеспечивает возврат после form1/form2.
Начинаем нечто
call-cc form1
продолжаем имея результаты form1
call-cc form2
продолжаем уже и с form2
framework обеспечивает возврат после form1/form2.
+1
Понятно.
> на каждую клиентскую сессию в рантайме развешивается некое дерево замыканий и продолжений, которые держат ссылки на различные объекты, не позволяя мусорщику их подчистить.
> мы не можем нарастить производительность системы добавлением нового сервера с балансировкой веб-запросов в кластере. Потому что все запросы клиента в пределах одной пользовательской сессии должны попадать на ту машину, где она была создана.
> на каждую клиентскую сессию в рантайме развешивается некое дерево замыканий и продолжений, которые держат ссылки на различные объекты, не позволяя мусорщику их подчистить.
> мы не можем нарастить производительность системы добавлением нового сервера с балансировкой веб-запросов в кластере. Потому что все запросы клиента в пределах одной пользовательской сессии должны попадать на ту машину, где она была создана.
0
Stateful веб-приложения — зло. Стейты интерфейса на продолжениях не исключение. Не нужно городить такой слой абстракций, аукнется.
+1
А в чём их проблема?
+1
Если коротко: использование stateful архитектуры влечет за собой не оправданное в большинстве случаев усложнение архитектуры.
Протокол http по своей натуре stateless. Для имитации сеансового общения с состоянием (сессии) в любом случае приходится делать хаки. Это или проставление специального хедера с идентификатором сессии, либо специальное поле в передаваемых данных, ну или конечно же встроенный механизм на основе кук. Однако нужно понимать, что это скорее для исключительных ситуаций, где без стейта уже никак, например авторизация пользователя. Не зря же существует вообще REST-архитектура.
Что касается стейтовых приложений, то они имеют право на жизнь, но вспомним чем же так хороша REST-архитектура. Это легкое обеспечение отказоустойчивости и масштабируемости. В случае стейтового приложения нужно будет использовать хитроумный механизм репликации состояний между узлами кластера, что является довольно серьезным усложнением инфраструктуры приложения, на которое нельзя идти без веских причин.
Одно дело, если имеем в виду толстое интерпрайзное приложение, в котором до черта многостраничных форм, то тут да, наверное стоит приложение сделать stateful и настравивать репликацию сессий на выбранном аппсервере. Но тут уже сложившийся набор технологий.
Протокол http по своей натуре stateless. Для имитации сеансового общения с состоянием (сессии) в любом случае приходится делать хаки. Это или проставление специального хедера с идентификатором сессии, либо специальное поле в передаваемых данных, ну или конечно же встроенный механизм на основе кук. Однако нужно понимать, что это скорее для исключительных ситуаций, где без стейта уже никак, например авторизация пользователя. Не зря же существует вообще REST-архитектура.
Что касается стейтовых приложений, то они имеют право на жизнь, но вспомним чем же так хороша REST-архитектура. Это легкое обеспечение отказоустойчивости и масштабируемости. В случае стейтового приложения нужно будет использовать хитроумный механизм репликации состояний между узлами кластера, что является довольно серьезным усложнением инфраструктуры приложения, на которое нельзя идти без веских причин.
Одно дело, если имеем в виду толстое интерпрайзное приложение, в котором до черта многостраничных форм, то тут да, наверное стоит приложение сделать stateful и настравивать репликацию сессий на выбранном аппсервере. Но тут уже сложившийся набор технологий.
0
Не понял. В выражении callCC $ \k -> k (чёнибудь) k имеет тип (a -> Cont r b), то есть возвращает продолжение со входом отличным от чёнибудь. При этом возвращаемое замыканием значение имеет тип Cont r a. То есть тип чёнибудь. Получается что типы построенного с помощью k продолжения и продолжения, которое будет возвращено (пипец, мне бы хоть окурочек от того косяка, что это породил) отличаются. Как такое может получиться?
+1
После прочтения хочется воскликнуть: о Боже, ну зачем так усложнять простую вещь?
-1
Нет. Ну а к чему минус? Вот смотрите, вызовам с продолжениям в руководстве по lisp уделена пара страничек. И этого достаточно, чтобы понять и пользоваться. В Haskell же монады, мозговыворачивательные ограничения на типы и т.д. Какой смысл в этом? Я вот действительно не понимаю. Тем более, что если судить по Real World Haskell это всё нисколько не упрощает программирование, а только запутывает его. So why so overcomplicated?
0
square_Cont :: Int -> Cont r Int
-- square_Cont x = return (x*x)
square_Cont = return . join (*)
incr_Cont :: Int -> Cont r Int
-- incr_Cont x = return (x+1)
incr_Cont = return . (+1)
func_Cont :: Int -> Cont r Int
{-
func_Cont x = do inc <- incr_Cont x
sq <- square_Cont inc
return sq
-}
func_Cont = (square_Cont =<<) . incr_Cont
> Эта программа вычисляет факториал, и если он оказывается больше 9000, возвращает сообщение «OVER 9000», а если нет, то просто его значение.
Эта программа возвращает строку «OVER 9000» для n > 7, а для остальных n возвращает строку с n!..
foo :: Int -> Cont r String
foo s = do (i, back) <- getCC' s
when (i < 20) $ back (i*2)
return $ show i
А зачем тут String?
Что такое getCC' и откуда?
0
Как я вижу, Вы сделали некоторые функции короче. Конечно можно и так, но цель моего «развёрнутого» кода в том, что можно проследить взаимосвязь между использованием продолжений как обычных функций, и как монад.
Сравните:
Да, эта программа не учитывает само значение факториала, просто для n>7 факториал больше 9000.
String тут потому, что в конце мы возвращаем show i, т.е. строковое представление числа.
getCC' — это вариант getCC, с помощью которого можно ещё и передать состояние. Грубо говоря, getCC' возвращает нам пару из текущего состояния вычисления (число в данном случае) и функции, которая берёт новое состояние и возвращает вычисление в заданную точку (как goto). В статье есть больше про getCC и getCC' + объяснение как они работают.
Сравните:
func_cps :: Int -> (Int -> r) -> r
func_cps x k = incr_cps x $ \inc ->
square_cps inc $ \sq ->
k sq
иfunc_Cont :: Int -> Cont r Int
func_Cont x = do inc <- incr_Cont x
sq <- square_Cont inc
return sq
Да, эта программа не учитывает само значение факториала, просто для n>7 факториал больше 9000.
String тут потому, что в конце мы возвращаем show i, т.е. строковое представление числа.
getCC' — это вариант getCC, с помощью которого можно ещё и передать состояние. Грубо говоря, getCC' возвращает нам пару из текущего состояния вычисления (число в данном случае) и функции, которая берёт новое состояние и возвращает вычисление в заданную точку (как goto). В статье есть больше про getCC и getCC' + объяснение как они работают.
0
Sign up to leave a comment.
Продолжения в Haskell