← All posts tagged ada

Неприятные моменты C
Когда в команде Evolution всё шло наперекосяк. Нам тогда пришлось купить машину Solaris просто чтобы иметь возможность купить Purify; тогда не было Valgrind.
В Вилларибо просто компилируют бесплатным GNAT со включенными проверками, а в виллабаджо ищут, на каком бы платном Солярисе отладить под платным Purify

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

Идёт какая-то прямо неделя принятия моих наработок в открытые проекты

I've uploaded JVM-GNAT for macOS, see
Thanks to you, I could put inside Java API files.
В оригинале документация и примеры для JGNAT не была рассчитана на проекты GPR, была устаревшая система по типу Search Directories в Делфях или include path в C, а привязки, хотя и генерировались разные, но использовались только те, что подключены. А я сделал проект, и привязки тоже проектом, и пока пытался собрать проект привязок, повылезали ошибки в случаях, когда для абстрактного метода стояла pragma Import вместо pragma Export, а также конфликты имён в разном регистре, которые генератор привязок сам не переварил. По результатам разруливания для всех стандартных Java API есть рабочие привязки. Это и приняли.

Пакет (Binding) Ada2012 Unicode NCURSES под Windows
Тут пригодился мой шаблон проекта

Работа Ada Web Server Client TLS через прокси починена

Допилил CheerpJ и JGNAT друг под друга

Посмотреть можно здесь

Пока что вижу: насчёт многозадачности — правда. Я думал, это фишка простого Cheerp, а раз в простом Cheerp нету асинхронизатора, то это всё может работать только на SharedArrayBuffer и не везде. Но нет. Планировщик находится в loader.js от CheerpJ и, насколько я могу судить, работает. В том числе можно динамически подгружать классы, и они грузятся (с поддержкой AOT) по сети, и исполнение зелёного потока продолжается с момента остановки. EmScripten так не умеет, там только синхронным XHR можно с файловой системой работать, и только в Web Workers, в общем, без асинхронизатора это ни о чём.

Вместе со Swing там, похоже, даже движок текста свой подгружается. Антиалиасинг явно получше, чем в браузере. Но время запуска будь здоров. Хотя большая часть сейчас зависит от производителя. Если они там у себя что-нибудь подкрутят, васм внедрят, например, ведь Cheerp умеет, то есть, куда ужаться. Просто начинать с тем, что есть, а оно само будет улучшаться.

Об исключенных командах или за что «списали» инструкцию INTO?
Любопытно было почитать материал от разработчика компилятора, способного выжимать из процессора максимум. Ещё @Tajunu писал про ущербность LLVM по сравнению с TenDRA, но так, достаточно поверхностно, а тут — от того, кто реально в теме.

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

ada

Вот как же досадно, что русские адаисты — одновременно… того. То @Strephil берега попутал. То @Tajunu , о чьём гражданстве сроду никогда раньше не задумывался, оказался с Украины, и не просто с Украины, а «Слава Украине», известно, кто — известно, кто, и вообще полный привет. Чё-т как-то не очень помогла йога просветлению. И для полного счастья они ещё и про Аду стали всё меньше писать, а всё больше именно… того. Одному мне за всех адаистов приходится отдуваться.

У AdaCore обновилась страница загрузки GNAT
На один дебилизм стало меньше. Раньше у них выбор начинался с года, а потом шли платформы. Если в каком-то году нет платормы, то её даже в списке не было. Потом сделали, чтоб было, но серого цвета. Это касается всяких экспериментальных платформ типа LEGO NXT MindStorm, на смену которому пришёл ARM для голых досок. А также JVM и CLI, которые кроме гуглострадальцев (AppEngine) оказались почти никому не нужны, когда есть нормальные (нативные) компиляторы. Если всё же хочешь скачать, перебирай разные года, пока не найдёшь нужный. Сейчас, если зайти в more platforms, все платформы в списке можно выбрать, и сам выбирается наибольший год выпуска.

Я бы ещё SPARK до 2012го года включительно отдельно выделял, потому что в старом СПАРКе аннотации для верификатора в комментариях специального вида пишутся, и это совместимо с, например, MapuSoft AdaMagic, BTC ObjectAda, BTC Apex Ada, Janus Ada, Irvine и пр. застрявшими между Ada 95 и Ada 2005, а аннотации SPARK 2014 пишутся в аспектах, которые поддерживает только GNAT. Понятно, что AdaCore не сильно заинтересованы в поддержке конкурентов.

Ещё заметил, что на страницу загрузки теперь можно попасть, не оставляя свой email.

Теперь, наверное, самым ожидаемым был бы кроссплатформенный пакетный менеджер с онлайн базой данных. Это было бы логичным продолжением линии развития gnatmake => gprmake => gprbuild+gprinstall. Даже в Делфи свой уже появился.

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

