Язык программирования Seed7: особенности и примеры использования
Содержание:
1. Язык Seed7;
2.Особенности и примеры использования (Вы читаете данный раздел);
3. Библиотеки;
4. Примеры.
Что же представляет собой Seed7, похож ли он на другие языки, насколько экзотичен? Первое и основное - это расширяемый язык программирования, то есть синтаксис задается на уровне самого языка. Конечно, Seed7 присущ определенный синтаксис, однако он определен в библиотеке, а не запрограммирован жестко в коде интерпретатора либо компилятора. В библиотеки вынесено практически всё - даже поддержка типов данных. К слову, помимо «языковых» библиотек, в Seed7 предусмотрены библиотеки на все случаи жизни, но об этом чуть позже.
Теперь об основных отличиях Seed7 от других языков. Начну с того, что в нем нет списка зарезервированных слов: синтаксис языка может задаваться пользователем, хотя, конечно же, есть некоторые предустановленные конструкции. Нет оператора return - вместо него для возвращения функцией значения используется переменная result. На практике нет разницы между функцией, оператором, процедурой и выражением. Массивы могут быть параметрами функций. Нет автоматического приведения типов. Строки могут иметь бесконечную длину. Бесконечное число для значащих символов в идентификаторах.
Простейший пример на Seed7 таков:
В первой строке (include) мы подключаем стандартную библиотеку Seed7, где кроме прочего определено, что функция main - точка входа в программу, а writeln - оператор для вывода текстовой строки. Затем идет строка (const proc: main is), которая означает константный объект main типа proc. Далее - пусть вас не запутает знание Паскаля - в Seed7 для определения функции или процедуры служит конструкция:
Это может выглядеть так:
А может - так:
Слово func - это начало функции, end func - конец. Между ними может быть еще begin, а также local для объявления переменных. Вот тот же пример, но с объявлением строки s_string со значением Hello world и её передачей в качестве параметра для writeln:
Как видите, программы на Seed7 (в его «предустановленном» варианте) несколько похожи на Pascal. Схожесть проявляется не только в синтаксисе, но и, например, в способе объявления параметров. В Pascal, если функция не может изменять значение параметра, то параметр объявляется без всякого, а если может, то с var:
В Seed7 неизменяемый параметр начинается со слова in, а изменяемый - inout:
✓ параметр можно использовать только как константу:
✓ значение параметра можно менять внутри функции, и это изменение будет действовать и вне её пределов:
✓ значение можно менять внутри функции, изменения не выйдут за пределы её тела:
Новые синтаксические конструкции также объявляются подобно функциям. Приведу пример из документации. Вдобавок к обычным циклам while и repeat/until добавим loop, который позволяет выполнять выход из цикла в его середине. Пример использования loop:
Здесь мы читаем посимвольно из файла до тех пор, пока не встретится символ новой строки. Пока он не встречается, добавляем символ к строке stri. Чтобы добавить в язык новую конструкцию цикла loop, надо определить её так:
Чтобы интерпретатор «подхватил» такое определение, надо еще добавить строку:
Я не останавливаюсь на подробностях, поскольку стремлюсь осветить наиболее интересные стороны Seed7. Есть ли в этом языке поддержка объектно-ориентированного программирования? Да, но выглядит непривычно. В Seed7 введена концепция интерфейсов и воплощений (implementations). Интерфейс в Seed7 можно очень грубо соотнести с абстрактным классом в других языках программирования. А воплощения - это производные от интерфейса классы, реализующие ту или иную функциональность. Например, может быть интерфейс чтения растровых картинок - Raster, определяющий некий общий набор функций: чтение, запись, предоставление доступа к данным изображения. И несколько воплощений - отдельно для форматов вроде PNG, JPEG, TIFF.
Пример:
Функции draw всё равно, что рисовать - лишь бы ей был передан параметр с воплощением интерфейса Raster. А вот воплощение:
Теперь свяжем интерфейс и воплощение:
И напишем функцию-воплощение именно для PNG:
Структуры могут наследовать поля родителей. Вот как можно объявить потомка структуры ClassA, дополнив его строковым полем s:
Общие замечания по ООП в Seed7: полиморфизм и наследование работают, но их поддержка осуществляется за счет функций и структур - в общем, похоже на «ООП без ООП» в GTK+ (структуры + функции), но всё же с большим уклоном в традиционное ООП.
Следует так же отметить, что для изучения Seed7 прекрасно подойдет компьютер для начинающих (http://Rumman.ru). Данный язык программирования не требует затрат больших ресурсов, в результате чего является идеальным решением для начинающих программистов. Впрочем, это не меняет того факта, что при помощи Seed7 Вы сможете создать действительно качественный программный продукт!
1. Язык Seed7;
2.
3. Библиотеки;
4. Примеры.
Что же представляет собой Seed7, похож ли он на другие языки, насколько экзотичен? Первое и основное - это расширяемый язык программирования, то есть синтаксис задается на уровне самого языка. Конечно, Seed7 присущ определенный синтаксис, однако он определен в библиотеке, а не запрограммирован жестко в коде интерпретатора либо компилятора. В библиотеки вынесено практически всё - даже поддержка типов данных. К слову, помимо «языковых» библиотек, в Seed7 предусмотрены библиотеки на все случаи жизни, но об этом чуть позже.
Теперь об основных отличиях Seed7 от других языков. Начну с того, что в нем нет списка зарезервированных слов: синтаксис языка может задаваться пользователем, хотя, конечно же, есть некоторые предустановленные конструкции. Нет оператора return - вместо него для возвращения функцией значения используется переменная result. На практике нет разницы между функцией, оператором, процедурой и выражением. Массивы могут быть параметрами функций. Нет автоматического приведения типов. Строки могут иметь бесконечную длину. Бесконечное число для значащих символов в идентификаторах.
Простейший пример на Seed7 таков:
$ include "seed7_05.s7i";
const proc: main is
func
begin
writeln ("hello world");
end func;
const proc: main is
func
begin
writeln ("hello world");
end func;
В первой строке (include) мы подключаем стандартную библиотеку Seed7, где кроме прочего определено, что функция main - точка входа в программу, а writeln - оператор для вывода текстовой строки. Затем идет строка (const proc: main is), которая означает константный объект main типа proc. Далее - пусть вас не запутает знание Паскаля - в Seed7 для определения функции или процедуры служит конструкция:
func
end func;
end func;
Это может выглядеть так:
func
begin
end func;
begin
end func;
А может - так:
func
begin
end func;
begin
end func;
Слово func - это начало функции, end func - конец. Между ними может быть еще begin, а также local для объявления переменных. Вот тот же пример, но с объявлением строки s_string со значением Hello world и её передачей в качестве параметра для writeln:
$ include "seed7_05.s7i";
const proc: main is
func
local
var string: s_hello is "Hello world"; begin
writeln (s_hello); end func;
const proc: main is
func
local
var string: s_hello is "Hello world"; begin
writeln (s_hello); end func;
Как видите, программы на Seed7 (в его «предустановленном» варианте) несколько похожи на Pascal. Схожесть проявляется не только в синтаксисе, но и, например, в способе объявления параметров. В Pascal, если функция не может изменять значение параметра, то параметр объявляется без всякого, а если может, то с var:
function foo (a: integer; var b: integer)
В Seed7 неизменяемый параметр начинается со слова in, а изменяемый - inout:
✓ параметр можно использовать только как константу:
const func integer: foo (in integer: a)
✓ значение параметра можно менять внутри функции, и это изменение будет действовать и вне её пределов:
const func integer: foo (inout integer: a)
✓ значение можно менять внутри функции, изменения не выйдут за пределы её тела:
const func integer: foo (in var integer: a)
Новые синтаксические конструкции также объявляются подобно функциям. Приведу пример из документации. Вдобавок к обычным циклам while и repeat/until добавим loop, который позволяет выполнять выход из цикла в его середине. Пример использования loop:
loop
ch := getc (inFile); until ch = 'n' do
stri & := str (ch);
end loop;
ch := getc (inFile); until ch = 'n' do
stri & := str (ch);
end loop;
Здесь мы читаем посимвольно из файла до тех пор, пока не встретится символ новой строки. Пока он не встречается, добавляем символ к строке stri. Чтобы добавить в язык новую конструкцию цикла loop, надо определить её так:
const proc: loop
(in proc: statements].) until (ref func boolean: condition) do
(in proc: statements2) end loop is func
local
var boolean: exitLoop is FALSE;
begin repeat
statements].;
if not condition then
statements2; else
exitLoop := TRUE;
end if;
until exitLoop;
end func;
(in proc: statements].) until (ref func boolean: condition) do
(in proc: statements2) end loop is func
local
var boolean: exitLoop is FALSE;
begin repeat
statements].;
if not condition then
statements2; else
exitLoop := TRUE;
end if;
until exitLoop;
end func;
Чтобы интерпретатор «подхватил» такое определение, надо еще добавить строку:
$ syntax expr: .loop.().until.().do.().end.loop is -> 25;
Я не останавливаюсь на подробностях, поскольку стремлюсь осветить наиболее интересные стороны Seed7. Есть ли в этом языке поддержка объектно-ориентированного программирования? Да, но выглядит непривычно. В Seed7 введена концепция интерфейсов и воплощений (implementations). Интерфейс в Seed7 можно очень грубо соотнести с абстрактным классом в других языках программирования. А воплощения - это производные от интерфейса классы, реализующие ту или иную функциональность. Например, может быть интерфейс чтения растровых картинок - Raster, определяющий некий общий набор функций: чтение, запись, предоставление доступа к данным изображения. И несколько воплощений - отдельно для форматов вроде PNG, JPEG, TIFF.
Пример:
# Объявляем интерфейс Raster
const type: Raster is new interface;
# Объявляем функцию отрисовки картинки
const proc: draw (in Raster image) is DYNAMIC;
const type: Raster is new interface;
# Объявляем функцию отрисовки картинки
const proc: draw (in Raster image) is DYNAMIC;
Функции draw всё равно, что рисовать - лишь бы ей был передан параметр с воплощением интерфейса Raster. А вот воплощение:
const type: PNG is new struct
var integer: width is 0;
var integer: height is 0;
# и так далее
end struct;
var integer: width is 0;
var integer: height is 0;
# и так далее
end struct;
Теперь свяжем интерфейс и воплощение:
type_implements_interface (PNG, Raster);
И напишем функцию-воплощение именно для PNG:
const proc: draw (in PNG: image) is func
begin
# Как-то рисуем image
end func;
begin
# Как-то рисуем image
end func;
Структуры могут наследовать поля родителей. Вот как можно объявить потомка структуры ClassA, дополнив его строковым полем s:
const type: ClassB is sub ClassA
var string: s is "hello world";
end struct;
var string: s is "hello world";
end struct;
Общие замечания по ООП в Seed7: полиморфизм и наследование работают, но их поддержка осуществляется за счет функций и структур - в общем, похоже на «ООП без ООП» в GTK+ (структуры + функции), но всё же с большим уклоном в традиционное ООП.
Следует так же отметить, что для изучения Seed7 прекрасно подойдет компьютер для начинающих (http://Rumman.ru). Данный язык программирования не требует затрат больших ресурсов, в результате чего является идеальным решением для начинающих программистов. Впрочем, это не меняет того факта, что при помощи Seed7 Вы сможете создать действительно качественный программный продукт!