00:05 Введение
02:50 Две заблуждения
09:09 Компиляторный конвейер
14:23 История до сих пор
18:49 Товарная накладная
19:40 Проектирование языка
23:52 Будущее
30:35 Прошлое
35:57 Выбор битв
39:45 Грамматики 1/3
42:41 Грамматики 2/3
49:02 Грамматики 3/3
53:02 Статический анализ 1/2
58:50 Статический анализ 2/2
01:04:55 Система типов
01:11:59 Внутренности компилятора
01:27:48 Среда выполнения
01:33:57 Заключение
01:36:33 Предстоящая лекция и вопросы аудитории

Описание

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

Полный текст

Слайд 1

Добро пожаловать на эту серию лекций о цепочках поставок. Я - Жоанн Верморель, и сегодня я буду рассказывать о “Языках и компиляторах для цепочек поставок”. Я не помню, чтобы компиляторы обсуждались в каком-либо учебнике по цепочкам поставок, и все же эта тема является первостепенной. Мы видели в самой первой главе этой серии, в лекции под названием “Продуктовая доставка”, что программирование является ключом к получению выгоды от времени, вложенного экспертами по цепочкам поставок. Без программирования мы не можем получить выгоду от их времени, и мы относимся к экспертам по цепочкам поставок как к расходным материалам.

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

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

Слайд 2

Давайте начнем с развеивания двух заблуждений, которые были распространены в кругах поставщиков корпоративного программного обеспечения в течение последних трех десятилетий или около того. Первое - это заблуждение о “программировании Лего”, где программирование рассматривается как нечто, что можно полностью обойти. Действительно, программирование сложно, и всегда есть поставщики, которые обещают, что с помощью своего продукта и фантастической технологии программирование может быть превращено в визуальный опыт, доступный каждому, полностью устраняя все трудности самого программирования, так что опыт фактически становится похожим на сборку Лего, что даже ребенок может делать.

Это было попытано бесчисленное количество раз в последние несколько десятилетий и всегда безуспешно. В лучшем случае продукты, предназначенные для достижения визуального опыта, превратились в обычные языки программирования, которые не особенно легче освоить по сравнению с другими языками программирования. Кстати, это анекдотический повод, почему, например, в серии продуктов Microsoft есть серия “Visual”, такие как Visual Basic for Application и Visual Studio. Все эти визуальные продукты были представлены в 90-х годах с надеждой превратить программирование в чисто визуальный опыт с дизайнерами, где все было бы просто перетаскиванием и размещением. Реальность заключается в том, что все эти инструменты в конечном итоге достигли очень значительной степени успеха, но сейчас они просто обычные языки программирования. От визуальных частей, которые были в начале этих продуктов, почти ничего не осталось.

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

Второе заблуждение - это заблуждение о “технологии Звездных войн”, которое заключается в том, что легко подключить и использовать фантастические технологии. Это заблуждение очень привлекательно для поставщиков и внутренних проектов. Существенно, что соблазнительно сказать, что есть фантастическая база данных NoSQL, которую мы можем просто внедрить, или есть фантастический стек глубокого обучения, или графовая база данных, или распределенная активная платформа и т.д. Проблема этого подхода заключается в том, что он относит технологию так же, как в Звездных войнах. Когда у вас есть механическая рука, герой может просто получить механическую руку, и она работает. Но на самом деле проблемы интеграции преобладают.

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

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

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

Slide 3

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

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

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

На диаграмме вы можете увидеть типичный конвейер, и этот архетип подходит для большинства языков программирования, о которых вы, вероятно, когда-либо слышали, таких как Python, JavaScript, Java и C#. У всех этих языков есть конвейер, существенно похожий на описанный здесь. В конвейере компилятора у вас есть серия преобразований, и на каждом этапе процесса у вас есть представление, которое представляет всю программу. Компилятор разрабатывается таким образом, чтобы иметь ряд четко определенных преобразований, и на каждом этапе процесса вы работаете с полной программой. Она просто представлена по-разному.

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

Slide 4

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

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

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

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

Slide 5

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

Slide 6

