Pike

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 23:55, 8 июня 2016.
Pike
Парадигма мультипарадигмный: объекто-ориентированный, функциональный, процедурный
Спроектировано Фредрих Хубинет
Разработчики Department of Computer and Information Science (IDA) at Linköping University
Печать дисциплины статическая, динамическая, манифестная
OS Unix, Windows
Лицензия GPL/LGPL/MPL
Портал: pike.lysator.liu.se
Главная реализация
Pike

Pike -(произносится [ paɪk ] ) это интерпретируемый, высокоуровневый, кросплатформенный язык программирования общего назначения. Синтаксис напоминает язык С. В отличие от многих других динамических языков, Pike обладает и статической, и динамической типизацией, и требует явного объявления типов. Язык включает в себя гибкую систему типов, которая даёт преимущества языков с динамической типизацией, и так же обладает преимуществами статически типизированных языков.

История

Вначале был Zork. Потом несколько людей решили создать мультиплеерные приключенческие игры. Одним из них был Lars Pensjö из университета Чалмерз в Гётинберге, Швеции. Для своей игры ему понадобился простой, эффективный язык. Так был создан LPC (Lars Pensjö C). Примерно через пять лет Fredrik Hübinette (Hubbe) начал играть в однуиз таких игр и обнаружил, что язык был одним из самых простых в использовании, с которым он сталкивался. Ему настолько понравился язык, чо он начал улучшать его и со временем он создал свой диалект LPC, который назывался LPC4. Он всё ещё был нацелен в сторону написания адвенчур, но был также достаточно полезным для написания других вещей. Основной проблемой LPC4 было авторское право, поскольку он был основан на коде Lars Pensjö. У него была лицензия, кторая не позволяла использовать этот код в коммерческих целях, поэтому в 1994 Hubbe начал разработку µLPC, нового, но похожего на существующий интерпретатора LPC.

Через некоторое время Hubbe получил финансирование для написания µLPC от Signum Support AB, компании, которая посвятила себя GNU и ПО под GPL. Целью их финансирования было просто создание большего числа ПО под GPL.

Когда µLPC стал пригодным для использования, InformationsVävarna AB стали использовать его для своих веб-серверов. До этого Roxen WebServer (тогда ещё Spinner) был некоммерческим и написанным на LPC4. Потом в 1996 Hubbe начал работать в InformationsVävarna, разрабатывая для них µLPC. В это же время название было изменено с µLPC на Pike для получения коммерчески приемлемого имени. После этого Pike разрабатывался Hubbe на полную ставку и иногда другими работниками до тех пор, пока Hubbe не ушёл из InformationsVävarna, которая сейчас сменила название на Roxen Internet Software.

Обзор языка

Сравнение с другими языками

  1. PythonPython - язык, который, наверное больше всего похож на Pike. Pike быстрее и лучше объектно-ориентирован. При этом синтаксис похож на С и Java, что делает его более понятным для тех ,кто знает эти языки. С другой стороны, Python имеет больше доступных библиотек.
  2. C++ Синтаксис Pike почти такой же как у С++. Наибольшая разница заключается в том, что Pike интерпретируемый. Это делает код медленней, но уменьшает время компиляции почти до нуля. Для тех приложений, которым требуется скорость С или С++, чаще проще написать расширения на Pike, чем писать всё на С или С++.
  3. Lisp and SchemeВнутри Pike имеет много общего с простыми реализациями интерпретаторов Lisp и Scheme. Они все основаны на стеке, интерпретируемые, компилируются в байт-код. Pike также "одноячеечный" язык, как и Scheme.
  4. PascalУ Pike нет ничего общего с Pascal.
  5. Tcl/TkPike похож на Tcl/Tk по назначению и они оба обеспечивают удобную работу со строками. Однако, у Pike лучше доступные типы данных и он сильно быстрее.

Особенности Pike

Pike - это язык программирования, который:

  • объектно-ориетированный
  • интерпретируемый
  • быстрый
  • динамический
  • высокоуровневый
  • поход на С, С++, С# и Java
  • легко расширяемый

У Pike есть:

  • сборщик мусора
  • продвинутые функции для работы со строками
  • 8 лет разработки за спиной
  • продвинутые типы данных, например, ассоциативные массивы
  • поддержка больших чисел
  • встроенная поддержка сокетов

Лицензия

Pike выпущен под Gnu General Public License, GPL, the Gnu Lesser General Public License, LGPL, и Mozilla Public License, MPL.

Структуры языка

Структуры управления

  • Условия
    • if
if( expression )
  statement1;
else
  statement2;
    • switch
switch ( expression )
{
  case constant1:
    statement1;
    break;

  case constant2:
    statement2;
    break;

  case constant3 .. constant4:
    statement3;
    break;

  default:
    statement5;
}
  • Циклы
    • while
while ( expression )
	  statement;
    • for
for ( initializer_statement ; expression ; incrementor_expression )
  statement ;
    • do-while

Иногда непрактично, чтобы выражение всегда вычислялось до того, как цикл выполнится в первый раз.

do
  statement;
while ( expression );

Например, если вы хотите написать программу для модема, которая набирает вашего интренет-провайдера, она может выглядеть как-то так:

do {
  modem->write("ATDT441-9109\n"); // Набрать 441-9109
} while(modem->gets()[..6]] != "CONNECT");

Этот пример предполагает, что уже написан код для взаимодействия с модемом через функции write и gets.

    • foreach
foreach ( array_expression, variable )
  statement;
  • Breaking out of loops
    • break

break chfpe выходит из цикла, switch или catch и продолжает выполнение сразу после цикла. Break нельзя использовать вне этих конструкций. Он очень полезен в связке с while(1) для создания циклов, которые, к примеру, парсят команды:

while(1)
{
  string command=Stdio.Readline()->read("> ");
  if(command == "quit") break;
  do_command(command);
}
    • continue
while(1)
{
  string command=Stdio.Readline()->read("> ");
  if(strlen(command) == 0) continue;
  if(command == "quit") break;
  do_command(command);
}
    • return

Return выходит сразу из всей функции.

#!/usr/local/bin/pike

int main()
{
  return 1;
}

Типы данных

  • Базовые типы
    • int
    • float
    • string
  • Типы с указателями
    • array
    • mapping
    • multiset
    • program
    • object
    • function
  • Sharing data
  • Переменные

Операторы

  • Арифметические операторы
Функция Синтаксис Идентификатор Возвращает
Сложение a + b `+ сумму a и b
Вачитание a - b `- b разность b - a
Отрицание - a `- минус a
Умножение a * b `* a уноженное на b
Деление a / b `/ a делённое на b
Остаток a % b `% остаток от деления a на b

Замечание: Третий столбец, "Идентификатор" - это имя функции, которая на самом деле выолняет вычисление.К примеру, a + b можно так же записать как `+(a, b).

  • Операторы сравнения
Функция Синтаксис Идентификатор Возвращает
Равно a == b ` == 1 если а равно b, 0 иначе
Не равно a != b `!= 0 если a равно b, 1 иначе
Больше a > b `> 1 если a больше чем b, 0 иначе
Больше или равно a >= b `>= 1 если a больше или равно b, 0 иначе
Меньше a < b `< 1 если a меньше b, 0 иначе
Меньше или равно a <= b `<= 1 если a меньше чем или равно b, 0 иначе
  • Логические операоры

Логические операторы, которые работают со значениями истина/ложь. В Pike любое значение кроме нуля считается истиной. Логические операторы также могут решать, какие аргументы будут вычилсяться, а какие нет. Поэтому у этих операторов нет идентификаторов и их нельзя вызвать как обычные функции. Всего представлены 4 логических оператора:

Функция Синтаксис Возвращает
And a && b If a ложь, возвращается a и b не вычисляется. Иначе возвращается b.
Or a || b Если a истина, возвращается a и b не вычисляется. Иначе возвращается b.
Not  ! a Возврщается 0 if a истина, иначе 1.
If-else a ? b : c Если a истина, возвращается b и c не вычисляется. Иначе возращается с и b не вычисляется.
  • Побитовые/множественные операторы

Эти операторы используются, чтобы работать с битами как с элементами множества. Они так же могут работать с массивами, мультмножествами и маппингами как с множествами

Функция Синтаксис Идентификатор Возвращает
Сдвиг влево a << b `<< Умножает a на 2 b раз.
Сдвиг вправо a >> b `>> Делит a на 2 b раз.
Инверсия (not) ~ a `~ Возвращает -1-a.
Пересечение (and) a & b `& Все элементы, присутсвующие и в a, и в b.
Объединение (or) a | b `| Все элементы, присутсвующие в a или b.
Симметричная разность (xor) a ^ b `^ Все элементы, присутсвующие в a или b, но не присутсвующие и там, и там
  • Индексирование

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

Функция Синтаксис Идентификатор Возвращает
Индекс a [ b ] `[] Возвращает элемент с индексом b из a.
Поиск a ->identifier `-> Ищет идентификатор. Тоже самое, что a["identifier"].
Присвоить индекс a [ b ] = c `[]=; Установить элемент с индексом b в значение с.
Присвоить индекс a ->identifier = c `->= Установить элемент с индексом "identifier" в значение с.
Граница a [ b .. c ] `[..] Возвращает отрезок, начинающийся на индексе b и заканчивающийся на индексе c.
Граница a [ .. c ] `[..] Возвращает отрезок от начала a и заканчивающийся на индексе c.
Граница a [ b .. ] `[..] Возвращает отрезок, начинающийся на индексе b и идущий до конца a.
  • Оператор присвоенияОператор писвоения только один, но его можно комбинировать с другими операторами для сокращения кода. Оператор присвоения выглядит следующим образом:
variable = expression
variable += expression
//etc.
  • Остальные операторы

Операторы, не попадающие под конкретные категории.

Функция Синтаксис Идентификатор Возвращает
Вызов a ( args ) `() Вызывает функцию a.
splice @ a Нет Отправляет каждый элемент массива а как отдельный аргумент при вызове функции.
Инкремент ++ a Нет Увеличивает a на 1 и возвращает новое значение a.
Декремент -- a Нет Уменьшает a на 1 и возвращает новое значение a.
Постинкремент a ++ Нет Увеличивает a на 1 и возвращает старое значение a.
Постдекремент a -- Нет Уменьшает a на 1 и возвращает старое значение a.
Преобразование (type) a Нет Пытается привести а к значению указанного типа.
Null a, b none Вычисляет a и b, зетем возвращает b.
  • Приоритет операторов:

Таблица показывает относительный приоритет всех операторов в убывающем порядке:

(a) a() a[b] a->b a[b..c] ({}) ([]) (<>)
 !a ~a (type)a ++a --a
a++ a--
a*b a/b a%b
a+b a-b
a>>b a<<b
a>b a>=b a<b a<=b
a == b a!=b
a&b
a^b
b
&&
||
a?b:c
=
@a
,

Примеры кода

Простой пример на Pike, который демонстрирует возможности ввода-вывода и работу с аргументами командной строки:

#!/usr/local/bin/pike

int main(int argc, string *argv)
{
    if(argc > 1 &amp;&amp; argv[1] == "--traditional")
    {
        write("hello world\n"); // old style
    }else{
        write("Hello world!\n"); // new style
    }
    return 0;
}

Далее приводится чуть более полезный пример вывода небольшой базы данных:

!/usr/local/bin/pike

mapping (string:array(string)) records =
([
    "Star Wars Trilogy" : ({
        "Fox Fanfare",
        "Main Title",
        "Princess Leia's Theme",
        "Here They Come",
        "The Asteroid Field",
        "Yoda's Theme",
        "The Imperial March",
        "Parade of the Ewoks",
        "Luke and Leia",
        "Fight with Tie Fighters",
        "Jabba the Hut",
        "Darth Vader's Death",
        "The Forest Battle",
        "Finale"
    })
]);

void list_records()
{
    int i;
    array (string) record_names=sort(indices(records));

    write("Records:\n");
    for(i=0;i<sizeof(record_names);i++)
        write(sprintf("%3d: %s\n", i+1, record_names[i]));
}

void show_record(int num)
{
    int i;
    array (string) record_names =	sort(indices (records));
    string name=record_names[num-1];
    array (string) songs=records[name];    write(sprintf("Record %d, %s\n",num,name));
    for(i=0;i<sizeof(songs);i++)
        write(sprintf("%3d: %s\n", i+1, songs[i]));
}

int main(int argc, array (string) argv)
{
    if(argc <= 1)
    {
        list_records();
    } else {
        show_record((int) argv[1]);
    }
}

Ссылки

  1. Официальный веб-сайт Pike (ENG)
  2. Справка (ENG)
  3. Мануал от MIT (ENG)
  4. Github