...

суббота, 10 июня 2017 г.

[recovery mode] По щучьему велению… (язык программирования Pike)

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

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

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

История

Язык появился еще 1994 году. Автор Fredrik Hübinette. Предшественником считатся язык 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("http://ift.tt/2soNznM");
    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)

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

    Let's block ads! (Why?)

    Комментариев нет:

    Отправить комментарий