С 1950-х годов было создано тысячи языков программирования. Оценки варьируют, но количество языков программирования, которые использовались для производственных целей, вероятно, находится в диапазоне от одной тысячи до десяти тысяч. Многие из этих языков являются просто вариациями или родственниками друг друга, иногда даже просто кодовой базой компилятора, разветвленной в немного другом направлении. Интересно отметить, что несколько очень крупных предприятий по разработке программного обеспечения значительно расширились благодаря внедрению собственных языков программирования. Например, SAP представил ABAP в 1983 году, Salesforce представил Apex в 2006 году, а даже Microsoft начал свою деятельность еще до появления Windows, разработав Altair BASIC в 1975 году.

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

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

Все это действительно вызывает вопрос: а что насчет языка программирования, специально разработанного для целей цепочки поставок? Действительно, здесь может быть значительный потенциал в терминах производительности, надежности и даже производительности цепочки поставок.

Slide 7

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

Интересно то, что игровая индустрия имеет очень хорошо установленную структуру. Во-первых, у нас есть игровые движки, признанные лидерами которых являются Unity и Unreal. Эти игровые движки содержат низкоуровневые компоненты, которые представляют интерес для суперинтенсивной уточненной 3D-графики, и они определяют ландшафт для уровня инфраструктуры вашего кода. Есть несколько компаний, которые разрабатывают очень сложные продукты, называемые игровыми движками, и эти движки используются всей отраслью.

Затем у нас есть игровые студии, которые разрабатывают игровой код для каждой игры. Игровой код будет кодовой базой, которая обычно специфична для разрабатываемой игры. Для разработки игрового движка требуются очень сложные программные инженеры, которые обладают высоким техническим мастерством, но не обязательно знают много о играх. Разработка игрового кода не так интенсивна с точки зрения чистых технических навыков. Однако программные инженеры, разрабатывающие игровой код, должны понимать игру, над которой они работают. Игровой код устанавливает платформу для игровой механики, но не определяет детали.

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

В настоящее время игровой код часто становится доступным для фанатской базы, что означает, что гейм-дизайнеры могут писать правила и потенциально изменять игру, но это также могут делать и фанаты, которые являются обычными потребителями игр. В отрасли есть несколько интересных анекдотов. Например, игра Dota 2, которая невероятно успешна, началась как модификация существующей игры. Первая версия, просто названная Dota, была чистой модификацией игры World of Warcraft 3, созданной фанатской базой. Вы можете видеть, что степень настраиваемости и программирования на уровне игровых правил очень обширна, потому что было возможно из существующей коммерческой игры, World of Warcraft 3, создать совершенно новую игру, которая затем стала огромным коммерческим успехом через вторую версию. Теперь это интересно, и мы можем начать думать, глядя на игровую индустрию, что это означает для отрасли цепочки поставок?

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

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

Slide 8

До сих пор подход игровой индустрии к цепочке поставок остается научной фантастикой, за исключением нескольких компаний. Я считаю, что большинство из этих компаний, случайно, являются клиентами Lokad. Вернемся к сегодняшней теме, мы видели в предыдущих лекциях, что Excel остается самым популярным языком программирования в этой отрасли. Кстати, с точки зрения языка программирования, Excel является функциональным реактивным языком программирования, поэтому он даже является своим собственным классом.

В настоящее время вы, возможно, слышите от поставщиков предложения о модернизации цепочек поставок с использованием некоторого вида настройки науки о данных. Однако мое поверхностное наблюдение за последнее десятилетие заключается в том, что подавляющее большинство этих инициатив потерпело неудачу. Это уже прошлое, и чтобы понять, почему, нам нужно начать с рассмотрения списка используемых языков программирования. Если мы посмотрим на Excel, мы увидим, что в нем используются в основном два языка программирования: формулы Excel и VBA. VBA даже не является обязательным; вы можете далеко продвинуться, используя только VLOOKUP в Excel. Обычно это будет всего один язык программирования, и он доступен не программистам.

