Limbo

Limbo — язык программирования в операционной системе Inferno, созданный разработчиками UNIX.

Limbo
СемантикаКонкурентное программирование
Класс языкаязык программирования
Появился в1995
АвторШон Дорвард, Фил Винтерботтом, Роб Пайк
РазработчикBell Labs
Система типовстрогая
Испытал влияниеC, CSP, Alef
Повлиял наStackless Python, Go, Rust
Сайтvitanuova.com/inferno/li…

Особенности

Язык Limbo близок Си и Java, результатом компиляции является байт-код, что обеспечивает переносимость. Переносимость же лежит в основании самой ОС Inferno (наследницы Plan 9), доведенной до состояния приложения, запускаемого поверх хост-операционной системы: Plan 9, FreeBSD, Irix, Linux, Mac OS X, Solaris, Windows NT.

Limbo имеет встроенный механизм межпроцессного взаимодействия под названием «channels».

Среди встроенных типов:

  • byte (8-разрядное целое беззнаковое число),
  • int (32-разрядное целое число со знаком),
  • big (64-разрядное целое число со знаком),
  • real (64-разрядное число с плавающей запятой),
  • array (массив со слайсами),
  • string
  • adt (Абстрактный тип данных)
  • tuple (Кортеж),
  • module

Типы данных

Помимо обычных числовых типов, структур и union, Limbo поддерживает строки и несколько более специфических типов данных: списки, массивы, tuples и каналы. (Ещё есть специальный тип "модуль", но с точки зрения особенностей языка он интереса не представляет.) Все эти типы данных это first-class variables, т.е. их можно сохранять в переменных, передавать через каналы, и т.д.

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

Строки

Строки можно преобразовывать в массивы байт, и наоборот.Кроме этого строки поддерживают срезы, т.е. можно обратиться к конкретному символу или последовательности символов, например: my_string[5:15].

Списки

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

Для работы со списками есть три оператора:

  • "::" (создание нового списка, левый операнд это один элемент, правый это список элементов того же типа)
  • hd" (возвращает первый элемент списка не меняя сам список)
  • "tl" (возвращает список состоящий из второго и последующих элементов заданного списка - т.е. "выкусывает" первый элемент)

Пример:

l : list of int;l   = 10 :: 20 :: 30 :: nil; // создаём список из 3-х элементовl   = 5 :: l;                // добавляем в начало ещё одинi  := hd l;                  // получаем int равный 5, список не изменилсяl2 := tl l;                  // получаем новый список 10 :: 20 :: 30 :: nill2  = tl l2;                 // удаляем из него первый элемент

Массивы

array содержит фиксированное кол-во элементов одного типа.Размер массива указывается при его создании/инициализации, а не при объявлении типа переменной - т.е. массивы можно динамически создавать в любой момент (когда стал известен требуемый размер массива).Фактически в Limbo только два способа динамически выделить память: создать array указав требуемый размер через переменную, и добавить новый элемент в начало list.Естественно, массивы тоже поддерживают срезы.

Tuples

Tuple - это список из 2-х и более элементов любых типов. И это не просто список, а такой же тип данных, как и другие - тип самого Tuple фактически определяется по тому, каких типов элементы и в каком порядке он содержит.Пример:

i_s : (int, string);i_s = (5, "five");// тип i_r_s_s это (int, real, string, string)i_r_s_s := (5, 0.5, "five", "comment");

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

// создаёт переменные i типа int и s типа string и// инициализирует их значениями 5 и "five"(i, s) := i_s;

Обмен значений двух переменных на Limbo:

(i, j) = (j, i);

Каналы

Каналы (chan) позволяют организовывать IPC между локальными процессами передавая атомарно объекты заданного типа.Чтение/запись канала это блокирующая операция.

c := chan of int;   // создаёт каналc <-= 10;           // отправить в каналi := <-c;           // принять из канала int<-c;                // принять и проигнорировать значениеc = nil;            // уничтожить канал

Каналы бывают буферизированные (размер буфера вы указываете примерно так же, как размер массива). Запись в буферизованные каналы не блокируется пока не будет заполнен буфер. Буфер работает как FIFO очередь.Для мультиплексирования каналов в Limbo есть целых два средства - можно читать из массива каналов, а можно использовать специальный оператор alt для выбора канала.

alt {    i := <-inchan           =>        sys->print("received:%d\n", i);    outchan <-= "message"   =>        sys->print("message sent\n");}

Составные типы

array of chan of (int, list of string)

Это массив хранящий каналы, по которым передаются tuple состоящие из int и списка строк. Размер массива здесь не определяется, он будет задан в процессе выполнения, при инициализации массива.

Unicode

Limbo использует UTF8 для I/O, и UTF16 для представления строк в памяти.Т.е., например при считывании исходника модуля с диска в нём может использоваться UTF8 в комментариях, строках и символьных константах.Если есть массив байт (array of byte) и он конвертируется в строку, то байты из массива обрабатываются как UTF8 и конвертируются в строке в UTF16; а при преобразовании строки в массив байт происходит обратное преобразование и в массиве оказывается UTF8.

Функции

Функциям можно передавать параметрами ссылки на функции.

ООП

В привычном понимании концепции ООП нет. Однако абстрактные типы данных (adt) помимо обычных типов данных в качестве элементов могут содержать связанные функции.

Потоки

Для запуска заданной функции в отдельном потоке в Limbo используется встроенный оператор spawn.

Ошибки и исключения

Поддержка исключений есть, как обычных строковых, так и пользовательских типов. Большинство системных и библиотечных функций вместо исключений для возврата ошибок используют tuple: (errcode, result).

Пример программы

Программа, выводящая «Hello, World».

implement Command;include "sys.m";include "draw.m";sys:Sys;Command: module{    init: fn (ctxt: ref Draw->Context, argv: list of string);};init(ctxt: ref Draw->Context, argv: list of string){sys = load Sys Sys->PATH;        sys->print("hello world\n");        for (; argv!=nil; argv = tl argv)               sys->print("%s ", hd argv);        sys->print("\n");}

Примечания

Ссылки


🔥 Top keywords: Заглавная страницаЯндексДуров, Павел ВалерьевичСлужебная:ПоискYouTubeЛунин, Андрей АлексеевичПодносова, Ирина ЛеонидовнаВКонтактеФоллаут (телесериал)WildberriesTelegramРеал Мадрид (футбольный клуб)Богуславская, Зоя БорисовнаДуров, Валерий СемёновичРоссияXVideosСписок умерших в 2024 годуЧикатило, Андрей РомановичFallout (серия игр)Список игроков НХЛ, забросивших 500 и более шайбПопков, Михаил ВикторовичOzon17 апреляИльин, Иван АлександровичMail.ruСёгун (мини-сериал, 2024)Слово пацана. Кровь на асфальтеПутин, Владимир ВладимировичЛига чемпионов УЕФАГагарина, Елена ЮрьевнаБишимбаев, Куандык ВалихановичЛига чемпионов УЕФА 2023/2024Турнир претендентов по шахматам 2024Манчестер СитиMGM-140 ATACMSРоссийский миротворческий контингент в Нагорном КарабахеЗагоризонтный радиолокаторПинапВодительское удостоверение в Российской Федерации