Limbo

Поделись знанием:
Перейти к: навигация, поиск
Limbo
Семантика:

Конкурентное программирование

Появился в:

1995

Автор:

Шон Дорвард, Фил Винтерботтом, Роб Пайк

Система типов:

строгая

Испытал влияние:

C, CSP, Alef

Повлиял на:

Stackless Python, Go

Сайт:

[www.vitanuova.com/inferno/limbo.html anuova.com/inferno/limbo.html]

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





Особенности

Язык 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, т.е. их можно сохранять в переменных, передавать через каналы, etc. Обычные числовые типы можно преобразовывать друг в друга, кроме того строки тоже можно преобразовывать в числа и наоборот. Но все преобразования должны указываться явно, неявных преобразований типов нет.

Строки

Строки можно преобразовывать в массивы байт, и наоборот. Кроме этого строки поддерживают срезы, т.е. можно обратиться к конкретному символу или последовательности символов, например: 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 :: nil
l2  = 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");
}

Напишите отзыв о статье "Limbo"

Ссылки

  • doc.cat-v.org/inferno/4th_edition/limbo_language/ The Limbo Programming Language — описание языка

Отрывок, характеризующий Limbo

– Ah! Il m'aime tant! – сказала Элен, которой почему то казалось, что Пьер тоже ее любил. – Il fera tout pour moi. [Ах! он меня так любит! Он на все для меня готов.]
Билибин подобрал кожу, чтобы обозначить готовящийся mot.
– Meme le divorce, [Даже и на развод.] – сказал он.
Элен засмеялась.
В числе людей, которые позволяли себе сомневаться в законности предпринимаемого брака, была мать Элен, княгиня Курагина. Она постоянно мучилась завистью к своей дочери, и теперь, когда предмет зависти был самый близкий сердцу княгини, она не могла примириться с этой мыслью. Она советовалась с русским священником о том, в какой мере возможен развод и вступление в брак при живом муже, и священник сказал ей, что это невозможно, и, к радости ее, указал ей на евангельский текст, в котором (священнику казалось) прямо отвергается возможность вступления в брак от живого мужа.
Вооруженная этими аргументами, казавшимися ей неопровержимыми, княгиня рано утром, чтобы застать ее одну, поехала к своей дочери.
Выслушав возражения своей матери, Элен кротко и насмешливо улыбнулась.
– Да ведь прямо сказано: кто женится на разводной жене… – сказала старая княгиня.
– Ah, maman, ne dites pas de betises. Vous ne comprenez rien. Dans ma position j'ai des devoirs, [Ах, маменька, не говорите глупостей. Вы ничего не понимаете. В моем положении есть обязанности.] – заговорилa Элен, переводя разговор на французский с русского языка, на котором ей всегда казалась какая то неясность в ее деле.
– Но, мой друг…
– Ah, maman, comment est ce que vous ne comprenez pas que le Saint Pere, qui a le droit de donner des dispenses… [Ах, маменька, как вы не понимаете, что святой отец, имеющий власть отпущений…]
В это время дама компаньонка, жившая у Элен, вошла к ней доложить, что его высочество в зале и желает ее видеть.
– Non, dites lui que je ne veux pas le voir, que je suis furieuse contre lui, parce qu'il m'a manque parole. [Нет, скажите ему, что я не хочу его видеть, что я взбешена против него, потому что он мне не сдержал слова.]
– Comtesse a tout peche misericorde, [Графиня, милосердие всякому греху.] – сказал, входя, молодой белокурый человек с длинным лицом и носом.
Старая княгиня почтительно встала и присела. Вошедший молодой человек не обратил на нее внимания. Княгиня кивнула головой дочери и поплыла к двери.
«Нет, она права, – думала старая княгиня, все убеждения которой разрушились пред появлением его высочества. – Она права; но как это мы в нашу невозвратную молодость не знали этого? А это так было просто», – думала, садясь в карету, старая княгиня.

В начале августа дело Элен совершенно определилось, и она написала своему мужу (который ее очень любил, как она думала) письмо, в котором извещала его о своем намерении выйти замуж за NN и о том, что она вступила в единую истинную религию и что она просит его исполнить все те необходимые для развода формальности, о которых передаст ему податель сего письма.
«Sur ce je prie Dieu, mon ami, de vous avoir sous sa sainte et puissante garde. Votre amie Helene».
[«Затем молю бога, да будете вы, мой друг, под святым сильным его покровом. Друг ваш Елена»]
Это письмо было привезено в дом Пьера в то время, как он находился на Бородинском поле.


Во второй раз, уже в конце Бородинского сражения, сбежав с батареи Раевского, Пьер с толпами солдат направился по оврагу к Князькову, дошел до перевязочного пункта и, увидав кровь и услыхав крики и стоны, поспешно пошел дальше, замешавшись в толпы солдат.
Одно, чего желал теперь Пьер всеми силами своей души, было то, чтобы выйти поскорее из тех страшных впечатлений, в которых он жил этот день, вернуться к обычным условиям жизни и заснуть спокойно в комнате на своей постели. Только в обычных условиях жизни он чувствовал, что будет в состоянии понять самого себя и все то, что он видел и испытал. Но этих обычных условий жизни нигде не было.
Хотя ядра и пули не свистали здесь по дороге, по которой он шел, но со всех сторон было то же, что было там, на поле сражения. Те же были страдающие, измученные и иногда странно равнодушные лица, та же кровь, те же солдатские шинели, те же звуки стрельбы, хотя и отдаленной, но все еще наводящей ужас; кроме того, была духота и пыль.
Пройдя версты три по большой Можайской дороге, Пьер сел на краю ее.
Сумерки спустились на землю, и гул орудий затих. Пьер, облокотившись на руку, лег и лежал так долго, глядя на продвигавшиеся мимо него в темноте тени. Беспрестанно ему казалось, что с страшным свистом налетало на него ядро; он вздрагивал и приподнимался. Он не помнил, сколько времени он пробыл тут. В середине ночи трое солдат, притащив сучьев, поместились подле него и стали разводить огонь.
Солдаты, покосившись на Пьера, развели огонь, поставили на него котелок, накрошили в него сухарей и положили сала. Приятный запах съестного и жирного яства слился с запахом дыма. Пьер приподнялся и вздохнул. Солдаты (их было трое) ели, не обращая внимания на Пьера, и разговаривали между собой.
– Да ты из каких будешь? – вдруг обратился к Пьеру один из солдат, очевидно, под этим вопросом подразумевая то, что и думал Пьер, именно: ежели ты есть хочешь, мы дадим, только скажи, честный ли ты человек?
– Я? я?.. – сказал Пьер, чувствуя необходимость умалить как возможно свое общественное положение, чтобы быть ближе и понятнее для солдат. – Я по настоящему ополченный офицер, только моей дружины тут нет; я приезжал на сраженье и потерял своих.
– Вишь ты! – сказал один из солдат.
Другой солдат покачал головой.
– Что ж, поешь, коли хочешь, кавардачку! – сказал первый и подал Пьеру, облизав ее, деревянную ложку.
Пьер подсел к огню и стал есть кавардачок, то кушанье, которое было в котелке и которое ему казалось самым вкусным из всех кушаний, которые он когда либо ел. В то время как он жадно, нагнувшись над котелком, забирая большие ложки, пережевывал одну за другой и лицо его было видно в свете огня, солдаты молча смотрели на него.