Pull to refresh

Обзор языка программирования AsmX

Level of difficultyEasy
Reading time7 min
Views22K
Лого AsmX
Лого AsmX

Часть 0. Причины написания статьи

Основная причина написания этой статьи — тотальное несоответствие обещаний автора языка (далее просто автора) насчёт своего детища и реальных его возможностей, полное отсутствие тестирования и цензура в комментариях его телеграм-канала (единственный ресурс с включёнными комментариями). Я не преследую цели оскорбить автора, выдумать несуществующие недостатки или распространить дезинформацию. Тесты были проведены на последней версии от 27.08.2023 15.00. Любой ответ автора приветствуется.

Часть 1. Что такое AsmX?

Автор продвигает AsmX как новый вариант языка ассемблера. Однако это неправда; рассмотрим ассемблер — низкоуровневый, императивный, беcтиповый язык. Сборка ассемблера отличается от сборки других языков и является простым переводом слов‑команд в бинарные коды тех же команд. Проверим AsmX на эти качества:

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

  • Императивность: AsmX объектно‑ориентированный.

  • Отсутствие типов: типизация переменных в AsmX — статическая, типизация регистров — динамическая.

  • Сборка: AsmX — интерпретируемый язык.

Таким образом видно, что AsmX не является не то что вариантом ассемблера, но и просто низкоуровневым языком. Дальнейшее сравнение с ассемблером считаю бесполезным. Сравнивать его будем с языком C++, так как он намного ближе к AsmX, чем ассемблер (высокоуровневый, объектно-ориентированный, статически типизированный, компилируемый) и в некотором роде автор, рассказывая о мифических плюсах своего языка, описывает C++. Подробнее в одной из предыдущих статей (https://telegra.ph/Razbor-fitch-yazyka-AsmX-08-16).

Часть 2. Переменные и типы

Переменные создаются инструкцией set:

@set <name> <type> <value>;

Стоит обратить внимание, что переменная обязательно должна быть инициализирована, удаление аргумента value вызывает ошибку:

Текст ошибки
Текст ошибки

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

Код записи в переменную result
Код записи в переменную result
Полный вывод «компилятора», обратите внимание на строки 1 и 2
Полный вывод «компилятора», обратите внимание на строки 1 и 2

Но тут возникает интересный вопрос: можно ли сменить тип переменной при перезаписи? И ответ:

Код смены типа переменной
Код смены типа переменной
Вывод "компилятора"
Вывод «компилятора»

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

Конверсия 2 -> 2.0 недопустима
Конверсия 2 -> 2.0 недопустима

Также стоит отметить всякие странные авторские типы: Void — возвращается при ошибках, не имеет о самой ошибке никакой информации. Almost — возвращается единственной функцией is_almost, которая говорит, близко ли число к своему округлённому значению (по очень странному правилу (1.9 — не близко к 2, зато 36 — близко к 40) и без настроек). Возвращает эта функция значение из пары Almost (типа Almost)/False (типа Bool). Зачем нужен отдельный тип вместо True — непонятно. Также сюда перекочевал чисто Javascript'овский тип Infinity, возвращаемый при делении на ноль.

Часть 3. Константы

Константы создаются инструкцией define:

@define <name> <value>;

Хочу отметить отсутствие явной типизации и отсутствие ошибки при попытке перезаписи константы:

Код теста
Код теста
Вывод "компилятора"
Вывод «компилятора»

Автор в целом очень сильно недолюбливает принцип Fail Fast. Его тип Void, только мешающий отладке и не дающий никакой информации, и игнорирование очевидно ошибочных инструкций — тому подтверждение.

Часть 4. Функции

Всего в AsmX четыре вида функций: unit, method, tion, coroutine.

  • Unit — обычная функция, с поправкой на неуказываемый тип возвратного значения, отсутствующий полиморфизм и возврат через софтовые регистры языка.

  • Method — то же, что и Unit, только можно использовать внутри класса и имеет доступ к полям этого класса.

  • Tion — инновационно‑революционная разработка автора, Unit с поддержкой Ad‑Hoc полиморфизма.

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

Unit и Method пока пропустим. Первый уже полностью заменён Tion, про второй лучше говорить в контексте местного ООП. Первый наш пациент — Tion:

Пример использования Tion, его динамического возвратного типа и возврата через регистр $urt
Пример использования Tion, его динамического возвратного типа и возврата через регистр $urt
Вывод "компилятора"
Вывод «компилятора»

Первый вопрос: что за регистр такой, $urt? Он по сути своей глобальная статическая переменная Javascript с названием, расшифровывающемся, как Unit ReTurn (предположительно). Сначала хочу отметить путаницу возвратных регистров: $ret, $urt, $return. $ret — для обычных операций арифметики и тому подобного, $urt — для всех функций, $return — видимо, вообще для всего. Зачем здесь три возвратных регистра — вопрос открытый. Второй интересный вопрос — а при чём тут вообще Javascript? Всё просто: интерпретатор AsmX написан именно на нём, поэтому оттуда заимствуются некоторые вещи, такие как динамическая типизация регистров и констант, а также тип Infinity.

Хочу отметить ещё понятнейшее объяснение ошибки трейсбэком Javascript при передаче аргумента неподходящего типа в Tion.

Взглянем на локальные переменные функций в AsmX:

Пробуем скомпилировать такой код
Пробуем скомпилировать такой код

Интересующие нас вопросы: какую из переменных result вернёт первый вызов Tion, глобальную или локальную? Позаимствует ли перегрузка Tion локальную переменную у другой перегрузки или возьмёт глобальную? Изменится ли глобальная переменная при перезаписи внутри Tion? Ответ: код вообще не скомпилируется с ошибкой.

Первая перегрузка. Tion вообще не знает о существовании ни глобальной, ни локальной переменных
Первая перегрузка. Tion вообще не знает о существовании ни глобальной, ни локальной переменных

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

Код теста
Код теста
Вывод "компилятора"
Вывод «компилятора»

Хоть аргументы обрабатываются правильно, но на их тип интерпретатор совершенно не смотрит. А вывод функции через yield почему-то не значение, а тип этого значения, да ещё и не существующий в самом языке. Ещё хочу заметить, что слово number прекрасно записывается в переменную типа Float, что выглядит довольно странно на контрасте с невозможностью автоматической конверсии 1 в 1.0. Дальнейший анализ поведения функций считаю бесполезным за их ограниченной применимостью.

Часть 5. Ветвления, циклы, условные переходы

Как таковых ветвлений и циклов в AsmX нет, но есть два варианта: условные переходы и рекурсии. Начнём с условных переходов. У них есть ровно три тяжёлых недостатка: невозможность свободного перемещения по коду(нельзя выйти из функции, например), невозможность скомпилировать их даже в авторский .app «бинарник» и ужасающее влияние на время интерпретации. Насчёт скорости интерпретации можете посмотреть ещё одну статью с бенчмарками.

Если кратко, без цикла этот язык медленнее C++ в примерно 300-400 миллиардов раз, а с циклом на условном переходе — в 72.2 триллиона раз. Для разговора о рекурсии нужно сказать, что почти все условные переходы за исключением одного требуют использования меток(label), однако переход на метку, объявленную в коде позже инструкции перехода, перейти нельзя из-за интерпретируемости языка, так что ограничить рекурсию таким образом не получится. Заодно метки нельзя устанавливать внутри функций, так что возможности рекурсии снижаются ещё сильнее. Единственный условный переход, которым возможно пользоваться — с ограничением количества, он может принимать относительный адрес (не относительно начала программы, а относительно инструкции с переходом, да ещё и не в байтах или тому подобном, а в строках) вместо метки. Таким образом, одна из важнейших частей любого языка здесь практически полностью отсутствует.

Часть 6. ООП

Про него коротко. Оно сломано напрочь и до сих пор остаётся в таком состоянии на момент первой статьи. Пункт ООП по ссылке: https://telegra.ph/Razbor-fitch-yazyka-AsmX-08-16

Часть 7. Сборка

Хочется отметить, что ни в один существующий бинарный файл этот язык не компилируется. Есть только один формат — .app, придуманный самим автором. У этого формата есть один небольшой прикол: при исполнении он обратно расшифровывает его в код AsmX и интерпретирует его, замедляя выполнение в полтора раза.

Часть 8. Умения автора

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

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

Что будет с проектом, к которому сам автор так относится, лет через 5 — вопрос интересный.

Часть 9. Заключение

В этой статье я разобрал основные особенности языка AsmX и указал на их недостатки. Шуточки про странные аргументы автора и стикеры с Илоном Маском, маленькие недочёты вроде того, что парсер считает разделением блоков кода между собой не отступы, как в условном питоне, а пустые строки, что делает форматирование большого блока кода невозможным, алгоритм, гордо названный нейросетью на ровном месте, и консольное IDE, работающее хуже, чем nano, в этой статье опущены, для того чтобы указать на недостатки в ядре языка и расхождение спецификации и реальных возможностей AsmX. Для всех, кому тесты кажутся неправильными/кто хочет проверить что‑то своё, оставляю ссылку на GitHub репозиторий AsmX.

Tags:
Hubs:
Total votes 46: ↑40 and ↓6+41
Comments86

Articles