Много лет спустя пишу на Аде и обращаю внимание на то, что пишу практически в стиле единственного присваивания, благо адский declare-begin-end позволяет, и благо, начиная с Ada 2012 всё больше вещей можно записать выражениями. В этом плане Делфи уступает даже 83ей Аде. По принципу наименьших прав большинство значений между declare и begin — константы, и строки — соответственно, тоже. Кроме того, хотя есть Делфи-подобные строки (Unbounded_String в стандартной библиотеке и Universal_String в Матрёшке Вадима Годунко) со счётчиком ссылок, быстрее всего работают строки, размещаемые на стеке. Это которые самый обычный type String is array (Positive range <>) of Character, по принципу действия похожий на вариадические массивы в C99 и alloca(). После размещения на стеке у них размер поменять нельзя, а, значит, и нет особого смысла им не быть константой. И так получилось разделение на де факто немутируемые обычные строки и мутируемые строки в динамической памяти, похоже на String и StringBuilder .NET.

В каком-то смысле вернулся к тому, с чего начинал, с поправкой на то, что Unbounded_String как значение вполне себе пригоден для хранения в записях, массивах и контейнерах, в отличие от.

Попробовал GNAT 2017. Пишут, что там Ada 2020 уже начата. Первое, что приходит в голову:
Current_Amount := @ + Amount_To_Read;… работает. Вроде там ещё был новый синтаксис агрегата для инициализации матриц функцией от индексов. Остальное либо уже сделано, либо не будет сделано в собственно языке по идеологическим причинам.

Что больше всего понравилось — так это то, что ASIS4GNAT, GNATCOLL, XMLAda и AWS предкомпилированы, а то как-то раньше тупо было. Раньше надо было ставить не входящий в комплект MSYS или MSYS2, ставить не входящий в комплект make, и на них собирать AWS, GNATCOLL и пр. И объяснять, как это делать, желающим пересобрать твою программу.

Почему-то компилятор жутко тупит над производными типами. Вот, например, type TDateTime = type Double. Логично сделать так:

TDateTime(SysUtils.StrToFloat(…))Ан нет, E2089 Invalid typecast. Может, проблема в том, что результат StrToFloat — Extended, а не Double?
TDateTime(Double(SysUtils.StrToFloat(…)))Всё равно E2089 Invalid typecast. Да как же так? Сам ты инвалид!

Что самое удивительное, работает, если приведение типа НЕ ДЕЛАТЬ:
SysUtils.FormatDateTime(…, SysUtils.StrToFloat(…))Вот так компилируется и само приводится сквозь все Extended, Double и TDateTime, хотя я бы сильно не хотел, чтоб число с плавающей точкой случайно могло стать OLE датой/временем.

Ещё это сильно мешает привязки делать. По привычке возьмёшь напишешь type TPluginItem = type Pointer, и начинает тебе компилятор мозг выедать на ровном месте, а на неровном — соответственно, не выедать. Плюнешь, переделаешь в указатель на пустую запись с уникальным именем. Вот теперь получился указатель, который «не похож» на произвольно взятый другой указатель, но, к сожалению, всё ещё похож на указатель, чего лишний раз не хотелось бы, и от чего производный тип должен был спасти. Гипотетически для непохожести можно завернуть ещё дополнительно в запись, но тогда может сломаться работа с внешней библиотекой, ибо Delphi получает запись-результат всегда через дополнительный указатель, даже если она меньше размера двух указателей, как предписано stdcall. И тем более результат с плавающей точкой таким образом не приедет через регистр сопроцессора.

А вот на Аде берёшь и пишешь type OLE_Date_Time is new Long_Float или type Plugin_Item_Type is new Address, и работает это именно так, как ожидаешь. Одно в другое случайно не сконвертируется, а по требованию — всегда пожалуйста, без этих дурацких непонятных ошибок. И, конечно, на Аде, когда пишешь пакет, можно просто написать в публичной части type Plugin_Item_Type is private, и всё, внутреннее устройство для внешнего мира становится непрозрачно. Если нужно, функции конвертации из/в Address можно написать в дочернем пакете, чтоб глаза не мозолило в родительском. А то в Delphi, C и C++ вечно свалка в пространстве имён, хочется закрыться руками от падающих отовсюду в пространство имён гор мусора.

Увидел среди новых TLD .ads, пока без возможности регистрации. Наверное, хорошо подходит для адских библиотек, там по широко принятому соглашению .ads = ADa Specification, человеческий аналог заголовочных файлов.

Почитал сорцы в linuxrtl, бросилось в глаза MarshaledAString вместо PAnsiChar. Открыл System.pas, нашёл там при включенном NEXTGEN такое:
_PAnsiChr = _PAnsiChar;
MarshaledAString = _PAnsiChr;
При этом _PAnsiChar не объявляется, то есть, он встроенный. Без NEXTGEN _PAnsiChr = привычному PAnsiChar. Напрашивается мнение, что из MarshaledAString пытаются лепить типа-не-указатель, который надо класть в System.TMarshal. Судя по тому, что WriteLn(X) и X[0] := '2' компилируются, природа этого типа пока ещё не совсем замаскирована.

Также огорчило, что до сих пор нет нормальных 32битных символов и строк. В языке Ада они уже 12 лет как появились как неотъемлемая часть стандарта. Как можно идти на Линукс без 32битных строк? В API открытых библиотек Юникод, сколько я видел, любой libidn возьми, всегда представлен 32битными строками. Открыл System.pas, увидел там type UCS4Char = type Cardinal для всех платформ, где Cardinal — это беззнаковое 32-битное целое, а type … = type … в Делфи делает новый тип, не совместимый со старым без приведения типа, аналог адского type … is new …

Ещё посмотрев по сторонам, нашёл StdDefTypes.inc , а в нём — type wchar_t = Int32

Ни методов TMarshal, ни попыток аналогично скрыть указатель вроде Marshaled32String, ничего такого. Высокопоставленные китайские чиновники с именами из иероглифов за пределами BMP, а также все причастные, которым текст с этими именами надо обрабатывать, не одобряют это.

Windows 10 Creators Update: что нового в Bash/WSL и Windows Console
В то время как Win10 Anniversary Update поставлялся с поддержкой Ubuntu 14.04, в новом обновлении Win10 CU теперь WSL поддерживает Ubuntu 16.04.То есть, если хочется писать на Аде под роутер на MIPSe, теперь не надо искать, как бы так обновить встроенную Ubuntu до 15, чтобы не сломать.

Главой целью создания WSL было уменьшить «разрыв» по ощущениям, когда запускаешь инструменты Windows рядом с инструментами командной строки и окружениями Linux. Когда мы выпустили WSL в Windows 10 AU, то поместили Linux и Windows рядом друг с другом, но всё ещё был большой «разрыв» между ними — хотя обе системы могли иметь совместный доступ к некоторым файлам, каждое из окружений было довольно сильно изолировано от другого. Пользователи часто говорили, что хотят иметь возможность запускать приложения Windows и консоли Bash, и запускать приложения Linux и Windows. Так что мы добавили эту функцию! В Windows 10 Creators Update вы можете запускать приложения и инструменты Windows из консоли Bash.
Как раз то, чего не хватало. А то хочется dcclinux64.exe вызвать из линуксовых скриптов, а никак, или хочешь прямо из ФАРа запускать mips-linux-gnu-gnatmake и не можешь, тоже не очень здорово. Да, я знаю, что можно через plink и XMing как минимум в одну сторону срастить, и у меня Windows 2003 и Debian в соседних доменах Xen так и живут. А тут-то из коробки теперь. Удивительно видеть, как Microsoft опережает Apple в том, чтобы поддерживать Linux.

Ещё одной частой просьбой сообщества была поддержка в консоли больше чем 16 цветов. Поддержка 256 цветов и более очень важна при работе с современными всё более сложными и насыщенными инструментами командной строки, шеллами и т. д. В Win10 Creators Update консоль обновилась и поддерживает полный, прекрасный 24-битный цвет!
Я даже побежал в MSDN смотреть, какое там новое Console API для этого дела. Но не увидел. Тут советуют начинать любить Escape-последовательности. Эм, а как же гасить панели во всяких ФАР Менеджерах, если мы не можем прочитать буфер и потом восстановить его? Или теперь предлагаете буфер на виртуальном экране ncurses хранить? Вот так поворот.

В общем, пошёл обновляться.

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

TestValue := TCalDayOfWeek(20);Такой оператор молча проглотил ошибку, что меня как адиста, конечно, возмущает.
TestValue := dowMonday + 20;Такой оператор не компилируется, но направление мысли было верным. Ещё немного подумав, я нашёл ближайший аналог на Делфи:
TestValue := dowMonday;
Inc(TestValue, 20);
В этом случае бросается ERangeCheckError, что и требовалось.

На Аде я бы написал TCalDayOfWeek'Val (выражение) без необходимости во временной переменной.

Но в языке Ада, наоборот, нет такого всеядного Inc, как в Делфи. Как адаисту, мне кажется, что это чаще разумно, чем нет. Если перечисляемый тип гоняется в число и обратно, пусть это всё в явном виде будет написано. А вдруг написан бред? Когда всё потенциально бредовое требуется в явном виде расписать, заметить бредовость легче.

В обоих языках появились конструкции для удобного перебора коллекций. for-in-do в Делфи и for-of-loop в языке Ада. Но в языке Ада можно и нужно возвращать ссылочный тип, и под такой перебор не нужно объявлять переменную, а в Делфи — нужно, и нужно именно затем, что оно всё будет при переборе постоянно копироваться и уничтожаться, хоть там какой развесистый record внутри. Но зато при переборе стандартного System.Generics.Collections.TDictionary в Делфи перебираем пары ключ-значение, а при переборе стандартного Ada.Containers.Hashed_Maps — только сами значения.