Category: техника

Category was added automatically. Read all entries about "техника".

flow

О специалистах

За последнее время уже столько раз отвечал, что решил вынести из комментариев к http://justy-tylor.livejournal.com/231069.html в отдельный пост:

Есть изначально ошибочная предпосылка, что специалист предметной области способен сам писать хотя бы простые алгоритмы. Это не так. Требуется умение сознательно моделировать сущности, качества и события предметной области, на что способен лишь специалист по автоматизации предметной области. Разница как между уборщицей и разработчиком робота-пылесоса. В каких-то случаях специалиста по автоматизации можно подготовить из предметника (например, бизнес-аналитика), но чаще оказывается проще обучить программиста особенностям предметки.
flow

Типы для реальности

Тут последнее время всё всплывает вопрос - как совместить систему типов и сущности реального (или возможного) мира. Спрашиваете - отвечаем.

История.

Системы типов в computer science работают с абстракциями. Есть тип ЦелоеЧисло, есть значение 100500. А если тип ЦентрифужныйНасос, то он суть product type (структурка, класс, ...), который может содержать в себе некие значения в связи с центрифужными насосами. Онтологи это неодобряэ, дескать, надо в системе типов различать индивид Насос№123 (реальный, физический) и структурки, представляющие малый срез его качеств. Поэтому пишут свои системы типов, где всё заведомо правильно и одобрено Аристотелем, прекрасно записывается на слайды PowerPoint и глиняные таблички, но не работает.

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

Решение.

Представьте себе такой product type:
struct vector2d { float x; float y; };
Значения этого типа содержат пару float, а вот сам тип содержит в себе множество геометрических смыслов, с которыми работает непосредственно человеческий разум. Какие-то из этих смыслов можно воплотить в коде функций/методов, другие остаются в реальном мире.

Идём дальше, рассматриваем тип беззнакового целого uint32_t. Чуть ниже уровнем это тоже product type. 4 байта, 32 бита, есть некий побайтовый layout (big-endian или little-endian), который различается между платформами. Таким образом, у vector2d, uint32_t и float есть некий битовый "хвост". Причём, длина этого "хвоста" идентична для float и uint32_t. Разница лишь во вне-битовых смыслах реального мира, которые, опять же, могут быть частично выражены в каких-либо программных аспектах.

Но бывают и unit types, где кроме указания типа ничего нет. Классы и структуры без полей, конструкторы алгебраических типов без параметров, etc. Такой тип содержит исключительно смыслы реального мира. Соответственно, "мистические онтологические индивиды" могут быть представлены обычными unit types. Для типа Насос№123 его "хвост" находится в реальном (или возможном) мире. Этот тип - множество все темпоральных частей данного насоса. Аналогично, тип ГородОдесса - множество темпоральных частей реально существующего города. И описывать качества этих сущностей или какие-либо требования к ним мы можем точно так же, как с обычными типами, используя богатые (или не очень) возможности языка - методы, type classes, etc.

Однако, как нам выразить деятельностное требование, что в каких-то контекстах можно указывать только Город, а в каких-то только Насос? Здесь предлагаются множества, sum types.

Первый случай - variant, экстенсиональное определение.

Во многом похож на реализацию алгебраических типов в Haskell, но с важным отличием - вместо конструкторов типов используются полноценные product types и unit types, поэтому не требуется создавать дубликаты одинаковых смыслов для разных variant.
data CardinalDirection = N | S | W | E
data CompassDirection = N | S | W | E | NW | NE | SW | SE
В Haskell такое повторение не допускается, но при интеграции данных такая возможность необходима. Надо, чтобы в каждом variant, предусматривающем состояние paused, вместо MY_ENUM_BLABLABLA_PAUSED использовался standard_dictionary.paused, с подходящим и хорошо документированным набором смыслов.

Второй случай - tag, интенсиональное определение. Ближайшие аналоги - классификация, type classes, type families. Для сущности Насос№123 ставятся тэги Оборудование, Насос, ЦентрифужныйНасос. В свою очередь, на ЦентрифужныйНасос может быть поставлен тэг ВидНасосов.

Тэги ставятся только явно, на этом уровне нет системы правил "если Насос, то значит и Оборудование". Отдельные смыслы живут долго, но у таксономий жизнь короткая, "телевизоры только с кинескопом" или "телефоны только стационарные" быстро перестают соответствовать действительности. Так что, без таксономий.

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

Как избавиться от динамической типизации

Давно хотел оформить subj в один пост, а сейчас и срачи подоспели в тему:
http://thedeemon.livejournal.com/54732.html
http://belnetmon.livejournal.com/2093044.html
http://metaclass.livejournal.com/735575.html

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

Когда в языке с динамической типизацией пишется obj.width = 132, то мы и так заранее знаем, что width всегда int (или что-то ещё известное, в зависимости от архитектуры системы). Нет ситуаций, когда в width должен содержаться экземпляр какого-нибудь HTTPConnection или иной мусор. Однако, width может отсутствовать, если данный obj не используется в ситуациях заведомо требующих наличия width, а используется только там, где width не требуется, или наличие дополнительно проверяется.

Это типичная ситуация для САПРов, где таких width, которые есть или нет, могут быть сотни и тысячи. Обычных product types и sum types оказывается недостаточно. Поэтому в САПРах всегда своя система типов, отличающаяся от системы типов хост-языка. Можно добавлять пользовательские свойства (как строки), хотя не во всех системах можно регистрировать ограничения на их типы (что значением "mywidth" всегда будет целое число). В языках с динамической типизацией об этом вообще не думают, объект является контейнером Map(строка->хзчто). Бардак.

Системное решение такое: вместо случайных строк ключами в контейнере должны быть полноценные identity, а типы хранимых значений должны однозначно соответствовать им. Назовём такой тип контейнера multidomain.

Далее, для обычных структур (product types) мы используем описание самой структуры при трансляции a = ent.width, а для multidomain придётся добавить описания необходимых свойств:
type physical.width = pair float UoM
type ui.width = int
и использовать как
b = ent physical.width // получить значение или ошибку времени выполнения
c = ent maybe ui.width // получить Just значение или Nothing
со строгим контролем типов.

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

Кроме того, multidomain контейнеры подходят не только для "ад, коровники, энтерпрайз", описаний винтиков и жизненного цикла нефтяной платформы, но и для описаний самих типов данных, включая пользовательские traits.