Как стать автором
Обновить

Комментарии 38

А чем обусловлен выбор Haskell для написания, собственно, визуализатора? Почему не какой-нибудь промышленный язык?
В последнее время я все больше и больше нахожу Haskell удобным для почти любого типа задач. Если бы визуализацию писал на другом языке, у меня бы спрашивали, почему не на Haskell. На самом деле, писать и отлаживать легко. Нелегко только продумать логику. Рефакторинг в Haskell — дело местами даже приятное, чего не скажешь о том же С++. Статическая типизация помогает в этом: если где-то изменил тип выражения, компилятор скажет, какой участок кода нужно подогнать. Исправляешь, — и всё начинает работать ожидаемым образом.
А можно узнать критерии, по которым вы относите Haskell к «непромышленным» языкам?
Чтобы его можно было визуализировать самим собой?
НЛО прилетело и опубликовало эту надпись здесь
> Коллега, а что если образцы и охранные выражения визуализировать как фильтры в стенах?
Почему бы и нет. Надо только помнить, что булевое охранное выражение может быть сколь угодно большим, и для «сути охраны» должно быть достаточно места. Это же касается и сопоставления с образцом. Есть ли у вас возможность набросать эскиз?

Генераторы списков можно разобрать на части:

[(x, y) | x < — xs, y < — ys, x `elem` someList, not. empty $ y]

Шаблон возвращаемого значения(x, y)
Обязательный символ|
Источники значенийx < — xs, y < — ys
Охранные выраженияx `elem` someList, not. empty $ y


Шаблон визуализируется как обычное выражение. Затем можно поставить вместо вертикальной черты, например, рамку или два столба. Источники значений и охранные выражения — это вертикальные конструкции, идущие подряд. Источники — это выражение наверху (xs), затем натуральная (не текст, а блоки) стрелка вниз, а внизу — блок целевого значения (x). Охранные выражения почти также, только вместо стрелки — горизонтально расположенная рамка с дыркой. Как приду домой, набросаю концепт.
НЛО прилетело и опубликовало эту надпись здесь
Ну, сахарок-то он, конечно, сахарок… А сам do, в свою очередь, сахарок для оператора >>= и лямбд… И при визуализации мы могли бы свести все это к одному и тому же виду. Однако было бы полезно все-таки для генераторов создать индивидуальный дизайн. Конечно, некоторые конструкции будут совпадать, — на то и эквивалентность этих конструкций дана. Но если рассахаривать генератор списков, люди, сравнивая код и визуализацию, будут недоумевать. Впрочем, тут есть над чем поразмыслить.
НЛО прилетело и опубликовало эту надпись здесь
Про три измерения вы верно заметили. Для эффективного использования пространства нужно придумать хорошие конструкции, что у меня как-то не выходило. Тут еще появляется проблемка: растущие вверх и вширь блоки закрывают другую часть сцены. Приходится пока балансировать.
НЛО прилетело и опубликовало эту надпись здесь
Идея замечательная! Про гиперссылки я и не думал.

Хммм, а что если сделать не только гипессылки на нужную функцию, но и на визуализированную документацию?
НЛО прилетело и опубликовало эту надпись здесь
Пока не знаю, надо бы выяснить…
Визуализация штука сложная, конечно.
Функция — это преобразователь из одного типа данных в другой, и тогда значения одного типа должны выглядеть одинаково (но разные типы — по-разному).
А guard — это фильтр значений, т.е. пропускает определённые значения и не пропускает другие, тогда его форма должна зависеть от самого значения.

Ну, например.
length — тоннель с треугольным входом и квадратным выходом. Входит любой длины треугольная призма, выходит параллепипед. Причём в поперечной оси отражается тип (треугольник — список, квадрат — число) а в продольной — значение.
length xs == 0 — guard, который сначала пропускает значение вперёд через length, меняя его тип, а затем поперёк через тоннель, способный пропустить только 0.

Список, правда, продвинутый пример, так как он полиморфный.

Интересно было бы подумать, не пригодится ли при визуализации математическая запись типов:
list(A) = 1 + A * list(A)
bool = 2
nat = 1 + nat

В общем, полезного я мало сказал, но может хоть идей на размышление подкинул.
Мысли интересные и правильные, наталкивают на другие мысли.

Действительно, если функция преобразовывает данные, то ее логично представить трубой-туннелем. Проблема с типами в том, что их много, а сечений туннеля — мало. Как показать очень-очень сложный тип вроде

data StructureObject = StructureObject
        { soObjectSpec       :: ObjectSpec
        , soGeometry         :: Geometry
        , soGraphObjectSpec  :: GraphObjectSpec
        , soStructureObjects :: StructureObjects
        } deriving (Show)

?

А вот для декларации типов туннели, может, и подойдут. В любом случае, надо рисовать эскизы сначала. :)
Именованный тип от кортежа ничем структурно не отличается, т.е. в данном случае достаточно взять 4 фигурки подтипов и соединить их как удобнее.

Вообще говоря если брать мат.запись, то имеются кортеж (product) (A x B), т.е. оба значения, и coproduct (A + B), т.е. одно из значений (Either). Для типов с фиксированным кол-вом значений используют число. Т.е. например Bool — это 2.

Пример:
Список — голова или хвост, содержащий элемент и список
list(A) = 1 + A x list(A)

Maybe:
maybe(A) = 1 + A

Изобразить кортеж, в общем-то, несложно. А вот по поводу coproduct и аналогов Bool надо думать.
Может, набросаете по-быстрому пару эскизов?
Прямо сейчас времени нет, могу попробовать на выходных набросать.
НЛО прилетело и опубликовало эту надпись здесь
Вот, набросал я таки эскиз генераторов:

image
НЛО прилетело и опубликовало эту надпись здесь
Рамка? Охранное выражение. Но тут спорный момент, я долго над ним размышлял.

Сбоку — это где?
НЛО прилетело и опубликовало эту надпись здесь
Поддержу предложение подумать о возможном смещении отображения от прямого повторения синтаксиса к отображению смысла.
Предложу вариант:
_X_Y_ [ тут охранное выражение ] X<-XS, Y<-YS
Охранное выражение похоже на фильтр. Его можно отобразить в виде «коробки», которая будет иметь квадратное отверстие со стороны x<-xs, т.е. на входе, а сто стороны выхода будет иметь фигурное отверстие. Получится что-то, вроде «из всех xs пролезут только подходящие».
НЛО прилетело и опубликовало эту надпись здесь
Тоже думал над вертикальном расположении «исходников», но охрана может не только X охранять, но и Y вместе с ним. Правда, такую комплексную охрану можно уже после объединяющей скобки поставить.
НЛО прилетело и опубликовало эту надпись здесь
                xs           ys
                  |             |
                 V           V
_x_y_ <- [ x "==" y ]

(Тут у меня что-то типа стрелок сверху вниз, надеюсь, понятно будет)
image
НЛО прилетело и опубликовало эту надпись здесь
Вот так?

image
НЛО прилетело и опубликовало эту надпись здесь
Если пространство, в котором располагаются объекты, изначально координатное, то скорее всего оно станет сильно разреженным по мере отрисовки кода, а если ему наложить структуру, в самом простом случае задать ячейки для размещения, то оно станет более компактным, а если структуру пространства менять в зависимости от родителя, то компактность еще повысится. Но здесь дерево собирается с нижних уровней, и в связи с этим
задать ограничения с верхний уровней для нижних не представляется возможным. Просто возможно возникнут в связи с этим неудобства, например я захотел бы вписать сцену в другой графический проект, с заранее известными ограничениями и на размер и на компактность.
p.s.
«Как мы знаем, процесс, при котором один язык преобразовывается в другой, называется компиляцией» — мне кажется больше подходит термин «трансляция»
Вряд ли возможно строить дерево сверху вниз. Я рисовал и обычные деревья — AVL — там тоже если не знать, сколько места нужно листьям, верхушку не нарисуешь. Для AVL-дерева можно построить формулу, которая будет расчитывать место для любого уровня, поскольку это фукнкция от количества элементов и от номера уровня. Для кода такую формулу не выведешь. Как понять, не будет ли мало пространства 100x100x100 клеток? Если только продвинутым анализом каким-нибудь…
Во первых, дочерние элементы в процессе их размещения могут заглянуть к родителю и спросить его: «в чем ты мне предлагаешь отрисоваться (какую ты задаешь структуру пространства)?» вопрос будет не сколько ты мне конкретно предлагаешь места, а относительное место в этом пространстве, во вторых, а кто не использует несколько проходов по дереву для оптимизации построения деревьев в пространстве, если во главу угла ставится компактность. Я думаю этим не стоит брезговать сильно.
Может быть и так, но я не уверен. К тому же для компактизации нужно язык продумать еще сильнее, а может быть даже изменить совсем: чтобы элементы и выразительны были, и могли бы разместиться с оптимальной плотностью.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации