Limbo: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[отпатрулированная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
м r2.6.5) (робот добавил: zh:Limbo
м Списки: опечатка, забыты кавычки
 
(не показано 27 промежуточных версий 22 участников)
Строка 1: Строка 1:
{{другие значения|Limbo (значения)}}
{{Карточка языка программирования
{{Карточка языка программирования
|name = Limbo
| name = Limbo
|logo =
| logo =
|semantics = [[Конкурентное программирование]]
| semantics = [[Конкурентное программирование]]
|year = [[1995]]
| year = [[1995]]
|designer = Шон Дорвард, Фил Винтерботтом, Роб Пайк
| designer = Шон Дорвард, Фил Винтерботтом, Роб Пайк
|typing = [[Строгая типизация|строгая]]
| typing = [[Строгая типизация|строгая]]
|implementations =
| implementations =
|dialects =
| dialects =
|influenced_by = [[Си (язык программирования)|C]], [[CSP]], [[Alef]]
| influenced_by = [[Си (язык программирования)|C]], [[Communicating Sequential Processes|CSP]], [[Alef]]
|influenced = [[Stackless Python]], [[Go]]
| influenced = [[Stackless Python]], [[Go]], [[Rust (язык программирования)|Rust]]
|website = [http://www.vitanuova.com/inferno/limbo.html http://www.vitanuova.com/inferno/limbo.html]
| website = http://www.vitanuova.com/inferno/limbo.html
}}
}}
{{другие значения|Limbo (значения)}}
'''Limbo''' — [[язык программирования]] в [[операционная система|операционной системе]] [[Inferno (операционная система)|Inferno]], созданный разработчиками [[UNIX]].
'''Limbo''' — [[язык программирования]] в [[операционная система|операционной системе]] [[Inferno (операционная система)|Inferno]], созданный разработчиками [[UNIX]].


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

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


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


Среди встроенных типов:
Среди встроенных типов:
* byte (8-разрядное целое беззнаковое число),
* byte (8-bit unsigned),
* int (32-разрядное целое число со знаком),
* int (32-bit signed),
* big (64-разрядное целое число со знаком),
* big (64-bit signed),
* real (64-разрядное число с плавающей запятой),
* real (64-bit floating point),
* array (массив со [[:en:Array_slicing|слайсами]]),
* array (массив со [[:en:Array slicing|слайсами]]),
* string
* string
* adt ([[Абстрактный тип данных]])
* adt ([[Абстрактный тип данных]])
* tuple ([[Кортеж]]),
* tuple ([[Кортеж (информатика)|Кортеж]]),
* module
* module


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

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


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


* "::" (создание нового списка, левый операнд это один элемент, правый это список элементов того же типа)
* "::" (создание нового списка, левый операнд это один элемент, правый это список элементов того же типа)
* "hd" (возвращает первый элемент списка не меняя сам список)

* hd" (возвращает первый элемент списка не меняя сам список)

* "tl" (возвращает список состоящий из второго и последующих элементов заданного списка - т.е. "выкусывает" первый элемент)
* "tl" (возвращает список состоящий из второго и последующих элементов заданного списка - т.е. "выкусывает" первый элемент)
Пример:
Пример:
Строка 67: Строка 65:


=== Tuples ===
=== Tuples ===
Tuple - это список из 2-х и более элементов любых типов. И это не просто список, а такой же тип данных, как и другие - тип самого Tuple фактически определяется по тому, каких типов элементы и в каком порядке он содержит.
Tuple - это список из 2-х и более элементов любых типов. И это не просто список, а такой же тип данных, как и другие - тип самого Tuple фактически определяется по тому, каких типов элементы и в каком порядке он содержит.
Пример:
Пример:
<source lang="cpp">
<source lang="cpp">
Строка 75: Строка 73:
i_r_s_s := (5, 0.5, "five", "comment");
i_r_s_s := (5, 0.5, "five", "comment");
</source>
</source>
Tuple можно раскладывать на составляющие присваивая его в список обычных переменных:
Tuple можно раскладывать на составляющие, присваивая его в список обычных переменных:
<source lang="cpp">
<source lang="cpp">
// создаёт переменные i типа int и s типа string и
// создаёт переменные i типа int и s типа string и
Строка 101: Строка 99:
alt {
alt {
i := <-inchan =>
i := <-inchan =>
sys->print("received: %d\n", i);
sys->print("received:%d\n", i);
outchan <-= "message" =>
outchan <-= "message" =>
sys->print("message sent\n");
sys->print("message sent\n");
Строка 123: Строка 121:
В привычном понимании концепции ООП нет. Однако абстрактные типы данных (adt) помимо обычных типов данных в качестве элементов могут содержать связанные функции.
В привычном понимании концепции ООП нет. Однако абстрактные типы данных (adt) помимо обычных типов данных в качестве элементов могут содержать связанные функции.


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


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


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

Программа, выводящая «[[Hello, World]]».
Программа, выводящая «[[Hello, World]]».
implement Command;
implement Command;
Строка 147: Строка 144:
sys->print("%s ", hd argv);
sys->print("%s ", hd argv);
sys->print("\n");
sys->print("\n");
}
}


== Ссылки ==
== Ссылки ==

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


{{Языки программирования}}
{{Языки программирования}}
{{Роб Пайк}}


[[Категория:Языки программирования семейства C]]
[[Категория:Языки программирования семейства Си]]
[[Категория:Inferno]]
[[Категория:Inferno]]

[[ar:ليمبو (لغة برمجة)]]
[[de:Limbo (Programmiersprache)]]
[[en:Limbo (programming language)]]
[[es:Limbo (lenguaje de programación)]]
[[fr:Limbo (langage)]]
[[ja:Limbo]]
[[pl:Limbo (język programowania)]]
[[pt:Limbo (linguagem de programação)]]
[[sv:Limbo (programspråk)]]
[[zh:Limbo]]

Текущая версия от 08:19, 20 ноября 2024

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

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, т.е. их можно сохранять в переменных, передавать через каналы, и т.д.

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

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

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 и списка строк. Размер массива здесь не определяется, он будет задан в процессе выполнения, при инициализации массива.

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");
}