Home

[icon] наивный идеализм
View:Свежие записи.
View:Архив.
View:Друзья.
View:Личная информация.
View:Website (http://dervish-candela.deviantart.com/).
You're looking at the latest 9 entries.

Tags:, , ,
Subject:асинхронный гуй
Time:12:30 pm
оказался проще, чем мы думали:
import threading
import wx.lib.newevent
MakeEvent01, wx.EVENT01 = wx.lib.newevent.NewEvent()

class widget1(wx.SomeWidget):
def async_report(self, s):
    event = MakeEvent01()
    event.text = s
    wx.PostEvent(self, event)

def __init__(self, parent, **kwargs):
   wx.SomeWidget.__init__(self, parent, wx.ID_ANY, **kwargs)

def AssignJob(self,do_stuff):
   do_stuff_frozen = functools.partial(do_stuff, async_report)
   self.t = threading.Thread(target=do_stuff_frozen)
   self.Bind(wx.EVENT01, self.Event01Handler)
   self.t.start()

def Event01Handler(self, evt)
   self.Display(evt.text)

Этому добру кормим любую функцию вида DoSomeLongAndHeavyStuff(log) и радуемся жизни.
Интересно, можно ли ещё проще.
comments: 5 комментариев or Оставить комментарий в избранное рассказать другу

Tags:, , , , , ,
Subject:ВНЕЗАПНО, Хаскель атакуэ
Time:10:36 am
Вчера мы с [info]hakubo обсуждали Хаскель. Ну, обсуждали - это сильно сказано, обычно он присылает мне интересные ссылки на про языки программирования или аугментированную реальность, а я что-нибудь не слишком осмысленное пишу в эвей обратно, т.к. наши часы присутствия в онлайне сильно не совпадают.

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

Но обратно к Хаскелю. Мне все больше начинает казаться, что функциональные языки скрывают кучу стройных, красивых и простых концепций за отвратительнейшим синтаксисом, как будто нарочно пытаясь нас запутать.

Ради интереса полез посмотреть ,как у хаскеля с гуями (т.е. может ли он использоваться для чего-то кроме консольных программ или библиотек). И меня сразу же потрясла одна вещь - wxHaskell уже реализует почти буквально вон тот декларативный гуевый велосипед, что я придумал на досуге. Да простят мне бесстыдный и бесконечный самопиар, я так редко придумываю достойные идеи, что искренне радуюсь, когда их, оказывается, уже сделали.
hello
  = do f    <- frame    [text := "Hello!"]
       quit <- button f [text := "Quit", on command := close f]
       set f [layout := widget quit]

Вот это я называю «выразительность». Что (не)удивительно, этот код полностью понятен даже без какого бы то ни было знания Хаскеля, функциональных языков или принципов работы гуя на событийной основе.

Я по-прежнему боюсь тыкать палочкой Хаскель. Не могу представить, как лично мне его применить на практике, и хотя в теории это лечится чтением ртфм, на практике фм по нему часто запутан ещё больше, чем сам язык. Из других языков я, возможно, соберусь когда-нибудь потыкать палочкой Руби и Скалу. В Руби привлекает, по-видимому, большая гибкость и расширямость языка, полезная при создании кавайных, претенциозных и совершенно бесполезных маленьких DSL на месте. Чем хороша Скала, всем известно, хотя явовское наследие настораживает.
comments: 22 комментария or Оставить комментарий в избранное рассказать другу

Tags:, , , , ,
Subject:AVC, Application View Controller (переписано и дополнено)
Time:01:11 pm
Все мы помним, какая хорошая это идея — архитектура Model-View и её вариации, и какое дикое количество геморроя она вызывает на практике. Связано это с тем, что она никак принципиально не решает проблему переплетения кода модели и кода представления, не убирает этот беспорядок, а всего лишь дает возможность в нем ориентироваться. На гордое звание решения могут претендовать лишь инструменты, избавляющие нас от хаоса.
Об разделении business-кода и интерфейсов много говорили, и иногда по делу, но в итоге все сводилось к вписыванию кода в обработчики событий и бесчиаленные вызовы TextCtrl1.GetText(). Просто вместо хардкода последовательности инициализации интерфейсов хранились в отдельных файлах и представлялись в виде xml — этакий психологичеcкий трюк, чтоб относиться к ним, как данным. И если для компилируемых языков это было критично, то для, скажем, Питона уже никакой разницы между трансляцией xml-файла в интерфейсный код и собственно подгрузкой и непосредственным исполнением файла с уже имеющимся интерфейсным кодом в принципе не существует.

Эти жалкие полумеры меня не могли радовать. Идеальная система, как я её себе воображал, выглядела примерно так: берется алгоритм, где все инструкции вида print(x) или Label.SetText(x) убираются, а вместо них в начале ставятся, «watch(x) as Label»; а всякие словоблудия типа TextCtrl.GetText(s) заменяются на «reflect(s) as TextCtrl». Странные термины были выбраны специально, чтобы подчеркнуть декларативность стиля, вневременность и внеконтекстность связей: мы, Человек, должны только высказать, что хотим отображать переменную или знать значение текстбокса, а остальное - проблемы роботов.

Оказалось, что похожая штука существует: http://avc.inrim.it/
Именно (почти) об этом я мечтал. Это, товарищи, потрясающе. Эта штука автоматически связывает извлекаемые из ресурсов гуи и переменные в коде. Но мало того, по сути дела это ещё и мета-тулкит. Можно писать код, абсолютно агностичный не только к платформе, не только к конкретному тулкиту, — но и к гую как таковому в принципе.

От моей конепции AVC отличается тем, явно что использует xml и редакторы гуя. Это разумное решение - опираться на уже имеющиеся инструменты. А взамен на это она вообще избавляет нас от необходимости явно декларировать, что мы хотим отображать или знать - достаточно просто дать контролам имена соответсвующих переменных. Теоретически, на базе этого легко можно построить предложенную мной систему, которая будет ещё проще и примитивнее, но зато позволит быстро и в два слова писать истинно декларативный гуй от руки. А для случаев посложнее по-прежнему грузить интерфейсные файлы или читать конфигурацию раскладки шуевых элементов из строки с подобием вики-таблицы. Ну это все теоретически, на практике-то у меня кишка тонка такое кодить.

Картинка.

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

P.S. Ещё один похожий концепт был в экспериментальном интерфейсно-остроумном тулките Shoes для Руби, но для написания стандартного интерфейс он не подходил, да и не ставил перед собой такую задачу.
comments: 3 комментария or Оставить комментарий в избранное рассказать другу

Tags:, ,
Subject:свет в конце туннеля?
Time:11:11 am
В контексте проблемы гуя мне уже несколько раз упоминали про WPF. несмотря на то, там много как интересных решений (доведение до ума слоя абсракций между прикладным кодом и системой), так и серьёзных минусов (огромность и неподъёмность, проприетарная идеология), нас интересует один чисто технологический аспект: а именно, XAML. По заявлениям эта фиговина обеспечивает полностью декларативное написание гуёв и чистое, как никогда раньше, разделение функционального («бизнес», май эсс) кода и gui-кода, и ещё много прочего бла. К сожалению, при ближашем рассмотрении эта хрень оказалась старым добрым XML, т.е. никаких принципиальных изменений в парадигме написания интерфейсов не произошло - просто вызовы api в очередной раз спрятали ещё глубже и укутали слоями абстракции и задолбавшего X*L. Более того, с точки зрения человека XML, будь он хоть сто раз декларативный, в сотню раз хуже императивного гуя на тулкитах - ибо работать с XML можно только с помощью костылей, ведь это фактически антипаттерн человекочитаемости. Я допускаю, что там будет реализован какой-то более чёткий и ясный механизм связывания функциональности гуя и функциональности кода, но, используя презумпцию виновности, получаем вывод: это просто майкрософтовская реализация QtDesigner / Glade для очередных Foundation Classes, обвешанная пышными слоганами.

«Пастернака не читал, но осуждаю»© :D
comments: 1 комментарий or Оставить комментарий в избранное рассказать другу

Tags:, , , , ,
Subject:это бесценно
Time:02:24 pm
ярлык: C:\GTK\bin\glade-2.exe
реальность: C:\GTK\bin\glade-3.exe
Парни из команды GTK дают жару! прослоупочить собственный релиз! :)
comments: Оставить комментарий в избранное рассказать другу