С другой стороны, список языков программирования, необходимых для воспроизведения возможностей Excel с помощью настройки науки о данных, довольно обширен. Нам понадобится SQL и, возможно, несколько диалектов SQL, для доступа к данным. Нам понадобится Python для реализации основной логики. Однако Python сам по себе склонен к медленности, поэтому вам может понадобиться подъязык, например, NumPy. На этом этапе вы все еще не делаете ничего в терминах машинного обучения или математической оптимизации, поэтому для настоящего численного анализа вам понадобится что-то еще, еще один язык программирования, такой как, например, PyTorch. Теперь, когда у вас есть все эти элементы, у вас уже есть довольно много движущихся частей, поэтому конфигурация самого приложения будет довольно сложной. Вам понадобится конфигурация, и эта конфигурация будет написана с помощью еще одного языка программирования, такого как JSON или XML. Возможно, это не слишком сложные языки программирования, но это добавляет еще больше на тарелку.

Когда у вас есть так много движущихся частей, вам обычно нужна система сборки, что-то, что может выполнить все компиляторы и мирские рецепты, необходимые для создания программного обеспечения. У систем сборки есть свои языки. Традиционный подход - это язык, называемый Make, но есть и другие. Кроме того, поскольку Excel способен отображать результаты, вам нужен способ отображения вещей пользователю и визуализации. Это будет сделано с помощью смеси JavaScript, HTML и CSS, что добавляет еще больше языков в список.

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

Slide 9

Теперь давайте подумаем о том, каким должен быть язык программирования для цепочки поставок. Сначала нам нужно решить, что находится внутри языка и что принадлежит языку как гражданину первого класса, а что принадлежит библиотекам. Действительно, с языками программирования всегда можно передать возможности библиотекам. Например, давайте посмотрим на язык программирования C. Он считается довольно низкоуровневым языком программирования, и в C нет сборщика мусора. Однако в программе на C можно использовать сборщик мусора от третьей стороны в качестве библиотеки. В связи с тем, что сборка мусора не является гражданином первого класса в языке программирования C, синтаксис обычно относительно громоздкий и утомительный.

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

Было бы логично иметь реляционные данные внутри языка. Кроме того, что насчет пользовательского интерфейса (UI) и пользовательского опыта (UX)? Одним из сильных моментов Excel является то, что все это полностью встроено в язык, поэтому у вас нет языка программирования, а затем все виды сторонних библиотек для работы с презентацией, отображением и взаимодействием с пользователем. Все это является частью языка. Иметь все это в качестве сущности первого класса также будет очень интересно с точки зрения управления цепочкой поставок, по крайней мере, если мы хотим быть такими же хорошими, как Excel, для цепочек поставок.

Slide 10

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

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

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

Slide 11

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

Slide 12

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

Типичный способ представления грамматики формально - использование формы Бэкуса-Наура (BNF), которая является специальной нотацией. На экране вы видите мини-язык программирования, который представляет почтовые адреса США. Каждая строка с знаком равенства представляет правило продукции. Слева у вас есть нетерминальный символ, а справа от знака равенства - последовательность терминальных и нетерминальных символов. Терминальные символы красные и представляют символы, которые не могут быть выведены дальше. Нетерминальные символы находятся в квадратных скобках и могут быть выведены дальше. Эта грамматика здесь не полная; для полной грамматики нужно добавить еще много правил продукции. Я просто хотел сделать этот слайд достаточно лаконичным.

Грамматика - это нечто очень простое для определения в терминах синтаксиса вашего языка программирования, и она также гарантирует, что она будет неоднозначной. Однако это не означает, что, если она написана в форме Бэкуса-Наура, она будет действительной грамматикой или даже хорошей грамматикой. Чтобы иметь хорошую грамматику, нам нужно сделать немного больше. Математический способ характеризовать хорошую грамматику - иметь контекстно-свободную грамматику. Грамматика считается контекстно-свободной, если правила продукции могут быть применены для любого нетерминала, независимо от символов, которые вы находите справа и слева. Идея заключается в том, что контекстно-свободная грамматика - это нечто, где вы можете применять правила продукции в любом порядке, и как только вы видите совпадение или вывод, вы просто применяете его.

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

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

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

К счастью, в 2004 году Брайан Форд представил небольшой прорыв с документом под названием “Грамматики выражений разбора: основа синтаксиса на основе распознавания”. С этой работой Форд предоставил сообществу способ формализовать своего рода случайные эмпирические парсеры, которые существуют в области. Например, эти грамматики называются грамматиками выражений разбора (PEG), и с помощью PEG вы можете преобразовать эти полуслучайные эмпирические парсеры в фактические формальные грамматики какого-то вида.

Python, например, не имеет строго контекстно-свободной грамматики, но имеет PEG. PEG-грамматики вполне подходят, если у вас есть обширный набор автоматизированных тестов, потому что в этом случае вы можете справиться с сохранением семантики со временем. Действительно, с помощью PEG у вас есть формализация вашей грамматики, поэтому вы находитесь в лучшей ситуации по сравнению с отсутствием грамматики и наличием только парсера. Однако, с точки зрения эволюции семантики, с PEG вы не автоматически обнаружите изменение семантики, если измените саму грамматику. Таким образом, вам нужно иметь обширный набор автоматизированных тестов поверх вашего PEG, что, кстати, именно то, что есть в сообществе Python. У них есть очень надежный и обширный набор автоматизированных тестов. Теперь, с точки зрения поставщика цепочки поставок, я считаю, что грамматики не только заинтересованы в том, чтобы заставить вас осознать их важность, но также являются своеобразным литмусовым тестом. Вы можете проверить поставщиков корпоративного программного обеспечения, когда обсуждаете сложную конфигурацию программного обеспечения. Если поставщик отвечает “что такое грамматика?”, то вы знаете, что у вас проблемы, и обслуживание, скорее всего, будет медленным и дорогостоящим.

Slide 13

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

Рассмотрим следующую ситуацию: при написании кода, если ошибка может быть обнаружена в процессе набора, например, опечатка с красной подчеркиванием в Microsoft Word, то цикл обратной связи для исправления ошибки может быть таким коротким, как 10 секунд, что идеально. Если ошибка может быть обнаружена только при запуске программы, цикл обратной связи будет длиться не менее 10 минут. В цепочке поставок у нас часто есть большие наборы данных для обработки, и нельзя ожидать, что программа начнет обрабатывать все данные за считанные секунды. В результате, если проблема возникает только во время выполнения, цикл обратной связи будет длиться 10 минут или дольше.

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

Есть еще худший сценарий: если платформа, на которой вы работаете, не является строго детерминированной, то есть с одинаковым вводом и данными она может давать вам разные результаты. Это не так странно, как может показаться, так как в цепочке поставок у нас могут быть такие вещи, как Монте-Карло симуляции. Если в результатах есть какая-то случайность, мы можем иметь что-то, что не работает только время от времени, и в этой ситуации цикл обратной связи обычно длится более 10 дней. Итак, мы перешли от 10 секунд до 10 дней, и в этом есть огромные ставки. Статический анализ представляет собой набор техник, которые могут быть применены для обнаружения проблем, ошибок или сбоев, даже не запуская программу в первую очередь. Статический анализ позволяет обнаружить ошибку в реальном времени, пока люди пишут код, подобно красному подчеркиванию для опечаток в Microsoft Word. Более общим образом, существует большой интерес в преобразовании каждой проблемы так, чтобы она переходила в более ранний класс обратной связи, превращая проблемы, которые занимают дни для идентификации, в минуты или минуты в секунды и так далее.

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

Slide 14

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

С помощью статического анализа вы обычно получаете три категории: некоторые части кода, вероятно, хорошие, некоторые части, вероятно, плохие, и для многих вещей посередине вы просто не знаете. Идея заключается в том, что чем больше вы перемещаете из “неизвестно” в “плохой код”, тем больше усилий вам понадобится в терминах языкового дизайна, чтобы убедить компилятор, что ваша программа является допустимой. Поэтому нам нужно найти баланс между тем, сколько усилий вы хотите вложить в убеждение языка программирования в том, что ваш код правильный, и сколько гарантий вы хотите иметь на программу на этапе компиляции, еще до того, как программа фактически запустится. Это вопрос производительности.

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

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

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

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

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

Slide 15

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

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

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

С точки зрения цепочки поставок, мы ищем типовую систему, которая поддерживает то, что мы намерены сделать в интересах цепочки поставок. Мы хотим быть максимально ограничивающими, чтобы заранее выявлять проблемы и ошибки, но также максимально гибкими, чтобы позволить все операции, которые могут быть интересными. Например, рассмотрим сложение даты и целого числа. В обычном языке программирования вы, вероятно, скажете, что это недопустимо, но с точки зрения цепочки поставок, если у нас есть дата и мы хотим добавить семь дней, было бы логично написать “дата + 7”. В планировании цепочки поставок существует множество операций, которые включают сдвиг дат на определенное количество дней, поэтому было бы полезно иметь алгебру, в которой допустимо выполнять сложение между датой и числом.

Что касается типов, мы хотим разрешить сложение одной даты с другой? Вероятно, нет. Однако, мы хотим разрешить вычитание между двумя датами? Почему бы и нет? Если мы вычтем одну дату из другой, которая произошла раньше, мы получим разницу, которая может быть выражена в днях. Это имеет много смысла для расчетов, связанных с планированием.

Продолжая разговор о датах, также есть характеристики, которые могут быть интересными, когда мы думаем о том, что должна делать для нас типовая система с точки зрения цепочки поставок. Например, что насчет ограничения допустимого временного диапазона? Мы можем сказать, что даты, выходящие за пределы 20 лет в прошлое и 20 лет в будущее, просто недопустимы. Вероятно, если мы выполняем операцию планирования и в какой-то момент в программе мы манипулируем датой, которая находится более чем на 20 лет вперед, шансы того, что это не является допустимым сценарием планирования для большинства отраслей, ошеломляющие. В большинстве случаев вы не будете планировать операции на ежедневном уровне более чем на 20 лет вперед. Таким образом, мы можем не только использовать обычные типы, но и переопределить их таким образом, чтобы они были более ограничены и более подходящими для целей цепочки поставок.

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

Slide 16

В Lokad мы создали Envision - язык программирования, посвященный предиктивной оптимизации цепочек поставок. Envision - это смесь SQL, Python, математической оптимизации, машинного обучения и возможностей обработки больших данных, все объединенные в самом языке. Этот язык поставляется с веб-интегрированной средой разработки (IDE), что означает, что вы можете писать скрипты прямо из веб-интерфейса и использовать все современные функции редактирования кода. Эти скрипты работают с интегрированной распределенной файловой системой, которая поставляется с окружением Lokad, поэтому слой данных полностью интегрирован в язык программирования.

Скрипты Envision выполняются на группе машин, разработанных для использования всего облачного пространства. Когда скрипт запускается, он распределяется по многим машинам, чтобы работать быстрее. На экране вы можете увидеть конвейер компиляции, используемый Envision. Сегодня мы не будем обсуждать этот язык программирования; мы просто обсудим его конвейер компиляции, потому что это тема интереса для сегодняшней лекции.

Сначала мы начинаем с текста, который содержит скрипт Envision. Он представляет собой программу, написанную экспертом по цепочке поставок, а не программистом, чтобы решить конкретную проблему цепочки поставок. Эта проблема может заключаться в принятии решения о том, что производить, что пополнить, что переместить или изменить цену вверх или вниз. Эти случаи использования включают решения о том, что производить, пополнять, перемещать или изменять цены вверх или вниз. Текст скрипта содержит инструкции, и идея заключается в обработке этого скрипта и получении дерева синтаксического разбора без потерь (LST). LST представляет интерес, потому что это очень специфичное представление, которое не отбрасывает ни одного символа. Даже незначительные пробелы сохраняются. Причина этого заключается в том, чтобы гарантировать, что любые автоматические переписывания программы не изменяют существующий код. Такой подход позволяет избежать ситуаций, когда инструменты перемещают код, перемещают отступы или вызывают другие нарушения, которые затрудняют распознавание кода.

Операция базового рефакторинга, например, может включать переименование переменной и всех ее вхождений в программе без изменения чего-либо еще. Из LST мы переходим к Абстрактному Синтаксическому Дереву (AST), где мы упрощаем дерево. В этой стадии скобки не нужны, потому что структура дерева определяет приоритеты всех операций. Кроме того, мы выполняем серию операций десахаризации, чтобы удалить любой синтаксис, предоставленный для удобства конечного программиста.

Переходя от AST к Абстрактному Синтаксическому Графу (ASG), мы выравниваем дерево. Этот процесс включает разложение сложных операторов с высоко вложенными выражениями на последовательность элементарных операторов. Например, оператор вроде “a = b + c + d” будет разделен на два оператора, каждый из которых содержит только одно сложение. Именно это происходит при переходе от AST к ASG.

Из ASG мы переходим к Графу Оптимизации (OG), где мы выполняем формирование типов и широковещательную передачу, особенно в отношении реляционной алгебры. Как уже упоминалось ранее, Envision встраивает реляционную алгебру в язык. Как и в реляционных базах данных или SQL-базах данных, Envision встраивает реляционную алгебру как гражданина первого класса. Существует множество реляционных операций, и мы проверяем, что эти реляционные операции допустимы согласно схеме таблиц, с которыми мы работаем при переходе от ASG к OG. Граф Оптимизации (OG) представляет собой последний шаг нашего компилятора фронт-энда и состоит из чистых элементарных реляционных операций, применяемых к программе и представляющих маленькие логические единицы. Как и в SQL, эти элементы имеют реляционную природу.

Граф оптимизации называется “оптимизацией”, потому что существует множество преобразований, которые происходят от OG к OG. Эти преобразования происходят потому, что при работе с реляционной алгеброй организация операций определенным образом может значительно ускорить работу программы. Например, в SQL, если у вас есть фильтр, а затем операция, или операция сначала, а затем фильтр, гораздо лучше сначала отфильтровать данные, а затем применить операцию. Это гарантирует, что операции применяются только к необходимым данным, улучшая эффективность.

В Lokad последним шагом компилятора фронт-энда является High Intermediate Representation (HIR). HIR является чистым, стабильным и задокументированным интерфейсом между фронт-эндом и бэк-эндом конвейера компиляции. В отличие от Графа Оптимизации (OG), который постоянно изменяется из-за эвристик, HIR является стабильным и обеспечивает последовательный ввод для бэк-энда компилятора. Кроме того, HIR сериализуем, что означает, что его легко преобразовать в набор байтов для перемещения с одной машины на другую. Это свойство является важным для распределения вычислений по нескольким машинам.

Из High Intermediate Representation мы переходим к “funcs”. Функции - это значения, которые еще не были вычислены и представляют собой атомарные блоки вычислений в распределенном выполнении. Например, при сложении двух гигантских векторов из таблицы с миллиардами строк будет ряд функций, представляющих различные части этих векторов. Каждая функция отвечает за сложение части двух векторов и выполняется на одной машине. Большие вычисления разбиваются на множество функций, чтобы распределить нагрузку по нескольким ЦП и нескольким машинам, если вычисление достаточно большое для такой степени распределения. Функции называются “ленивыми”, потому что они не вычисляются сразу; они вычисляются по мере необходимости. Множество вычислений может произойти до того, как некоторые функции будут фактически вычислены, и как только функция будет вычислена, сама функция заменяется своим результатом.

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

С точки зрения цепочки поставок, на самом деле интересно то, что через эту, пожалуй, сложную конвейер компиляции мы воспроизводим степень интеграции, которую можно найти в Microsoft Excel. Язык интегрирован с уровнем данных и уровнем пользовательского интерфейса, позволяя пользователям видеть и взаимодействовать с результатами программы, так же, как они делают это с электронной таблицей Excel. Однако, в отличие от Excel, мы углубляемся в гораздо более интересные территории для управления цепочками поставок, объединяя концепции реляционных баз данных, математической оптимизации и машинного обучения.

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

Slide 17

В настоящее время компиляторы почти всегда нацелены на виртуальную машину, но эти виртуальные машины, в свою очередь, компилируются в другую виртуальную машину. На экране типичные слои виртуальных машин, которые можно найти в серверной настройке, очень похожи на то, что у нас есть с Envision-скриптом. Я только что представил конвейер компиляции, но в основном это был бы практически тот же стек, если бы мы думали о скрипте Python или электронной таблице Excel, работающей на сервере. Проектируя компилятор, вы в основном выбираете слой, на котором будете внедрять код. Чем глубже слой, тем больше технических вопросов вам придется решить. Для выбора слоя необходимо решить ряд проблем.

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

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

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

В-четвертых, есть вопросы распределения ресурсов. Если вы работаете с электронной таблицей Excel на своем компьютере, Excel может потреблять все вычислительные ресурсы на вашей рабочей станции. Однако, с Envision или SQL у вас есть несколько пользователей для обслуживания, и вам нужно решить, как распределить ресурсы. Более того, с Envision это не только несколько пользователей, но и несколько компаний для обслуживания, так как Lokad является многопользовательским. Это имеет смысл в цепочке поставок, потому что потребность в вычислительных ресурсах для большинства цепочек поставок очень прерывистая.

Обычно вам нужна очень интенсивная вспышка вычислений, например, в течение полутора или, может быть, одного часа, а затем ничего в течение следующих 23 часов. Затем повторяйте это ежедневно. Если бы вы выделили вычислительные ресурсы аппаратного обеспечения одной компании, эти ресурсы оставались бы неиспользованными 90% времени или даже больше. Поэтому вы хотите иметь возможность распределить нагрузку по множеству машин и множеству компаний, потенциально компаний, работающих в разных часовых поясах.

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

Slide 18

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

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

Slide 19

Следующая лекция будет о программной инженерии. Сегодня мы обсудили инструменты; однако, в следующий раз мы обсудим людей, которые используют эти инструменты, и какая командная работа требуется для успешного выполнения работы. Лекция состоится в тот же день недели, в среду, в 15:00 по парижскому времени.

Теперь я посмотрю на вопросы.

Вопрос: При выборе программного обеспечения для поставочных цепей, как предприятия, не разбирающиеся в технологиях, могут оценить, подходят ли им компилятор и языки программирования?

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

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

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

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

Вопрос: Вы непосредственно затронули проблему существующих языков программирования, не предназначенных для цепей поставок?

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

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

Например, первый релиз Python состоялся в 1990 году, поэтому это 30-летний язык программирования. Количество кода в популярном стеке, таком как Python, абсолютно гигантское, и по хорошей причине. Я не критикую его; это очень надежный стек, но он также огромный. Так что в конце концов мы оценили различные варианты: взять язык программирования, вычесть массу вещей, пока мы не будем удовлетворены тем, что у нас есть, или считать, что все эти языки программирования имеют свою собственную массу наследия.

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

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

Вопрос: Для оптимизации цепей поставок Envision подходит, так как он включает SQL, Python и т. д. Однако для WMS, ERP, где ключевым является процессный поток, а не математическая оптимизация, как можно оценить его компилятор и язык программирования?

Это очень хороший вопрос. Я лично играл с идеей, что в этой отрасли есть актеры, которые на самом деле создали собственные языки программирования, исключительно для того, чтобы реализовать что-то полностью транзакционное по своей природе, ориентированное на рабочий процесс. Цепи поставок, как я это вижу, в основном связаны с предсказательной оптимизацией. Однако г-н Наннани абсолютно прав; что насчет всей управленческой части, такой как ERP, WMS и т. д.?

Оказывается, в этой области есть много компаний, которые создали свой собственный язык программирования. Я упомянул SAP, у которого есть ABAP, разработанный именно для этого. К сожалению, ABAP не очень хорошо устарел, по моему мнению. В ABAP есть много вещей, которые не имеют смысла в XXI веке. Вы действительно видите, что это было разработано в ‘83 году, и это видно. Например, в Microsoft Dynamics в ERP есть свой собственный язык программирования. У Dynamics AX есть свой собственный язык программирования, и существует много проектов ERP, которые в значительной степени привносят свой собственный язык программирования. Так что это существует.

Теперь, являются ли эти языки действительно вершиной того, что мы можем сделать в современных, передовых языках программирования в 2021 году? Я так не думаю, и это также проблема, о которой я говорил: поставщики корпоративного программного обеспечения продолжают изобретать языки программирования, но обычно они делают это очень плохо. Это просто беспорядочное инженерное проектирование. Они даже не тратят время на чтение множества книг, доступных на рынке, а затем есть плохие инженеры, которые застревают с горячей кучей беспорядка.

