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

Язык K: Отображение графического интерфейса из данных

Время на прочтение4 мин
Количество просмотров8.8K
Я как всегда об APL, а точнее о старой версии языка K, которая содержала в себе GUI, с весьма необычным подходом к нему.

К сожалению новые версии языка K решили сосредоточиться только на обработке данных и исключили GUI, так что данный подход остался в истории, однако может быть кто-то подскажет аналогичные современные фреймворки — было бы очень интересно посмотреть.

Начнём. Краткое описание API, которое нам доступно:
`show$`v        show variable v
`hide$`v        hide variable v

Это всё, больше нет ничего. Т.е. основная особенность — что GUI в K это прямое отображение данных в памяти. А теперь как с этим можно удобно работать.

Для начала попробуем самое простое:
C:\>k
K 3.1 2004-01-28 Copyright (C) 1993-2004 Kx Systems
WIN32 2CPU 4030MB ws-1341.x.com 0 EVAL
  a:10 _draw 100    / vec
  a
20 51 12 34 31 51 29 35 17 89
  `show$`a

На экране появляется таблица со списком

Любое значение редактируемое, меняем 35 на 135 и это изменение сразу меняет значение в списке:
  a
20 51 12 34 31 51 29 135 17 89

Если меняем значение в списке, то оно тутже обновляется в интерфейсе.

Вывести небольшой список не проблема, а что если данных будет много? пусть будет очень много:
  a:(10 10000000) _draw 100   / 10 списков по 10 миллионов каждый
  `show$`a


Никаких проблем — всё быстро отображается, прокручивается и редактируется.

Именуем колонки: логично что имя колонки — это ключ, а список — значение из hashtable:
  t:.((`a;10 _draw 100;);(`b;10 _draw 100))
  `show$`t



Но это всё очень просто, смотрим что есть ещё. аттрибуты и триггеры — по сути это просто ключ-значение в hashtable, привязанном к переменной, в зависимости от того есть такое значение или нет — происходят разные действия:

Самый простой пример: добавление label.
  val:10
  val..l:"Input field"
  `show$`val



Следующие аттрибуты влияют на отображение в gui:
 Display attributes (for variables that have class).
  x     width           integer(KFONT width)
  y     height          integer(KFONT height)
  a     arrangement     nest of symbols(class `form)
  o     options         list of symbols(class `radio)
  l     label           string
  kl    click label     string (also klr)

  Data-display attributes (for variables that have class `data).
  functions (monadic, constant or array)        default
   e    editable        0 or 1                   1
   f    format          string from data         11$(11.2$)
   g    getdata         data from string         0$ etc.
   u    update          update[old;new]          :
   fg   foreground      integer(rrggbb)          0
   bg   background      integer(rrggbb)         -1(808080)

  expressions/events (strings)
   ins, del, f1 ... f12, ctrl_a ... ctrl_z
   k, kr, kk    click, click right, double click(precludes e)

   c      class(display)  symbol
        `data(default) atom, list, dict, list of lists, dict of lists
        `chart          as above where atom is list of y values
        `plot           as above where atom is matrix of (x;y) values
        `check         0 or 1
        `radio         symbol (one of ..o; see below)
        `button        expression or dictionary of expressions
        `form          dictionary of entries of any class(incl. `form)

Не буду описывать детальные особенности каждого из аттрибутов, так как большинство из них очевидны из описания и делать подобие мануала не хочется.

Для простоты создания словаря — язык позволяет работать в контексте внутри словаря — т.е. аналогия с папками и модулями, которые просто хэш-таблицы:
  \d form
  val:100
  incr:"val+:1"
  incr..l:"Increment"
  decr:"val-:1"
  decr..l:"Decrement"
  incr..c: decr..c: `button
  \d ^
  form / хэш ключей-значений и хэшей аттрибутов.
.((`val;100;)
  (`incr
   "val+:1"
   .((`l;"Increment";)
     (`c;`button;)))
  (`decr
   "val-:1"
   .((`l;"Decrement";)
     (`c;`button;))))


Аттрибутом ..a установим порядок отображения.
  form..a:`incr`val`decr
  form.val..e:0    / отключаем редактирование значения.



..a может быть любой формы. Например добавим пару кнопок.
  form.incr10:"val+:10"
  form.decr10:"val-:10"
  form.incr10..c : form.decr10..c: `button
  form..a:(,`incr;`decr10`val`incr10;,`decr)
  form..a
(,`incr
 `decr10 `val `incr10
 ,`decr)



Т.е. смысл в том, что всё GUI описывается примитивными структурами языка и является их же прямым отображением. Можно включать hash в hash, т.е. включать форму в форму компонуя элементы и тд.

Ну а теперь самое интересное, а именно несколько примеров:

Калькулятор:
calc..a:(`exp
   `va`vb`vc`vd
   `n0`n1`n2`n3
   `n4`n5`n6`n7
   `n8`n9`lp`rp
   `fa`fs`fm`fd`fe
   `eval`clear) / порядок элементов на форме
calc:@[_n;1_-1_ calc..a;:[;"exp,:(~_v)`l"]]	/ expressions
calc[.;`l]:"abcd0123456789()+-*%:"		/ labels
calc.eval:"exp:5:. exp"
calc.clear:"exp:\"\""
calc[.;`c]:`button
calc.exp:calc.exp..l:""

`show$`calc



Можно рисовать графики:
  p..c:`chart
  p:(5 5) _draw 100
  `show$`p



Или высокохудожественная мазня:
`show$.,((`p;({[x] (2 30)_draw 30}'!10);.,(`c;`plot;)))



А теперь удивительная вещь, которая когда-то так удивила своей краткостью и понятностью (при минимальном знании словаря конечно), что я решил начать изучать K глубже:

Broadcast сервер:
d:10 _draw 10

w:!0		/ empty client list

.m.g:{w,:_w;d}	/ return data
.m.c:"w@:&~w=_w"	/ retain clients
.m.s:{. x;w 3:\:x;}	/ (log `l 5:,x) apply and broadcast

\m i 1     listen on port 1

Клиент:
h:3:(`;1)	/ connect to server
d:h 4:_n	/ get database
d..t:"if[0=_w;h 3:(_v;_i;:;_v ._i)]"	/ send my updates

`show$`d

Вот эти несколько строчек создают сервер с простым списком в качестве данных. А сколько угодно клиентов присоединяются к нему и имеют совместно редактируемый список с обновление в реальном времени, всего 9 строчек. Подобный код (без GUI конечно) в настоящее время используется на многих крупнейших биржах для транспортных и балансировочных узлов, которые обслуживают инстансы баз данных Q (новая версия K).

Картинка конечно не передаёт того как это работает в динамике.

Теги:
Хабы:
+30
Комментарии6

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн