Category: философия

Category was added automatically. Read all entries about "философия".

404

abstraction build-up

Есть два подхода к построению абстракции высшего порядка: борьба с нижележащими слоями и логическое обобщение.

Логическое обобщение - это то, что любят делать математики. Взяли операции над матрицами, операциями по модулю и комплексными числами, посмотрели, что между ними общего, ррраз, и у нас группы, кольца, поля и т.д. Это такой святой грааль любой компьютерной технологии, когда из объектов нижележащего характера берётся всё общее и из них делается объект вышестоящего характера. Так задуман, например, tcp, который из любого ненадёжного пакетного протокола нижележащего уровня может изготовить что-то, что похоже на конфетку "ГОСТ-1921-ТИПА-СОЙДЁТ-ЗА-КОНФЕТКУ".

Но на практике, часто, вместо абстракции как обобщения, мы получаем "абстракцию, как подавление". Для реализации идеи "foo" (которая существует до обнаружения реализации) ищутся реализации, которые хотя бы отдалённо напоминают нужное. Дальше реализуется слой, который с помощью хаков, баша и какой-то матери (то самое "говно, палки и  intellectual property") слепливается что-то, похожее по свойствам на то, что нужно нашей новой абстракции.

Которая, на самом деле не абстракция, а чужеродное явление, едва прилепившееся сбоку (в онотологическом смысле). Одиночное изнасилование онтологическое дерево может выдержать. Проблемы начинаются тогда, когда получившееся снова становится жертвой "приделать под нужду", т.е. у нас получается "прилепившееся сбоку от прилепившегося сбоку". Чем больше таких слоёв незвучных абстракций образуется, тем больше нижележащие слои "сопротивляются", по факту обнажая неожиданные свойства, протекающие абстракции, неожиданные (по модели) ограничения и, чаще всего, кошмарный оверхед в производительности.

Можно было бы сказать, что "делайте хорошие абстракции и не лепите шути что из шути чего", но бывает так, что получающаяся абстракция (как обобщение свойств) никому не нужна, а нужно совсем другое. Желательно в разумное время, иначе ничего не заработает.
404

Поток сознания: энтропия в коде

Предварительные тезисы:

1. Понятие энтропии кода. 

Чем более хорошо написан код (вне зависимости от того, по каким метрикам определяется «хорошесть»), тем меньше его энтропия. Причина проста — для каждого «хорошего» состояния есть множество модификаций, которые его ухудшают, но весьма ограниченное количество модификаций, которые его улучшают.  Пространство всех возможных значений для «плохого» кода очевидно выше, чем для хорошего. Таким образом, энтропия у хорошего кода низкая. Можно даже тем же рассуждением показать, что у идеального кода самая низкая энтропия — из идеального кода путь только в более плохой, улучшать уже нечего. Даже если идеальных состояний несколько, переход между ними не делает ситуацию лучше (каждый — идеальный), а вот отклонение от идеала — делает, и таких возможных отклонений больше, чем переходов между идеалами.

(промежуточный тезис — хороший код имеет низкую энтропию)

2. Понятие полезности кода.


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

Collapse )
404

пример квадратно-гнездовой деоптимизации

Самым интересным примером деоптимизации во имя упрощения я считаю отсутствие регистров в модели памяти практически всех языков программирования. Даже самые упоротые на производительности языки не хотят притаскивать в модель памяти регистры. Оптимизатор может их использовать (и использует!), но на уровне абстракции их нет. Если их принести в язык, наверное, есть моменты, когда можно будет сделать тоньшее и точнее. Изящнее.

Но нет. Мы выжигаем всю изящность и оставляем квадратно-гнездовое "все непустые переменные в памяти у всех объектов в памяти есть адрес" (я про условный C/Rust).

Этот переход - пример сильной абстракции, которая скрывает детали реализации. При том, что с низкоуровневой точки зрения язык пушит невероятное количество policy, с высокоуровневой язык почти целиком состоит из tool.

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

Посмотрите на все великие абстракции окружающего мира - файлы, tcp, переменные... Каждая из них выжигает за собой всё. И каждая из них велика. И посмотрите на анти-паттерны. Делает ли cron описание "выполнить по таймеру" проще? Делает ли Makefile хоть что-то проще?
404

и ещё рефакторинг

Важный milestone: getPath сократилась до 100 строк, а всё это покрыто 60+ тестами. Надо бы больше, но некоторые кейсы я просто не могу нормально написать без софтмоков, а их ещё делать. (О чём речь: я не могу использовать untitest.mock, потому что это python2, и не могу использовать mock, потому что ограничения проекта). Мне предложили делать тесты, которые skip, если нет модуля mock, но эту штуку ещё отдельно писать надо.

На горизонте строки 425-994, которые представляют из себя остаток getSVG (из которой я, собственно, getPath и несколько других функций и вытащил). Да-да, добрая такая функция на 500+ строк, которая всё ещё делает Почти Всё.

В целом, я ощущаю, что оно чуть-чуть из рук выскользает, потому что в новом коде довольно много тестами не покрыто, но хочется дальше деребанить getPath. Но надо-таки покрывать то, что уже надёргано. Цикломатическая сложность понизилась, и самое-самое время начинать заморачиваться с тестами всяких corner case'ов, потому что в них как раз баги и обитаются...

Вот, например, из вытащенного:

def toSpline(edge):
    bspline = edge.Curve.toBSpline(edge.FirstParameter, edge.LastParameter)
    if bspline.Degree > 3 or bspline.isRational():
        try:
            bspline = bspline.approximateBSpline(0.05, 50, 3, 'C0')
        except RuntimeError:
            print("Debug: unable to approximate bspline")
    return bspline


Мне нужны тесты на:
1) кривые с Degree > 3
2) isRational (насколько я понимаю, это кривая Безье, описывающаяся полиномом с дробной степенью)
3) На ситуацию, что кривую не аппроксимировать.

Понятно, что моки спасут отца русской демократии, но мне хотелось бы записать в тесты всё-таки настоящий результат - с такой самой кривой, у которой такие загогулины.
404

unix way

Идея: утилита делает одну вещь, но делает её хорошо.

Что значит "хорошо"? Что нам не надо прикладывать специальных усилий для борьбы с этой вещью ради того, что она делает. Утрируя: мне нужно запаковать файл, я делаю |gzip, а выходе имею запакованный файл. Утилита чуть-чуть присыпана опциями по вкусу, но сама идея от этого не меняется - на входе данные, на выходе архив.

С учётом, что паковка - математическая операция (чистая), ошибки от gzip мы можем получить только если у нас в системе что-то плохо (ENOMEM), либо что-то плохо "до/после" в пайпе. И нас это полностью устраивает, потому что gzip в режиме паковки не может генерировать ошибок, ассоциированных с входными данными. Мы можем смело полагать, что gzip нам не добавит сложности в обработке ошибок - ошибка либо системная (фатальная), либо на входе/выходе. Если мы считаем вход/выход тоже системными (cat, редирект), то ошибки становятся системными все. Нам достаточно увидеть ненулевой код возврата, чтобы знать, что "была системная ошибка и операция не удалась". Более того, за вычетом мелкого нюанса с ENOSPACE (где-то дальше по пайпу), мы можем считать, что операция транзакционная - либо сработало и запаковало, либо нет. То есть gzip в режиме паковки нам не добавляет головной боли. Берёшь и используешь. Идеальная утилита.

А теперь смотрим на распаковку. Что должен делать gzip при фигне на входе? "not in gzip format", errno = 1, " Operation not permitted". Эта ошибка крайне отличается от enomem, либо ошибок чтения/записи из/в stdin/out. У нас появляется ошибка пользовательских данных. На одной и той же машине в тех же самых условиях с одним файлом всё отработает, а с другим нет.

Получается, что у нас есть два разных типа ошибок, которые мы должны обработать: системные ошибки (ENOMEM, broken pipe), и ошибки обработки данных (not in gzip format).

Мы можем начать играться с set -o pipefail, но мы всё равно не можем обработать эту ошибку отдельно. Мы получаем в пайпа код 1, и даже не знаем, кто его выставил без чтения stderr.

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

Опытный админ знает мерзкий хак:

set -o pipefail
cat /proc/cpuinfo |sort|(gzip -d || exit 33) |sort|wc -l
echo $?
33

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

Если мы хотим иметь разное поведение для системной ошибки и пользовательских данных, то инструмент 'bash pipe' уже не работает. Более того, к gzip, внезапно, вопросы, потому что он возвращает 1 на системные ошибки и на ошибки пользовательского ввода.

И возникает вопрос: можно ли считать unix-way'ным использование gzip -d? Делает ли он "одну вещь, но делает её хорошо"?
404

Философия

Философия - это хардкорная научная фантастика, из которой вытерли персонажей, экшен и фантастические допущения.

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

Пример современной философии: http://www.scottaaronson.com/papers/philos.pdf (Why Philosophers Should Care About Computational Complexity) (я уже постил эту ссылку если что)

И оно офигенно для чтения. Потому что поднимаемые там вопросы близки к уровню лучшей части футуримзма из фантастики образца Райта, Бенкси и Винджа.
404

Балансируя на грани философии и хардкорной практики

Традиционно, один из срачиков в философии крутится вокруг взаимного влияния семантики и синтаксиса. Мол, до какой степени синтаксис влияет на семантику и как семантика может определять допустимое для синтаксиса.

Но, пардон!

Семантика - это такая абстрактная фигня про смысл, значение и проблемы объективного и субъективного знания - короче, удел философов, некая аморфная и плохо определённая штука без практической реализации.

А вот синтаксис - это же суровая state-машина, LR-parser, deterministic context-free language, регэкспы. Ну, короче, та штука, которая выдаёт SyntaxError если написана неразборчивая фигня или пропущена запятая в коде. Как их можно ставить на одну линейку? Одно - витающая в облаках мысль в поисках смысла семантики, а другое - конкретные строки кода с конкретным, определённым мегабайтами кода, регэкспов и BNF'ов, ASN'ов синтаксисом.
404

Что-то меня на философию сегодня тянет

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

UPD: Главное различие - в рекурсии принято описывать условие для завершения. А у фракталов - нет.

Как будет выглядеть результат работы алогоритма, у которого сложность o(n), при этом есть реурсия, вызывающая себя два раза на o(n/2)?
404

Архитектурно-философское, про best practice

Часто столкнувшись с слегка нестандартной задачей я испытываю замешательство, потому что не знаю и не могу найти никаких существующих практик для её решения.

Это можно было бы счесть всего лишь "не знаю как делать и не хочу заморачиваться", но внутри я ощущаю что-то более сложное.

Это что-то сложное - не желание изобрестать велосипед там, где его уже изобрели с одной стороны, и боязнь коммита на "создание архитектуры". Когда что-то делаешь в рамках практик, то в той или иной мере двигаешься по хорошо известной архитектуре. Часто желание не изобретать свои архитектуры звучит так: "так надо делать потому что так делать положено". Например, положено делать питоновые программы с setup.py. При использовании уже существующих практик не только заимствуется хорошая архитектура, но и часто "за бесплатно" (то есть без необходимости об этом думать специально) обеспечивается совместимость с чем-то, о чём ты даже и не знаешь в момент, когда делаешь.

Таким образом, когда оказываешься в ситуации, когда известной практики нет, ты о существовании практики не знаешь, или существующая практика не подоходит - короче, когда надо изобретать своё, в этот момент, чем больше опыта, тем острее он давит и говорит о том, какие последствия будут. Очень отдалённые и очень неприятные. Ощущение "и чем я думал, придумывая вот эту хрень?", повторяющееся несколько раз, оно очень дисциплирует.

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

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

Вот, яркий пример: ну откуда мимо пробегающий программист знает про систему /etc/nginx/sites-available/ и sites-enabled? Он идёт читать маны от nginx'а, после чего идёт и херачит всё в nginx.conf, а при переносе в продакшен сисадмины только за голову хватаются (иногда от сарказма иногда от того, что не уследили и оно пролезло в продакшен).

А ведь проблема не в том, что "программист глупый". А в том, что это устное предание. Едва ли не культурная традиция, которая витает меж сисадминами.

И в других областях то же самое - я иногда чувствую очень конкретный сарказм у программистов по мотивам написанного мною. И не потому что "плохие алгоритмы", а потому что я не соблюл очевидные (для них практики). А где я про них узнать могу-то?

Вотъ.
404

Эстетика компьютеров и сетей

Главное, чего не хватает во всей фантастике - это романтики и эстетики компьютеров и сетей.

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

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

Если человек способен писать оды человечеству при виде большого моста или сотни небоскрёбов, то почему он не может сделать то же самое в отношении куда более сложной конструкции? Или нужна обязательно ошеломляющая визуальная картинка в стиле самопиара NASA, где по моему художников едва ли не больше, чем астронавтов?

Меня совершенно не устраивает визуализация a-la matrix, a-la GITS, a-la digimon. Там какие-то тривиальные 3D-эффекты без малейшего нижележащего смысла.

Denno coil уже лучше, но там всё равно нет _компьютерной_ эстетики. Там какое-то фэнтези, чуть приправленное НФ-базисом. Базис есть - эстетики нет.

А ведь любой, кто лично тыкался в IDA или сколько-то бродил по hex-dump'у знает, что она, вот она, тут прямо на экране.

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

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

А где реальная романтика? А где реальное ощущение глубокого погружения (унесите Лукьяненко, он дитя вышеописанного эникейского админства) в проблему, где описание реального (настоящего, не выдуманного!) стресса от аварий и проблем, где доползающее до самых пяток холодное ощущение, когда понимаешь, что Сделал Большую Хуйню и не менее тёплое ощущение от того, что "не забыл сделать бэкап" (а иногда холодное "бля, не сделал")?

С программерским, кстати, то же самое. Где у нас настоящая жизнь программистов (я не про тех, что в 1С отчёты правят)? Близко даже нет.

Ничего этого нет. А нужно. Потому что воспитание технарей не может быть только техническим, нужна эстетико-мотивационная часть, а если её нет, каждому приходится по кусочкам собирать её самому - это долго, это десятилетия, это трудно.

Где глашатай технарей???