Для решения второй проблемы (композиции логики) было бы неплохо иметь доступ к состоянию контролов как к именованным переменным. А то получается, что элементарная задача увеличения значения счетчика на единицу при нажатии на кнопку в функциональном подходе уже требует делать нетривиальные развязки на функциях. И счетчик это еще ерунда. Любая более-менее серьезная программа не обходится без диалога с опциями, которых запросто может быть и несколько десятков. Если к ним нельзя получить доступ как к переменным, то как его реализовывать в функциональном стиле? Это вообще возможно? Сильно подозреваю, что даже если и возможно, то развязка там получиться такая, что в ней черт ногу сломит.
1) А ты смотрел на фуджеты-то? Попробуй сделать калькулятор короче и изящней. Чуть выше была дана ссылка. 2) "Состояние контролов, как именованые переменные" - это ссылки, грубо говоря. То есть то, что мешает композиции. Отвергаем. 3) Да, придется коммутировать потоки. Это несложно, хотя и нудно. Можно и комбинаторов придумать.
1. Да, я посмотрел на фуджеты и под их впечатлением пишу. Впечатление такое, что для решения даже элементарных проблем там надо напрягаться. Вот уже достаточно простая задача - написать увеличение значения счетчика.
1. Ты сравниваешь построение элемента и его логику с одной только логикой (да и то - только ее частью).
Поэтому усложнение на ровном месте.
BTW, написание преобразующих состояние функций (i -> st -> (o,st)) проще, чем написание изменения глобального состояния. Это мой личный опыт (моделируя аппаратуру на C++, я пришел к такому же стилю программирования) и опыт товарищей из Эрланга.
Визуальные средства не дают декларативности. Вместо диалога, подходящего под look-n-feel текущей операционки мы полчаем именно кнопочки и именно "вот такую вот иконку."
2.Data.IORef
Им мало, кто пользуется. Только по необходимости.
3.Это хорошо, когда у тебя одна форма. Теперь представь, что одна и та же форма используется в паре-тройке мест, в других разных формах. Уже станет менее удобно.
И там далее сложность все увеличивается.
Протаскивание конфигурации накладно, но полезно. Видно, кто этим пользуется.
Если очень охота - state monad. Функционально и протаскивание скрыто.
1. В логику еще входит занание интерфейса функции mapstateF, которая обладает своими гитиками (например, зачем там возвращать cписок [n+1] и что он означает?) Ну ладно, изменение значения поля еще более-менее ничего проработано, а вот его получение? Человек тут тебя спросил насчет двух полей и их суммы и разности. Как результат тебе пришлось задуматься и начать что-то изобретать. А ведь любой VBист средней руки решает эту задачу не задумываясь.
Насчет фомализации работы дизайнеров, боюсь, что хорошее решение если вообще возможно, то будет настолько сложным, что врубиться в него будет достаточно непросто. Рисовать контролы в режиме What You See Is What You Get намного проще для типичного программиста и дизайнера.
3. Опции программы как раз вещь очень распространенная, есть практически в любой серьезной программе. Достаточно неприятно, когда уже с такой простой вещью возникают проблемы.
1. mapStateF' f st = let st' = f st in (st',[st'])тогда counter n = n+1
"Задуматься и что-то изобретать" мне пришлось из-за явно выраженного недетерминизма в этой задаче. Из-за того, что оба виджета ввода работают параллельно и поставляют данные по отдельности, асинхронно.
Простому программисту это не видно, что ж поделать.
Формализация работы дизайнера необходима для сколько-нибудь большого приложения. Решение это не очень сложное, находится в районе QOCA (hierarchical linear constraint solver). Это чуть-чуть сложнее, чем симплекс.
3. Не возникает с ней проблем. Не возникает.
Все "проблемы с опциями" - это требование, чтобы они лежали в глобальных переменных. Убери его и все станет на свои места.
Мне проще опустить объявление типов и потратить пять-десять минут в день на поиск ошибки, чем всюду их писать и постоянно менять (программа у меня меняется весьма сильно).
1. Ужос какие навороты. Извеняюсь, не до конца их просек, но вообще-то там как минимум еще должно фигуриривать слово Click, так что это еще не окончательная версия. :)
Если бы такая формализация работы дизайнера была бы действительно нужна, и реализации ее имеются, то почему эти реализации еще не захватили рынок? Что-то тут не так.
2. Если говоришь, что решение без глобальных переменных простое, то как насчет его написать в порядке практики работы с виджетами? :) Пусть нам надо реализовать окно с двумя полями, которое редактирует какие-то получаемые извне значения (не важно, какого типа) и по нажатию кнопки "Ok" возвращает то, что было введено, по нажатию кнопки "Cancel" возвращает исходные значения. Как передаются и возвращаются значения - не важно, можешь выбрать удобную для себя форму. Если интересно, со своей стороны могу предоставить для сравнения решение на визуальном средстве (оно совершенно тривиальное, думаю, напишется минуты за три).
counterF = intDispF >==< mapstateF count 0 >==< buttonF "Up" count n Click = (n+1,[n+1])Теперь заменится на -- Где-то в глубине библиотеки. Или нашей обертки над ней: mapStateF' f startSt = mapStateF aux startSt where aux st inp = let r = f st inp in (r,[r])
-- измененный код: counterF = intDispF >==< mapstateF' count 0 >==< buttonF "Up" count n Click = n+1Теперь и Click есть, и все остальное.
На библиотеку Qt смотрел? Там все примерно так и сделано. Но есть и визуальный редактор.
2.Как только замусь GUI, а не моделированием аппаратуры, сразу же. Ты узнаешь об этом одним из первых (если, конечно, будешь читать мой журнал).
Фуджетов я не знаю. Монаду для разборщиков написал с помощью потоковых процессоров, вот и все.
Reply
2) "Состояние контролов, как именованые переменные" - это ссылки, грубо говоря. То есть то, что мешает композиции. Отвергаем.
3) Да, придется коммутировать потоки. Это несложно, хотя и нудно. Можно и комбинаторов придумать.
Reply
counterF = intDispF >==< mapstateF count 0 >==< buttonF "Up ( ... )
Reply
Поэтому усложнение на ровном месте.
BTW, написание преобразующих состояние функций (i -> st -> (o,st)) проще, чем написание изменения глобального состояния. Это мой личный опыт (моделируя аппаратуру на C++, я пришел к такому же стилю программирования) и опыт товарищей из Эрланга.
Визуальные средства не дают декларативности. Вместо диалога, подходящего под look-n-feel текущей операционки мы полчаем именно кнопочки и именно "вот такую вот иконку."
2.Data.IORef
Им мало, кто пользуется. Только по необходимости.
3.Это хорошо, когда у тебя одна форма. Теперь представь, что одна и та же форма используется в паре-тройке мест, в других разных формах. Уже станет менее удобно.
И там далее сложность все увеличивается.
Протаскивание конфигурации накладно, но полезно. Видно, кто этим пользуется.
Если очень охота - state monad. Функционально и протаскивание скрыто.
Reply
Reply
Reply
Насчет фомализации работы дизайнеров, боюсь, что хорошее решение если вообще возможно, то будет настолько сложным, что врубиться в него будет достаточно непросто. Рисовать контролы в режиме What You See Is What You Get намного проще для типичного программиста и дизайнера.
3. Опции программы как раз вещь очень распространенная, есть практически в любой серьезной программе. Достаточно неприятно, когда уже с такой простой вещью возникают проблемы.
Дядя - это из моего поста в ru_lambda ( ... )
Reply
mapStateF' f st = let st' = f st in (st',[st'])тогда
counter n = n+1
"Задуматься и что-то изобретать" мне пришлось из-за явно выраженного недетерминизма в этой задаче. Из-за того, что оба виджета ввода работают параллельно и поставляют данные по отдельности, асинхронно.
Простому программисту это не видно, что ж поделать.
Формализация работы дизайнера необходима для сколько-нибудь большого приложения. Решение это не очень сложное, находится в районе QOCA (hierarchical linear constraint solver). Это чуть-чуть сложнее, чем симплекс.
3. Не возникает с ней проблем. Не возникает.
Все "проблемы с опциями" - это требование, чтобы они лежали в глобальных переменных. Убери его и все станет на свои места.
Мне проще опустить объявление типов и потратить пять-десять минут в день на поиск ошибки, чем всюду их писать и постоянно менять (программа у меня меняется весьма сильно).
Reply
mapStateF' f st = let f' = let st' = f st in (st',[st']) in mapState f' stТеперь более правильно.
Reply
Если бы такая формализация работы дизайнера была бы действительно нужна, и реализации ее имеются, то почему эти реализации еще не захватили рынок? Что-то тут не так.
2. Если говоришь, что решение без глобальных переменных простое, то как насчет его написать в порядке практики работы с виджетами? :) Пусть нам надо реализовать окно с двумя полями, которое редактирует какие-то получаемые извне значения (не важно, какого типа) и по нажатию кнопки "Ok" возвращает то, что было введено, по нажатию кнопки "Cancel" возвращает исходные значения. Как передаются и возвращаются значения - не важно, можешь выбрать удобную для себя форму. Если интересно, со своей стороны могу предоставить для сравнения решение на визуальном средстве (оно совершенно тривиальное, думаю, напишется минуты за три).
Reply
counterF = intDispF >==< mapstateF count 0 >==< buttonF "Up"
count n Click = (n+1,[n+1])Теперь заменится на
-- Где-то в глубине библиотеки. Или нашей обертки над ней:
mapStateF' f startSt = mapStateF aux startSt
where
aux st inp = let r = f st inp in (r,[r])
-- измененный код:
counterF = intDispF >==< mapstateF' count 0 >==< buttonF "Up"
count n Click = n+1Теперь и Click есть, и все остальное.
На библиотеку Qt смотрел? Там все примерно так и сделано. Но есть и визуальный редактор.
2.Как только замусь GUI, а не моделированием аппаратуры, сразу же. Ты узнаешь об этом одним из первых (если, конечно, будешь читать мой журнал).
Фуджетов я не знаю. Монаду для разборщиков написал с помощью потоковых процессоров, вот и все.
Все собираюсь освоить, но руки не доходят.
Поэтому - засчитывай мне слив.
Reply
Reply
И какой она была?
Reply
Reply
Судя по всему, Fudgets не сильно сложнее в разработке, чем Qt. ;)
Reply
Reply
Leave a comment