Вернувшись к вашему вопросу, я играл с идеей того, чтобы Lokad занялся этой областью и создал язык, который был разработан не для оптимизации, а для поддержки рабочего процесса. Однако на данный момент рост Lokad настолько велик, что мы не можем отвлекаться и заниматься рабочими процессами. Я абсолютно уверен, что это верно, и появятся новые актеры, которые справятся с управленческой частью проблемы. Lokad занимается только оптимизацией цепей поставок; есть также управленческая часть.

Вопрос: В настоящее время Python считается стандартным языком программирования. Есть ли какие-либо текущие изменения на рынке?

Это очень хороший вопрос. Понимаете, когда люди говорят мне “стандарты”, я был достаточно долго в этой сфере, чтобы видеть, как стандарты приходят и уходят. Я не очень стар, но когда я учился в школе, стандартом был C++. В 90-х годах C++ был стандартом. Почему бы не сделать это иначе? Затем появился Java, примерно в 2000 году, и комбинация Java и XML стала стандартом.

Люди даже говорили, что университеты тогда превратились в “школы Java”. Это был буквально термин того времени, около 2000 года; люди говорили: “Это уже не университет по компьютерным наукам, это просто школа Java”. Через несколько лет, когда я основал Lokad, язык программирования для всего, что касалось статистики, все еще был R. Python был все еще очень маргинальным, и R абсолютно доминировал в области статистического анализа.

По мере продвижения в области языков программирования C++ ушел в прошлое. Microsoft представил C# в 2002 году и платформу .NET, которая поглотила значительную часть экосистемы C++. Большая часть разработчиков C++ по всему миру работала в Microsoft, очень масштабной компании. То, к чему я прихожу, заключается в том, что происходит полная непрерывная эволюция, и каждый год люди смотрят на это так, будто есть стандарт, но этот стандарт постоянно меняется.

JavaScript существовал уже 20 лет, но это было ничто особенное. Затем в 2009 или 2012 году была опубликована книга “JavaScript: The Good Parts”, в которой было показано, что JavaScript не совсем безумный. Вы могли использовать JavaScript для реального проекта, не теряя рассудка; вам просто нужно было придерживаться хороших частей. Внезапно JavaScript стал очень популярным, и люди начали использовать его на стороне сервера с помощью системы под названием Node.js.

Python стал популярным всего несколько лет назад, после того, как сообщество Python претерпело изнурительное обновление с версии 2.7 на версию 3.x. По окончании этого обновления интерес к Python возродился. Однако Python подвержен многим опасностям. Это не очень хороший язык по стандартам XXI века. Это язык, который уже 30 лет, и это видно по его возрасту. Если вы хотите что-то лучшее во всех аспектах, кроме зрелости, вы можете посмотреть на Julia. Julia превосходит Python почти во всех аспектах для научных исследований, за исключением зрелости, где Julia все еще отстает на несколько лет.

Существует множество текущих эволюций, и легко ошибиться, приняв состояние отрасли за стандарт, который должен длиться. Например, в экосистеме Apple был Objective-C, а затем Apple решила создать Swift в качестве замены, который теперь заменяет Objective-C. Языковой ландшафт программирования все еще находится в стадии активного развития, и хотя это занимает время, если мы посмотрим на экосистему через десять лет, вероятно, произойдет значительное количество изменений. Python может не стать доминирующим языком программирования, так как существует много конкурирующих вариантов, которые предлагают лучшие решения.

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

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

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

Например, интеграция TensorFlow является сложной задачей. У Google есть 1000 инженеров, которые занимаются интеграцией TensorFlow во все свои конвейеры данных и приложения для своих целей. Но вопрос в том, могут ли стартапы или компании в сфере электронной коммерции позволить себе иметь столько людей, чтобы заниматься всей этой “сантехникой”? Обычно ответ - нет. Люди представляют себе, что просто выбрав эти инструменты, они смогут собрать их вместе и волшебным образом все заработает. Но это не так. Это требует огромного количества инженерной работы.

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

Думаю, это был последний вопрос. Увидимся в следующий раз.