Tags:, , , ,
Subject:ах, собаки! ах, какие же собаки!!
Time:02:10 pm
pygobject-2.14.1-1.win32-py2.5.exe (171 Кб)

>>> import gtk
ImportError: No module named cairo

господи, какие же собаки это не собаки! это крысы!!

pycairo-1.4.12-1.win32-py2.5.exe (82 Кб)

>>> import pygtk
>>> import gtk
>>> import cairo

Ну неужели нельзя было на сорсфорже выложить сразу готовую пачку одним инсталлером, а?
Я уже нашёл ссылку на эту пачку, но почему, бл..., её не было в категории win32 binary на сорсфорже?!
comments: 2 комментария or Оставить комментарий в избранное рассказать другу

Tags:, , , ,
Subject:как я скучаю по emerge
Time:01:53 pm
gtk-2.12.9-win32-2.exe
gtk-dev-2.12.9-win32-2.exe
pygtk-2.12.1-2.win32-py2.5.exe

>>> import pygtk
ImportError: No module named pygtk

>>> import gtk
ImportError: No module named gobject

надо, наверное, было качать какой-то другой инсталлер. Или исходник. Хотя питоновые инсталлеры всё равно генерятся из исходников. В общем, какой-то другой. repeat until©
comments: Оставить комментарий в избранное рассказать другу

Tags:, , , ,
Subject:Функциональный ГУЙ!
Time:10:34 am
В общем, я ляпнул что для излечения от виджетной тулчанки нам нужно использование функциональных парадигм, и пришлось задуматься:

