Semantic locality
Mar. 15th, 2017 09:37 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
http://esr.ibiblio.org/?p=7421
Раймонд умный пост написал по поводу концепций, которые лежат под Unix way. Я эту мысль про семантическую локальность три дня думать буду.
Раймонд умный пост написал по поводу концепций, которые лежат под Unix way. Я эту мысль про семантическую локальность три дня думать буду.
no subject
Date: 2017-03-16 08:07 am (UTC)Правда на практике делать экспорт-импорт данных из монолитной системы в виде потоков данных с семантической локальностью как правило лень и нет времени. Я даже сейчас подумал, что это основная проблема с юникс-вэйностью systemd, который там сразу начали обсуждать в комменариях.
no subject
Date: 2017-03-16 09:29 am (UTC)а) наша работа семантически локальна
б) может выполняться над потоком данных
Вообще, лично у меня к классическому unix-way-pipes есть масса претензий, основная, это отсутствие типизации. Все эти бесконечные awk -F '-' '{print $1" "$2"}' - это восстановление типов по косвенным признакам.
В современном серверном софте есть некотоая благая подвижка, в которой cli ко всякому сложному софту выводят данные в json. Всё то же самое, но уже с минимальной структурой, так, что не нужно тратить специальные усилия на обработку специальных случаев (пробелы в именах, "неправильные" символы и т.д.). Вместе с jq и другими видами query languages это очень удобно.
Революция произойдёт в тот момент, когда GNU научится хоть какой-то структуре в выводе программ.
Условно говоря, получение ip-адреса для eth3 будет выглядеть так:
ip -j a l|jq .eth3.ipv4.address[0]
.Второй больной вопрос: это error stream. У нас есть софт для работы с stdout/stdin, а stderr - полностью на откуп человеку. Всего машиночитаемого в обработке ошибок - единственный int, который относится не к куску данных, а ко всей программе. Для stderr нет никаких методов обработки - оно "human readable".
no subject
Date: 2017-03-16 10:23 am (UTC)Это здорово, но проблема в том, что это не универсально. К примеру, понадобились в структуре данных циклы - выход только в том, что бы сделать несколько команд-запросов разных видов данных, либо в том, что бы использовать более сложную структуру, типа YAML. Захотелось структуры более ориентированной на вывод (например, с названиями элементов в определённом порядке) - придётся использовать XML. А ведь сейчас в 2017 году, несмотря на то что все упомянутые форматы существуют много лет, до сих пор у людей большие проблемы, что бы распарсить даже одиночные сообщения в данных форматах. Не говоря уже о том, что потоковая передача заранее неизвестного количества сообщений в этих форматах определена только для YAML.
no subject
Date: 2017-03-16 10:32 am (UTC)Отсутствие универсального решения, которое бы покорило всех - да, печалит. Но, с другой стороны, отсутствие решения печалит ещё больше.
Ситуация с пайпами и данными в них напоминает компьютеры первых поколений, когда ещё не были придуманы типы данных. Вот тебе память, вот тебе адрес, вот тебе инструкция "читать из памяти", делай что хочешь. До момента более-менее приличных структур данных в языках несколько поколений языков сменилось.
no subject
Date: 2017-03-16 10:46 am (UTC)Во-первых, JSON предполагает, что мы в любой момент можем набрести на поддерево любого масштаба, а значит, "рабочее окно" в любой момент может неограниченно раздуться.
Во-вторых, JSON имеет отягощённую наследственность: у него в нутре гены JS, не предполагающего упорядоченность где-либо, кроме массивов, соответственно, любой обработчик имеет право переставлять ключи местами как попало, и читателю опять же придётся считать их все, прежде чем что-то обработать.
Чтобы обрабатывать это всё потоком - придётся много дополнительных ограничений на JSON наложить. В старом добром же Юниксе, можно было в большинстве случаев говорить о локальности, пока нам кто-нибудь гарантирует ограниченность длинны строки (в смысле line, а не string)
no subject
Date: 2017-03-16 10:53 am (UTC)Но потоковые парсеры при этом всё-таки есть. Собственно, в любом потоковом протоколе нам могут подсунуть объект больше нашего буффера размером. Например, строку длиной в гигабайт во внутрь авка. Как только мы эти данные начинаем считать не потоком байтов (для которых локальность 1) или потоком чего-то простого (4 байтовых последовательностей), так тут же локальность начинает становиться величиной условной.
Хотя в том же json'е, например, задача "извлечь 100 Гб значение по ключу из 10000 Гб json'а" вполне решается. Мы просто вешаем обработчик на чтение значения, которое выдаёт значение на stdout по мере чтения, а всё остальное пропускаем. Если у нас при этом нет превышения по размеру ключа (очевидно, что мы не можем найти что-то по ключу, который больше нашей оперативной памяти, т.к. не сможем его передать как параметр программы), то это вполне рабочее.
Я баловался с потоковыми парсерами json'ов, на удивление, это вещь и она может существовать в константной памяти при неконстантных входных данных.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2017-03-16 10:50 am (UTC)К примеру, если бы g++ выплёвывал stderr в каком-то структурированном формате, то возможно, было бы проще копаться в template vomit.
Но с другой стороны, благодаря принципу семантической локальности также оказалось возможным реализовать функционал, связанный с командой make в vim - благодаря давнему соглашению о текстовом формате имя_файла:строка:столбец: (make не знает в каком точно формате идёт вывод ошибок). Если каждый раз придумывать свой формат, то взаимодействующие программы будут вынуждены менять код для разбора вывода.
no subject
Date: 2017-03-16 10:58 am (UTC)Этот протокол неконсистентный, ибо он не сможет показать ошибку в файле "пример ошибки в файле:33:44" на строке 2 и столбце 4.
И вот эта неконсистентность между соглашениями (нам обещают stateless-separator, выдавая либо что-то без эскейпинга, либо с ложными срабатываниями) и превращает шелл-пайпы из няшки в ад и некомфортность.
Собственно, что там далеко говорить. Из свежего: systemd положил файлик "-" - и всё, миллион вопросов о том, почему ls ломается.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2017-03-16 10:23 am (UTC)Скорее, если я правильно вас понял, будет что-то вроде:
SomeInterpreter.exe /eval "import System; WriteLn( System.getNetworkStackInterface('eth3').getAddress( System.Network.NET_IPV4 ) )"
Утилиты для этого не нужны. :)
no subject
Date: 2017-03-16 10:41 am (UTC)no subject
Date: 2017-03-16 10:38 am (UTC)В принципе, Unix Way не противоречит тому, чтобы собрать сложную ветвящуюся и сходящуюся структуру обработчиков потоков, и даже с типами данных (шеллу это всё уже не по зубам). Но как только у нас случится первая исключительная ситуация где-то в глубинах конвейера - тут уже ой, всё.
no subject
Date: 2017-03-16 11:08 am (UTC)no subject
Date: 2017-03-16 07:23 pm (UTC)На этом месте мне вспомнился чудовищных размеров флейм с КЫВТа, где люди (в том числе те, кто компиляторы пишут, а не энтерпрайз какой) спорили о сравнительном удобстве и производительности между передачей кодов ошибок, как в Golang и исключениями, как много где. В теории, исключения лучше, если они реализованы правильно, и особенно они хороши в случае вызовов с в 40 уровнями вложенности в стеке, когда программист попросту устанет передавать ошибку наверх руками.
В типичном же unixway вряд ли можно встретить цепочку, где вызывалось бы больше 5 утилит. Вдобавок, нет никакого механизма "исключений", которые летали бы между процессами (и слава богу, наверное).
Чего нет в типичных пайпах - так это общепринятых границ сообщений. Даже для потоковых данных может появиться смысл в передаче данных некими кусками, chunk'ами. В виндовых named pipes есть механизм передачи отдельных сообщений, в юниксах же, насколько мне известно, подобное есть только в d-bus. Самостоятельно сделать разбивку на сообщения несложно, но - каждый раз это все равно нужно делать, и всякий будет делать это по-своему.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2017-03-16 07:16 pm (UTC)Все попытки сделать "шелл лучше чем bourne shell" сводились к тому, чтобы напихать в скриптовый язык более низкоуровневых конструкций - объектов, методов, массивов.
А надо было идти в противоположном направлении - к более человеческому языку, системе общих контекстов и умолчаний, которые естественным образом выстраиваются в процессе диалога.
no subject
Date: 2017-03-17 04:56 am (UTC)Проблема в том, что люди вообще не понимают, что bash - это язык со встроенной ленивостью, с офигительной параллельностью (& явно легче написать даже чем Хаскеллевский par, а в ленивом вызове | вообще всё по-умолчанию выполняется параллельно). Ну и когда пытаются заменить bash питоном всё "немного предсказуемо".
------------------------
И, конечно, это правда насчёт общих контекстов и умолчаний. Я не хочу писать кавычки у каждого строкового параметра ls, не хочу писать .0 у каждого float'а, хочу сразу иметь неограниченные целые числа и любую точность вещественных.
С другой стороны, нужно, всё-таки, иметь определённую строгость. Хотя бы в скриптах. Возможно, тут должно быть разделение - в интерактивном shell мы можем быть более вольны, а в скриптовом - более строги.
Т.е. сделать язык, который имеет несколько режимов: мягкий, когда это почти Питон по раздолбайству и жёсткий, когда это ML (вернее Хаскель). Так, чтобы когда мы пишем скрипт на 1 раз, можно было допускать ошибки, а когда это часть системы запуска, проверки были дай боже.
(no subject)
From:b и p
From:Башизм не пройдет
From:Баш на dash
From:Re: Баш на dash
From:(no subject)
From:(no subject)
From:no subject
Date: 2017-03-16 07:13 pm (UTC)Вы тут идете совершенно неправильным путем. На этом уровне работы типизация - зло. Тут нужны на не типизация а понимание программами контекста, аналогичное таковому у человека. Потому что все эти утилиты предназначены в первую очередь для генерации человекочитаемого вывода и обработки человеконаписанного ввода.
Основная идея unix-way в том, что человек участвует в диалоге утилит как равноправная сторона. Он может себя поставить на место любого фильтра и почитать глазами выходной поток, он может руками с клавиатуры понабирать входной поток.
Именно это обеспечило unix такую долгую жизнь и широкую популярность. Полное отсутствие барьера между интерактивной работой и программированием.
Соответственно, если мы хотим это улучшить, создать более удобную для пользователя систему, то нужно стремиться не к более структурированному вводу-выводу, характерному для более низкоуровневых средств, а к менее структурированному и более контекстно-зависимому, характерному для общения людей между собой.
no subject
Date: 2017-03-16 07:28 pm (UTC)И если сравнивать количество данных, переданных по нетипизированному unixway и по стандартизированному HTTP - НTTP выиграет в тысячи раз.
no subject
Date: 2017-03-16 08:31 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2017-03-17 06:30 am (UTC)Unix тоже создавался именно для этого. А потом оказался востребован компаниями. Поскольку у них тоже задачи нестандартные и инструменты с помощью которых не слишком обученные пользователи могут легко эти задачи решать, востребованы. А что тормозят, это пофиг, мы еще сто серверов купим, это дешевле, чем одного разрабочтика нанять.
no subject
Date: 2017-03-17 04:41 am (UTC)К сожалению, как вам там уже сказали, это не универсально. Unix cli - это полуавтомат, который может работать с ошибками. Строгая типизация - это штука, которая по определению работает без ошибков. А так, конечно, Haskell смог бы заменить bash.
> Всего машиночитаемого в обработке ошибок - единственный int, который относится не к куску данных, а ко всей программе.
Это было изящно решено товарищами из Digital в их операционных системах. В последней - OpenVMS оно выглядит так:
$ HELP/MESSAGE/LIBRARY=TOOLS:[MYPROJ]MYMESSAGES.MSGHLP$DATA ACCVIO
%MSGHLP-F-MDFERR, error accessing Help Message database file "TOOLS:[MYPROJ]
MYMESSAGES.MSGHLP$DATA"
-RMS-E-FNF, file not found
-SYSTEM-W-NOSUCHFILE, no such file
Ошибки - это строки с процентами и "-" в выводе. Т.е. сначала даётся машино-человеко-читаемый код %MSGHLP-F-MDFERR (подсистема-серьёзность-ошибка), после которого идёт нормальное описание.
no subject
Date: 2017-03-17 01:11 pm (UTC)Ага, и место на диске у неё не кончается, и в сети ни единого разрыва, и пользователь ересь не вводит...
no subject
Date: 2017-03-17 05:58 pm (UTC)Хотя на практике, конечно, в итоге все равно исключения. Но типизированные. Но типы всех возможных исключений детально не документированы. Но если подходить с умом, то пользоваться можно.
(no subject)
From:(no subject)
From:no subject
Date: 2017-03-17 09:12 am (UTC)Но Эрик не зря вспомнил ed! В нём есть такая замечательная команда s///, которая эту вашу локальность ломает напрочь (но, возможно, сохраняет какую-то другую, более общую?). Если этой командой пользоваться совсем грубо, могут прийти энциклонги. Если слегка поаккуратнее (хотя бы ввести понятие слов и разделителей), то уже чуть лучше: darcs вроде бы умеет понимать это как патч (и правильно сочетать с другими патчами). Но вот в языках программирования есть области действия имён. И тут уж либо IDE, которая при эти области знает (вместо набора отдельных утилит для отдельных задач), либо... я не знаю, что "либо". А ты?
... Живущий, пока не исчезнут машины ...
no subject
Date: 2017-03-17 10:52 am (UTC)no subject
Date: 2017-03-19 05:54 pm (UTC)https://www.microsoft.com/web
Если исправят, то смотреть сюда: http://pikabu.ru/story/kak_zhe_ya_lyublyu_isklyucheniya_4901079