Статья представляет собой очень краткое введение в Pike. Признайтесь — мало кто из вас слышал об этом языке. Однако язык Pike даже применяется в продакшене (для работы Opera в режиме Turbo).

Краткие характеристики:

— интерпретируемый (не будете думать чем бы заняться во время компиляции);
— cинтаксис: основанный на С (с минимальными отличиями);
— лицензия — GNU GPL, GNU LGPL and MPL;
— объектно-ориентированный;
— со сборщиком мусора (которому кстати, можно подсказывать если очень надо);
— …

История

Язык появился еще 1994 году. Автор Fredrik Hubinette. Предшественником считатся язык LPC (объектно-ориентированный язык на иснове языка C, созданный прежде всего для разработки игр — LPC Тут на самом деле интересная история — но копипастить вики не имеет смысла. Короче говоря, если бы не игры, не было бы языка.

Скажу сразу — с документацией не все в порядке. Далеко не все примеры (даже для новичков) будут работать (причем это может быть даже Hello world!).

Для начала работы можете запустить интерпретатор. Для этого можно просто набрать pike в консоли без параметров. И экспериментировать. Но мы так делать не будем. Давайте просто попишем (например, в блокноте).

Привет, мир!

Текст программы:

int main()
{
  write("Hello world!\n");
  return 0;
}

Сохраняем этот текст в hello.pike и запускаем в коммандной строке: pike hello.pike

Теперь с окошечком:

int main()
{
    GTK.setup_gtk(); 
    object w = GTK.AboutDialog();
    w.set_program_name("My GTK hello world program");
    w.signal_connect("destroy", lambda(){exit(0);});
    w.set_title("My first program"); 
    w.set_comments("Pike is a dynamic programming language with a syntax similar to Java and C. "+ 
        "It is simple to learn, does not require long compilation passes and has powerful built-in" +
	    "data types allowing simple and really fast data manipulation.");  
	array(string) arr1=({"Mr. Smith", "and others"});
	array(string) arr2=({"Mrs. Smith", "and others"});    	
    w.set_authors(arr1);
	w.set_artists(arr2);
    w.show_now();
    
  return -1;
}



Как видим, работа идет через GTK. Возврат -1 из функкции main нужно для того чтобы программа сразу не прекратила работу, иначе окошечка не увидите. Выход и программы происходит по кнопке закрытия окна с помощью прикрепленной лямбда-функции lambda(){exit(0);}

В официальном туториале для этого применяют GTK.Alert(«Hello world!»), но однако у меня такое не заработало (версия 8.0) — видимо туториал устарел.

Структуры данных:

Синтаксис работы с основными структурами данных радует.

Массивы:

int main()
{
    array(string) arr1 = ({ "red", "green", "white" });
	write(arr1);
	write("\n");
	array(string) arr2 = ({ "red", "green", "yellow" });
	write(arr2);
	write("\n");
	write(arr2 + arr1);  //просто все элементы двух массивов 
	write("\n");
	write(arr2 & arr1);  //пересечение 
	write("\n");
	write(arr2 | arr1);  //объединение множеств 
	write("\n");
	write(arr2 ^ arr1);  //xor - т.е. только те элементы которые не являются общими 
	write("\n");
	write(arr2 - arr1);  //разность 
	write("\n");
    
  return 0;
}

Результат:

redgreenwhite
redgreenyellow
redgreenyellowredgreenwhite
redgreen
redgreenyellowwhite
yellowwhite
yellow

Maps:

int main()
{
    mapping map2 = (["red":4, "white":42, "blue": 88]);
    mapping map1 = (["red":4, "green":8, "white":15]);	
	
    print_map(map2 + map1);
    print_map(map2 - map1);
    print_map(map2 & map1);
    print_map(map2 | map1);
    print_map(map2 ^ map1);
    
    return 0;
}

void print_map(mapping m){
    array(string) arr;
    arr = indices(m);
    foreach(arr, string key){
        write(key + ":" + m[key] + " ");    
    write("\n");
}


Результат:

red:4 green:8 white:15 blue:88
blue:88
red:4 white:15
red:4 white:15 green:8 blue:88
green:8 blue:88

Есть еще так называемые multiset. По сути тоже что mapping, но без значений:

int main(){
    multiset o = (< "", 1, 3.0, 1, "hi!" >); 
    print_multiset(o);	
    return 0;
}

void print_multiset(multiset m){
    array(string) arr;
    arr = indices(m);
    foreach(arr, string key){
        write(key + ":" + m[key] + " ");
    };
    write("\n");
}

Результат:

1:1 1:1 3.0:1 :1 hi!:1

Объекты

class car {    
    public string color;
	public string mark;
	private string driver;
	
	void create(string c, string m, string d){	
	    color = c;
		mark = m;		
		driver = d;
	}
	
	string who(){
	    return mark + " " + color + "\n";
	}	
}

int main(){
    car car1 = car("red", "vaz", "Mike"); 
    write(car1.who());	
	
    car car2 = car("green", "mers", "Nik");
    write(car2.who());		
    write(car2.mark);
	
    return 0;
}

Результат:

vaz red
mers green
mers

Метод create играет роль конструктора. Есть и модификаторы доступа. Но будьте осторожны с модификатором static. Мало того что он означает совсем не то, что вы подумали — он еще и depricated.

Связь с Java

А теперь дернем код Java (а почему и нет если можем?):

int main()
{
    float pi = Java.pkg.java.lang.Math.PI;
	write("Pi = " + pi + "\n");
	
	object syst = Java.pkg.java.lang.System;
	write("time = " + syst.currentTimeMillis() + "\n");
	
	object str = Java.pkg.java.lang.String("...Hello!...");	
	write((string)str.substring(3,str.length()-3) + "\n");
	
	object map2 = Java.pkg.java.util.HashMap(); 
        object key = Java.pkg.java.lang.String("oops");		
	object val = Java.pkg.java.lang.String("ha-ha");	
	map2.put(key, val);
	write((string) map2.get("oops") + "\n");
	
	object map = Java.JHashMap(([ "one":1, "two":2 ]));   
	write((string) map.get("two") + "\n");
    
  return 0;
}

Как видно из примера, обращение к классам Java идет через Java.pkg. При печати надо не забывать приводить объекты Java к строке с помощью (string). Можно вызывать обычные методы Java. Как видно из примера, для HashMap есть даже специальная конструкция для облегчения работы (что, впрочем, неудивительно).

Работа с интернетом

Скачаем страничку с интернета и выведем в консоль:

int main()
{
    Protocols.HTTP.Query web_page;
    web_page = Protocols.HTTP.get_url("https://pike.lysator.liu.se/about/");
    string page_contents = web_page->data();  
    write(page_contents);    
    return 0;
}

Щука помнит об СССР:

int main(){
    Geography.Countries.Country c = Geography.Countries.USSR;	
    write(c.name + "\n");    
    return 0;
}

Отступление от темы
(Готовя этот материал, параллельно экспериментировал с задачей определения страны по IP адресу — по своему адресу конечно. И вздрогнул когда перепутал программы и мне в ответ пришло «USSR»).

Заключение

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

Ссылки

> Главная
> Википедия (англ)
> Статья об языке
> github
> Roxen (веб-сервер на Pike)
Поделиться с друзьями
-->

Комментарии (6)


  1. yarric
    10.06.2017 22:38

    Каждый раз надеюсь увидеть в очередном новом языке RAII, и каждый раз разочаровываюсь...


    1. merhalak
      11.06.2017 12:48

      Боюсь вас разочаровать, но языку уже порядка 23 лет. Он такой же «новый», как и Java.


  1. uelkfr
    10.06.2017 23:14
    +1

    Бред-язык.

    GTK.setup_gtk();

    Где импорт GTK вначале файла?

    return -1;

    Почему не какой-нибудь w.runEventLoop();? В Си все привыкли, что return из main() будет напрямую идти в операционную систему.

    Вообщем дальше не смотрел.


  1. mwizard
    11.06.2017 12:40
    -1

    А зачем нужен этот язык? Какие он задачи решает, с которыми не справляется Python, JS, Lua, Ruby, bash?..


  1. Reineke
    11.06.2017 13:15

    Прочитав, сложилось впечатление (которое подтвердилось и выводом автора): «Прикольная и бесполезная штука. Черт знает нафиг оно такое нужно, но пусть будет».


  1. lasc
    12.06.2017 03:30

    Приходилось страдать по работе, поддерживая CRM и систему тикетов на Roxen(апликейшн сервер для Pike). Желал страшные кары автору.