— как применить функциональную парадигму к гую?
В предельно общем случае мы получаем следующее:

watch(var)
react(button)
reflect(var ←→ input)

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

Хорошо, ну а вот как это теперь написать?
Попробуем приблизить это к форме, реализуемой технологически (пусть даже в виде макросов) (OSHI-- я это сказал. проклятие Настоящих Программистов настигнет меня...)
Используя менеджер контекста, мы можем спрятать все детали инициализации и даже закрыть глаза на то, когда именно она происходит. Более того, стараемся помнить, что функциональная парадигма в идеале требует описывать только нужные действия, независимо от их порядка, но для простоты предположим, что мы помещаем эти формулы (объявления действий) в начале программы. На границе сознания смутно маячит проблема глобальных переменных, но мы её не замечаем, т.к. мы спасаем мир решаем более фундаментальную проблему, ну и плюс мы смутно помним, что в современных динамических языках не всё так с ними страшно. Кстати, аргументов у всех наших функций тоже должно быть ровно один, иначе наши уравнения теряют смысл (и приобретают Паскаль).

Ну, например, вот так:
(псевдокод, но валидный питон... почти. префиксы мы добавлять не будем, хотя wxХрень или QХрень смотрится, конечно, в сто раз круче, чем просто Хрень </ирония>)
with App:
    with Window1:    
        watch(var1) //отображение
        react(button1) = proc1  //уравнение :)
        reflect(var2 <> input1)  //отражение

В принципе, этот код уже должен работать без дополнительной рихтовки. Всё остальное должен либо (автоматически) конфигурировать отдельный девайс настройки, либо и знакомый нам по дельфям метод прямого обращения к свойствам компонента с помощью контекстного менеджера (который уже сам решит, когда выполнять данные ему инструкции настройки) тоже подойдёт. Важно не перегнуть абстракцию: в нашем случае компоненты должны реализовывать высокоабстрагированный интерфейс и сохранять функциональный стиль. Тут можно придумать множество синтаксического сахара - например, каждая из трёх фундаментальных инструкций watch/react/reflect могла бы сама служить контекстным менеджером настройки упомянутого в ней элемента интерфейса, и это было бы хорошо, но в отсутствие рабочей имплементации это — бессмысленное занятие.

Заметим, что я сделал формы нарочно непохожими: оно лучше, когда «разные идиомы выглядят по разному»©. А т.к. их назначения принципиально различны, то имеет смысл сделать их использование тоже разным. Хотя синтаксис можно допилить, и, особенно значки операторов, — их можно использовать любые. Например, вот такая версия с учётом вышесказанного:
reflect(var2 = input1) | proc2 //отражение в виде уравнения и ещё обработчик
    style="border:1pt;font-family:verdana" //внезапно набигает цсс! 
react(button1) >> proc1  //злой c++ возвращается и мстит! ха-ха-ха!!
    caption="push me" //а вот более традиционный подход
    appearace=schema1 //а ещё хорошо бы не прописывать все эти visible = true руками,ね
    behavior=follow(!proc1) //да и с задолбавшим enabled = false давно пора что-то делать

или даже вот такая спекуляция на идее корутин: reflect(var2 < proc2 > input1) //хотя это выглядит уже чересчур грязно
Можно всё. Кроме react(button1, proc1), конечно. За такое убивают.
comments: 16 комментариев or Оставить комментарий в избранное рассказать другу

Tags:, , ,
Subject:ГУЙ!
Time:11:37 am
Почему я принципиальный противник написания GUI-кода руками? Да потому, что это идиотизм: это сущностно противоречит самой идее гуя как такового. Все знают, насколько отвратительной порой бывает такая отвратительная каша GUI-кода и функционального кода, особенно когда возникает необходимость вычленить функциональный код из приложения на какой-нибудь древней платформе. Но! В системах RAD, оборудованных автоматической генерацией гуи-кода типа Дельфи/Билдер этот недостаток хотя бы консистентен (аналоги мне неизвестны, и не уверен, насколько нынче зелена трава на майкрософтовской лужайке). Код гуя генерируют роботы, а мы им просто поклоняемся. То есть знаем типичные недостатки, где их искать и как их лечить. Когда же код гуя пишет вручную человек на том же gtk, результат в каждом конкретном случае непредсказуем. Фактически, ничего не изменилось со времён печально знаменитой закусочной Steve Balmer's MFC's - я не вижу никаких качественных отличий кодинга на тех же ГТК или Qt. Только количественные: на порядок меньше гемора, -//- проще, -//- красивее, -//- функциональнее.
comments: 5 комментариев or Оставить комментарий в избранное рассказать другу

Реклама

[icon] наивный идеализм
View:Свежие записи.
View:Архив.
View:Друзья.
View:Личная информация.
View:Website (http://dervish-candela.deviantart.com/).
You're looking at the latest 9 entries.