Здравствуйте, VladD2, Вы писали: VD>Это уже хрень какая-то а не континюэшоны... если я тебя правильно понял.
Конечно хрень.
MC>>Я бы отнес континуации к средствам метапрограммирования по части control flow. VD>А не надо это делать. Для МП есть куда более подходящие средства.
Почему не надо? С помощью континуаций делаются эксепшены, корутины и прочая ересь, которую уже используют прикладные программисты. По мне так и есть — метасредство.
Здравствуйте, VladD2, Вы писали:
А>> Того врага народа, который придумал таймауты, надо выпороть публично. Чтоб другим неповадно было.
VD>Публично надо пороть тех кто заходит на сайт и держит там сессии без надобности.
На всяких гос. сайтах заполнение анкет часто занимает немалое время — надо найти разные документы, просмотреть. Очень потом приятно, после часа работы, увидеть по сабмиту что мол опа, таймаут.
Не, таймауты — это редкостный идиотизм, которому нет никакого оправдания.
Здравствуйте, Mr.Cat, Вы писали:
MC>Почему не надо?
Я уже отвечал на этот вопрос. Для этого есть лучшие средства.
MC>С помощью континуаций делаются эксепшены, корутины и прочая ересь, которую уже используют прикладные программисты. По мне так и есть — метасредство.
Сопрограммы и континиэшоны во многом похожи, но имеют принципиальные различия. Вольфхаунд где-то очень хорошо это продемонстрировал. Так что сделать качествнно из одного другое будет затруднительно.
Исключения же точно не стоит делать. Они просто должны быть в языке, если его дизайн на них расчитан. Опять же реализовать исключения эффективно не выйдет, так как эффективная их реализация — это их отсутствие в коде. Континюэшоны же принципиально не эффективны, так как не ложатся на архитектуру процессора на котором исполняется программа.
И исключения, и сопрограммы — это системные вещи. Метапрограммирование же призвано решать прикладные задачи.
Тут вообще какая-то подмена понятий. То что через одну фичу можно с горем пополам выразить другую не делает саму фичу метапрограммированием. Скажем через функции можно выразить циклы, но функции не дают поддержку МП.
Покажи мне как с помощью континюэшонов создать какую-то новую синтаксическую конструкцию. Тогда и поговорим.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А> На всяких гос. сайтах заполнение анкет часто занимает немалое время — надо найти разные документы, просмотреть. Очень потом приятно, после часа работы, увидеть по сабмиту что мол опа, таймаут.
А зачем для заполнения анкеты держать соединение?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: ФЯ для WEB
От:
Аноним
Дата:
24.09.09 17:21
Оценка:
Здравствуйте, VladD2, Вы писали:
А>> На всяких гос. сайтах заполнение анкет часто занимает немалое время — надо найти разные документы, просмотреть. Очень потом приятно, после часа работы, увидеть по сабмиту что мол опа, таймаут.
VD>А зачем для заполнения анкеты держать соединение?
А это надо "программистов" так называемых спрашивать, кто эти сайтики клепает. Обычно сессия выглядит так — авторизация (вот тут контекст сессии и создаётся) — две-три страницы с вопросами, а потом большая страница с большой формой. И вот при её сабмите таймаут и происходит.
Но вопрос не в этом. Вопрос простой — зачем вообще эти таймауты?!?
Здравствуйте, Аноним, Вы писали:
А> А это надо "программистов" так называемых спрашивать, кто эти сайтики клепает. Обычно сессия выглядит так — авторизация (вот тут контекст сессии и создаётся) — две-три страницы с вопросами, а потом большая страница с большой формой. И вот при её сабмите таймаут и происходит.
А> Но вопрос не в этом. Вопрос простой — зачем вообще эти таймауты?!?
Я вообще не понимаю о каких таймаутах речь.
Авторизация может тупо вернуть некий билет который можно хранить в куках. Сессия тут просто не нужна.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Сопрограммы и континиэшоны во многом похожи, но имеют принципиальные различия. Вольфхаунд где-то очень хорошо это продемонстрировал. Так что сделать качествнно из одного другое будет затруднительно.
Не так.
Сопрограммы конечно же выражаются через продолжения. Через продолжения можно выразить вообще любую конструкцию управляющую потоком исполнения.
Но у полноценных продолжений есть очень большая проблема которой нет у сопрограмм.
Продолжения в общем случае не совместимы с детерминированной финализацией. Сопрограммы этой проблемы не имеют.
А детерминированная финализация не практике необходима.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
VD>>Сопрограммы и континиэшоны во многом похожи, но имеют принципиальные различия. Вольфхаунд где-то очень хорошо это продемонстрировал. Так что сделать качествнно из одного другое будет затруднительно. WH>Продолжения в общем случае не совместимы с детерминированной финализацией. Сопрограммы этой проблемы не имеют. WH>А детерминированная финализация не практике необходима.
Продолжения не совместимы с детерминированной финализацией не более, чем обычные замыкания. Всегда при желании можно захватить ссылку на закрытый ресурс в environment долго-живущей лямбды.
Насколько я понимаю, Влад противопоставляет макросы и продолжения в качестве средств метапрограммирования. Опять же, в отношении детерминированной финализации они ничем не отличаются. Ничем не ограниченные трансформации AST в общем случае ничуть не безопаснее ничем не ограниченных манипуляций потоком управления.
з.ы. Заметьте, я не утверждаю, что при применении продолжений проблем совсем не возникает.
Здравствуйте, VladD2, Вы писали: VD>Сопрограммы и континиэшоны во многом похожи, но имеют принципиальные различия. Вольфхаунд где-то очень хорошо это продемонстрировал.
А ссылочку можно?
VD>Исключения же точно не стоит делать. Они просто должны быть в языке, если его дизайн на них расчитан.
Ну это, пожалуй, один из немногих примеров механизма "нелокальных переходов", который стал общепризнанным. А вот корутинами каждый в своем языке называет что-то свое.
VD>И исключения, и сопрограммы — это системные вещи. Метапрограммирование же призвано решать прикладные задачи.
Я смотрю на МП как на инструмент разработчика библиотек, которыми потом пользуются прикладные программисты. И континуации к таким инструментам тоже отношу. Впрочем, по вопросам классификации понятий мне спорить не хотелось бы.
VD>Тут вообще какая-то подмена понятий. То что через одну фичу можно с горем пополам выразить другую не делает саму фичу метапрограммированием.
Не с горем пополам одно через другое, а реализовать на основе одного целый класс схожих механизмов.
Так, гигиенические макросы позволяют создавать новые синтаксические конструкции, обладающие свойством лексической области видимости.
А континуации — создавать механизмы нелокального перехода.
Здравствуйте, VladD2, Вы писали:
VD>Тут вообще какая-то подмена понятий. То что через одну фичу можно с горем пополам выразить другую не делает саму фичу метапрограммированием. Скажем через функции можно выразить циклы, но функции не дают поддержку МП. VD>Покажи мне как с помощью континюэшонов создать какую-то новую синтаксическую конструкцию. Тогда и поговорим.
Синтаксическую конструкцию, конечно же, сделать нельзя. Но сделать так, чтобы вызов обычной функции выглядел как ключевое слово, можно.
Например, можно сделать некое подобие list-comprehensions:
(* test() возвращает [(1, 11); (1, 13); (2, 12); (3, 11); (3, 13)] *)let test () = generate (fun () ->
let x = oneof [1;2;3] in
let y = oneof [11;12;13] in
begin
guard ((x + y) mod 2 == 0);
return (x, y)
end)
oneof, guard, return кажутся ключевыми словами, но таковыми не являются.
Вот их определение (без комментариев, там происходит монадная рефлексия и прочее колдунство):
open Delimcc
let p = new_prompt ()
let shift f = take_subcont p (fun sk () ->
push_prompt p (fun () -> (f (fun c ->
push_prompt p (fun () -> push_subcont sk c)))))
let generate f = push_prompt p f
let bind m k = List.concat (List.map k m)
let return x = [x]
let oneof m = shift (fun k -> bind m (fun x -> k (fun () -> x)))
let guard cond = if cond then oneof [()] else oneof []
Признаю, для данной задачи макросы подходят гораздо лучше. А вот для веба, если мы хотим программировать серверную часть так, будто это обычный десктопный ГУЙ, показывающий модальные диалоги и дожидающийся ответа, все не так очевидно.
Здравствуйте, palm mute, Вы писали:
PM>Продолжения не совместимы с детерминированной финализацией не более, чем обычные замыкания. Всегда при желании можно захватить ссылку на закрытый ресурс в environment долго-живущей лямбды.
Ты не прав.
Засовываем все ресурсы в uniqueness типы и нет проблем.
Более того ты сейчас говоришь о искусственном продлении жизни ресурса.
Это не проблема особенно если обязать разработчика делать это явно и не давать продлевать жизнь уже убитым ресурсам. С uniqueness типами это получается автоматом.
С продолжениями другая беда.
Покажу на псевдокоде:
Не трудно заметить что file.Close() может быть вызвана более одного раза.
Что является фундаментальной проблемой и не может быть устранено при наличии полноценных продолжений вне зависимости от модели детерминированной финализации.
PM>Насколько я понимаю, Влад противопоставляет макросы и продолжения в качестве средств метапрограммирования. Опять же, в отношении детерминированной финализации они ничем не отличаются. Ничем не ограниченные трансформации AST в общем случае ничуть не безопаснее ничем не ограниченных манипуляций потоком управления.
Если за детерминированной финализацией следит система типов то ты хоть затрансформируйся... проверяльщик типов просто не пропустит программу в которой финализацию поломали.
Причем эти проверки могут быть осуществлены даже без зависимых типов.
PM>з.ы. Заметьте, я не утверждаю, что при применении продолжений проблем совсем не возникает.
Ты просто сильно занижаешь их вредность...
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, palm mute, Вы писали:
PM>Признаю, для данной задачи макросы подходят гораздо лучше. А вот для веба, если мы хотим программировать серверную часть так, будто это обычный десктопный ГУЙ, показывающий модальные диалоги и дожидающийся ответа, все не так очевидно.
Сам же ссылку на Ur/Web давал
Вот из такого кода
fun counter n = return <xml><body>
Current counter: {[n]}<br/>
<a link={counter (n + 1)}>Increment</a><br/>
<a link={counter (n - 1)}>Decrement</a>
</body></xml>
fun main () = counter 0
получаем вот такой HTML
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><body><sc>
Current counter: 0<br />
<a href="/ur/demo/Demo/Counter/counter/1">Increment</a><br />
<a href="/ur/demo/Demo/Counter/counter/-1">Decrement</a>
</body></html>
Обошлось без всяких там продолжений.
Просто сериализовали имя и аргументы функции в url и все.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, palm mute, Вы писали:
PM>>Продолжения не совместимы с детерминированной финализацией не более, чем обычные замыкания. Всегда при желании можно захватить ссылку на закрытый ресурс в environment долго-живущей лямбды. WH>Ты не прав. WH>Засовываем все ресурсы в uniqueness типы и нет проблем.
Подтягивается тяжелая артиллерия . Только что у нас были только макросы, теперь уже навороченные системы типов появились. Какие есть принципиальные трудности реализации такой же системы типов, которая поддерживает продолжения?
WH>С продолжениями другая беда. WH>Покажу на псевдокоде:
... WH>Не трудно заметить что file.Close() может быть вызвана более одного раза. WH>Что является фундаментальной проблемой и не может быть устранено при наличии полноценных продолжений вне зависимости от модели детерминированной финализации.
Предположим, у нас есть система типов, о которой ты говоришь.
Компилятор делает CPS-преобразование, callcc в псевдокоде превращается в:
Твоя система типов должна справиться с кодом после преобразования, если лямбды для нее не проблема.
PM>>з.ы. Заметьте, я не утверждаю, что при применении продолжений проблем совсем не возникает. WH>Ты просто сильно занижаешь их вредность...
Ни в коем случае. Я вообще не делаю оценочных утверждений типа "фича икс зло, а фича игрек — рулит". Мне просто не нравится, что о продолжениях создаются мифы.
Здравствуйте, WolfHound, Вы писали:
PM>>Признаю, для данной задачи макросы подходят гораздо лучше. А вот для веба, если мы хотим программировать серверную часть так, будто это обычный десктопный ГУЙ, показывающий модальные диалоги и дожидающийся ответа, все не так очевидно. WH>Сам же ссылку на Ur/Web давал WH>... WH>Обошлось без всяких там продолжений. WH>Просто сериализовали имя и аргументы функции в url и все.
Как это обошлось без продолжений? "сериализовали имя и аргументы функции в url" — это и есть продолжение. Думаю, если бы у функции counter были локальные переменные — их мы бы тоже увидели в url.
Обошлось без first-class продолжений, что неудивительно в прикладном DSL, зачем они там? Т.к. автор выбрал трудный путь — создать полноценный язык, с компилятором и стандартной библиотекой, написанными с нуля, — юзеру ничего не нужно знать о продолжениях, ими занимается компилятор.
А вот если general-purpose язык поддерживает first-class продолжения, то, теоретически, использовать его для веба проще, т.к. можно легко создать embedded DSL. Что важно, не нужно переписывать стандартную библиотеку, запросы пользователю можно отправлять из глубин библиотечных функций, подсунув им правильный callback.
Здравствуйте, WolfHound, Вы писали: WH>Что является фундаментальной проблемой и не может быть устранено при наличии полноценных продолжений вне зависимости от модели детерминированной финализации.
Я не согласен, что это фундаментальная проблема континуаций. С аналогичной проблемой можно столкнуться (а можно и не столкнуться) хотя бы в C#:
...если в Enumerate используется yield.
Если бы компилятор мог такие ошибки предотвращать — было бы хорошо. Но то, что это фундаментальная проблема — не согласен.
Здравствуйте, palm mute, Вы писали:
PM>Как это обошлось без продолжений? "сериализовали имя и аргументы функции в url" — это и есть продолжение. Думаю, если бы у функции counter были локальные переменные — их мы бы тоже увидели в url.
Это не продолжение. Это замыкание. Стек вызовов не сохраняется. Пожалуйста не путай их.
Кстати сам автор говорит о том же
Pressing the button triggers a call to loop, with the first argument given explicitly as count+1. Notice that this means that we are using closures, stored on the client side, to track state.
PM>А вот если general-purpose язык поддерживает first-class продолжения, то, теоретически, использовать его для веба проще, т.к. можно легко создать embedded DSL. Что важно, не нужно переписывать стандартную библиотеку, запросы пользователю можно отправлять из глубин библиотечных функций, подсунув им правильный callback.
Да не нужны продолжения.
Замыканий более чем достаточно.
Ur/Web это прекрасно демонстрирует.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Mr.Cat, Вы писали:
WH>>Что является фундаментальной проблемой и не может быть устранено при наличии полноценных продолжений вне зависимости от модели детерминированной финализации. MC>Я не согласен, что это фундаментальная проблема континуаций.
Ну давай раскажи как заставить try/finally bли любой другой способ детерминированной финализации работать в присутствии продолжений.
MC>С аналогичной проблемой можно столкнуться (а можно и не столкнуться) хотя бы в C#: MC>
MC>...если в Enumerate используется yield.
То что можно себе отстрелить голову и без продолжений ни кто не спорит.
Но в данном случае ты приводишь проблему которая есть только в конкретном языке с весьма позорной системой типов.
Простейшие uniqueness решают данную проблему на корню.
MC>Если бы компилятор мог такие ошибки предотвращать — было бы хорошо.
То что C# не может не значит что другие языки не могут.
MC>Но то, что это фундаментальная проблема — не согласен.
С корутинами типа yield действительно проблем нет.
Вот смотри:
def ReadLines(file : File) : Stream[string]
match (file.ReadLine())
| Some(line) =>
yield line;
ReadLines(file);
| None =>
Stream.End;
end
end
def DoSome(...) : Stream[string]
...
def file = File.Open(...);
...//если тут будет исключение файл будет закрыт
ReadLines(file);
end
Типы File и Stream[T] uniqueness.
Это значит что в один момент времени на объект может существовать одна и только одна ссылка.
Если ссылка на объект uniqueness типа вышла из зоны видимости то у объекта вызывается деструктор.
В данном случае функция ReadLines забирает владение открытым файлом, создает корутину в контексте которой будет жить открытый файл. И возвращает объект Stream[string].
При разрушении Stream[string] будет вызван деструктор объекта File.
Таким образом мы гарантировали что файл будт закрыт один и только один раз.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
12.8 Rpcify
Pieces of code are determined to be client-side, server-side, neither, or both, by figuring out which standard
library functions might be needed to execute them. Calls to server-side functions (e.g., query) within mixed
client-server code are identified and replaced with explicit remote calls. Some mixed functions may be
converted to continuation-passing style to facilitate this transformation.
Здравствуйте, palm mute, Вы писали:
PM>Подтягивается тяжелая артиллерия . Только что у нас были только макросы, теперь уже навороченные системы типов появились.
Пожалуйста не путай меня и Влада.
PM>Какие есть принципиальные трудности реализации такой же системы типов, которая поддерживает продолжения?
Если только продолжения то ни каких.
А если мы еще и детерминированную финализацию хотим то придется выбирать либо то либо другое.
PM>Предположим, у нас есть система типов, о которой ты говоришь. PM>Компилятор делает CPS-преобразование, callcc в псевдокоде превращается в:
И отвергается проверяльщиком типов. Ибо нефиг плодить ссылки на uniqueness тип.
PM>Ни в коем случае. Я вообще не делаю оценочных утверждений типа "фича икс зло, а фича игрек — рулит". Мне просто не нравится, что о продолжениях создаются мифы.
Какие мифы? Только факты.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн