Magik (język programowania)

Z Wikipedii, wolnej encyklopedii

Magikobiektowy język programowania, który obsługuje wielodziedziczenie, polimorfizm i typowanie dynamiczne. Jest on dostarczony przez GE Energy jako część platformy technologicznej Smallworld i został zaprojektowany od początku do realizacji złożonych aplikacji dla przedsiębiorstw użyteczności publicznej takich jak dystrybucja energii i telekomunikacji. Przeznaczony jest do tworzenia aplikacji GIS, stosowany w Smallworld GIS.

Magik (Inspirational Magik) został pierwotnie wprowadzony w 1990 r. i został poprawiony i zaktualizowany na przestrzeni lat. Jego obecną wersją jest 4.0 lub Magik SF (Small Footprint).

Podobieństwo do języka Smalltalk[edytuj | edytuj kod]

Magik jest podobny do Smalltalka pod względem cech języka i jego architektury: Programy w Magiku są kompilowane do kodu bajtowego interpretowanego przez maszynę wirtualną Magika. Maszyna wirtualna Magika jest dostępna na wielu platformach, w tym Microsoft Windows i różnych odmianach Uniksa i Linuksa.

Magik opiera się na konsoli i jego kod może być modyfikowany w locie, nawet gdy aplikacja jest uruchomiona. Konsola może być również wykorzystana do wykonania kodu Magika i aby zobaczyć wyniki.

Skompilowany kod jest przechowywany w jednym pliku o nazwie plik obrazu. Każdy plik obrazu trzyma kod bajtowy i stan sesji (np. wartości zmiennych) jaki był gdy obraz został ostatnio zapisany.

Funkcje języka[edytuj | edytuj kod]

Komentarze

Magik używa znaku # do zaznaczania części kodu jako komentarze:

 # To jest komentarz.
Przypisania

Magik używa operatora << aby przypisać:

 a << 1.234
 b << b + a
 c << "foo" + "bar" # Łączenie łańcuchów

Dla jasności, ten zapis jest odczytywany jako "a staje się równe 1,234" czy "b staje się równe b plus a". Ta terminologia oddziela przypisanie od porównania.

Magik obsługuje również skompresowaną odmianą tego operatora, który działa w sposób podobny do tych z C:

 b +<< a # Odpowiednik b << b + a
Symbole

Zarówno jak konwencjonalne typy danych takie jak liczby całkowite, zmiennoprzecinkowe i łańcuchy, Magik również implementuje symbole. Symbole są specjalnymi leksemami typu danych które są używane często w Magiku do unikalnej identyfikacji obiektów. Reprezentowane są przez ciąg znaków poprzedzony dwukropkiem. Na przykład:

 a << :hello  # kiedykolwiek jest napotkane :hello to jest ta sama instancja
Dynamiczne typowanie

Zmienne Magika nie mają ustalonego typu i mogą odwoływać się do różnych obiektów w czasie wykonania.

Wszystko w Magiku jest obiektem (nie ma rozróżnienia pomiędzy obiektami a prostymi typami jak liczby całkowite):

 a << 1.2     # liczba rzeczywista jest przypisana do zmiennej 'a'
 a << "1.2"   # później string jest przypisany do zmiennej 'a'
Obiekty

Obiekty są implementowane w Magiku przy użyciu egzemplarzy. Egzemplarze są podobne do klas w innych językach programowania takich jak Java, ale mają istotne różnice. Magik obsługuje wielokrotne dziedziczenie i mixiny (które implementują funkcjonalność bez danych). Nowe instancje są tworzone przez klonowanie istniejącej instancji (która zazwyczaj jest egzemplarzem ale nie musi być).

Nowe egzemplarze są tworzone za pomocą instrukcji def_slotted_exemplar(), na przykład:

 def_slotted_exemplar(:my_object,
 {
   {:slot_a, 34},
   {:slot_b, "hello"}
 }, {:parent_object_a, :parent_object_b})

Ten fragment kodu definiuje nowy egzemplarz zwany my_object który ma dwa sloty (lub pola) zwane slot_a (zainicjowany na 34) i slot_b (zainicjowany na "hello") i dziedziczy z dwóch istniejących egzemplarzy zwanych parent_object_a i parent_object_b.

Porównanie

Magik implementuje wszystkie zwykłe operatory logiczne (=, <, <=, >, >=, ~=/<>) do porównań, jak również parę niecodziennych. Operatory _is oraz _isnt są używane do porównywania określonych instancji obiektów zamiast wartości.

Na przykład:

 a << "hello"
 b << "hello"
 a = b zwraca True (_true) ponieważ wartości a i b są równe
 a _is b zwraca False (_false) ponieważ a nie jest tą samą instancją co b
 a << "hello"
 b << a = b zwraca True (_true) ponieważ wartości a i b są równe
 a _is b zwraca True (_true) ponieważ do b przypisaliśmy instancję obiektu a zamiast wartości a.
Metody

Metody są definiowane w egzemplarzach za pomocą instrukcji _method i _endmethod:

 _method my_object.my_method(a, b)
   _return a + b
 _endmethod

Jest to konwencja dostarczenia dwóch metod new() (do utworzenia nowej instancji) and init() (do zainicjowania instancji).

 # Metoda new
 _method person.new(name, age)
   _return _clone.init(name, age)
 _endmethod
 # Metoda inicjalizacji.
 _private _method person.init(name, age)
    # Wywołanie implementacji rodzica.
    _super.init(name, age)
    # Inicjalizacja slotów.
    .name << name
    .age << age
   _return _self
 _endmethod

Wywołanie _clone tworzy fizyczną kopię obiektu person. Wywołanie _super pozwala obiektom na wywołanie implementacji metody egzemplarza rodzica. Obiekty mogą odwoływać się do siebie używając _self. Sloty obiektu są dostępne i przypisywanie za pomocą notacji z kropką.

Metody które nie są częścią publicznego interfejsu obiektu mogą być oznaczone jako prywatne przy użyciu _private. Prywatne metody mogą być wołane wyłącznie przez _self, _super i _clone.

Opcjonalne argumenty mogą być deklarowane przy użyciu _optional. Opcjonalne argumenty które nie są przekazywane są przypisywane przez Magika do specjalnego obiektu _unset (odpowiednik null). Do deklarowania listy opcjonalnych argumentów może być użyte _gather.

 _method my_object.my_method(_gather values)     
 _endmethod
Iteracja

W Magiku na iteracje pozwalają _for, _over, _loop i _endloop.

 _method my_object.my_method(_gather values)
   total << 0.0
   _for a _over values.elements()
   _loop
      total +<< a
   _endloop
   _return total
 _endmethod
 m << my_object.new()
 x << m.my_method(1.0, 2, 3.0, 4) # x = 10.0

Tutaj values.elements() jest iteratorem który pomaga iterować wartości.

W Magiku metody generatora są zwane metodami iteratora. Nowe metody iteratora mogą być definiowane za pomocą _iter oraz _loopbody:

 _iter _method my_object.even_elements()
   _for a _over _self.elements()
   _loop
     _if a.even? _is _true
     _then
        _loopbody(a)       
     _endif
   _endloop
 _endmethod
Procedury

Magik obsługuje również funkcje zwane procedurami. Procedury są również obiektami i są deklarowane przy użyciu _proc i _endproc. Procedury są przypisane do zmiennych które mogą być następnie wywoływane:

 my_procedure << _proc @my_procedure(a, b, c)
   _return a + b + c
 _endproc
 x << my_procedure(1, 2, 3) # x = 6
Dziwactwa językowe

Ponieważ Magik był oryginalnie rozwijany w Anglii, metody w jądrze bibliotek Smallworlda są pisane przy użyciu brytyjskiej odmiany języka angielskiego. Na przykład:

  Użyj "initialise" zamiast "initialize".
Kolekcje

Podobnie jak inne języki programowania Magik też ma kolekcje. Należą do nich:

  • Simple Vector
  • Rope
  • Hash Table
  • Property List
  • Equality set
  • Bags

Przykład Hello World[edytuj | edytuj kod]

Oto przykład z Hello world napisany w Magiku:

 write ("Hello World!")

Linki zewnętrzne[edytuj | edytuj kod]