Magik (langage de programmation) - Magik (programming language)

Magik est un langage de programmation orienté objet qui prend en charge l' héritage multiple et le polymorphisme , et il est typé dynamiquement . Il a été conçu et mis en œuvre en 1989 par Arthur Chance de Smallworld Systems Ltd. dans le cadre du Smallworld Geographical Information System (GIS). Suite à l'acquisition de Smallworld en 2000, Magik est désormais fourni par GE Energy , toujours dans le cadre de sa plateforme technologique Smallworld.

Magik (Inspirational Magik) a été introduit à l'origine en 1990 et a été amélioré et mis à jour au fil des ans. Sa version actuelle est la 5.2.

En juillet 2012, les développeurs de Magik ont ​​annoncé qu'ils étaient en train de porter le langage Magik sur la machine virtuelle Java . Le portage réussi a été confirmé par Oracle Corporation en novembre de la même année.

Similitudes avec Smalltalk

Magik lui-même partage certaines similitudes avec Smalltalk en termes de fonctionnalités de langage et d'architecture: le langage Magik est compilé en codes d'octets interprétés par la machine virtuelle Magik . La machine virtuelle Magik est disponible sur plusieurs plates-formes dont Microsoft Windows , différentes versions d' Unix et Linux .

Magik est basé sur une console et le code peut être modifié à la volée même lorsqu'une application est en cours d'exécution. La console peut également être utilisée pour exécuter du code Magik et pour voir les résultats.

Le code compilé est stocké dans un seul fichier appelé fichier image. Chaque fichier image contient les codes d'octets compilés et l'état de la session (par exemple des valeurs de variable) lors de la dernière sauvegarde de l'image.

Caractéristiques linguistiques

commentaires

Magik utilise le # jeton pour marquer des sections de code en tant que commentaires:

 # This is a comment.

Affectations

Magik utilise l' << opérateur pour effectuer des affectations :

  a << 1.234
  b << b + a
  c << "foo" + "bar" # Concat strings

Pour plus de clarté, cette notation est lue comme "a devient 1,234" ou "b devient b plus a". Cette terminologie sépare l'affectation de la comparaison .

Magik prend également en charge une variante compressée de cet opérateur qui fonctionne d'une manière similaire à celles trouvées dans C :

  b +<< a # Equivalent to b << b + a

Pour imprimer une variable, vous pouvez utiliser la commande suivante

 a << "hello"
 write(a)

Symboles

Outre les types de données conventionnels tels que les entiers, les flottants et les chaînes, Magik implémente également des symboles. Les symboles sont un type de données de jeton spécial qui est largement utilisé dans Magik pour identifier de manière unique les objets. Ils sont représentés par un signe deux-points suivi d'une chaîne de caractères. Les symboles peuvent être échappés à l'aide du caractère de barre verticale . Par exemple:

  a << :hello  # whenever :hello is encountered, it is the same instance
  b << :|hello world|

Typage dynamique

Les variables Magik ne sont pas typées comme elles le sont en C # et peuvent référencer différents objets lors de l'exécution. Tout dans Magik est un objet (il n'y a pas de distinction entre les objets et les types primitifs tels que les entiers):

  a << 1.2     # a floating point number is assigned to variable 'a'
  a << "1.2"   # later, a string is assigned to variable 'a'
Objets

Les objets sont implémentés dans Magik à l'aide d'exemples. Les exemples ont des similitudes avec les classes d'autres langages de programmation tels que Java , mais avec des différences importantes. Magik prend en charge l'héritage multiple et les mixins (qui implémentent des fonctionnalités sans données). Les nouvelles instances sont créées en clonant une instance existante (qui sera généralement l'exemple mais ne doit pas nécessairement l'être).

De nouveaux exemplaires sont créés à l'aide de l'instruction def_slotted_exemplar() , par exemple:

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

Ce fragment de code définira un nouvel exemplaire appelé my_object qui a deux slots (ou champs) appelés slot_a (pré-initialisé à 34) et slot_b (pré-initialisé à "hello") qui hérite de deux exemplaires existants appelés parent_object_a et parent_object_b .

Comparaison

Magik met en œuvre tous les opérateurs logiques habituels ( = , < , <= , > , >= , ~=/<> ) à titre de comparaison, ainsi que quelques unes inhabituelles. Les opérateurs _is et _isnt sont utilisés pour comparer des instances spécifiques d'objets, ou des références d'objet plutôt que des valeurs.

Par exemple:

  a << "hello"
  b << "hello"

  a = b # returns True (_true) because the values of a and b are equal
  a _is b # returns False (_false) because a is not the same instance as b

  a << "hello"
  b << a
  a = b # returns True (_true) because the values of a and b are equal
  a _is b # returns True (_true) because b was assigned the specific instance of the same object as a, rather than the value of a.

Méthodes

Les méthodes sont définies sur des exemplaires en utilisant les instructions _method et _endmethod :

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

Il est conventionnel de fournir deux méthodes new() (pour créer une nouvelle instance) et init() (pour initialiser une instance).

  # New method
  _method person.new(name, age)
    _return _clone.init(name, age)
  _endmethod

  # Initialise method.
  _private _method person.init(name, age)
     # Call the parent implementation.
     _super.init(name, age)
     # Initialise the slots.
     .name << name
     .age << age
    _return _self
  _endmethod

Le _clone crée une copie physique de l' person objet. L' _super instruction permet aux objets d'appeler une implémentation d'une méthode sur l'exemplaire parent. Les objets peuvent se référencer à l'aide de l' _self instruction. Les emplacements d'un objet sont accessibles et attribués à l'aide d'une notation par points.

Les méthodes qui ne font pas partie de l'interface publique de l'objet peuvent être marquées comme privées à l'aide de l' _private instruction. Les méthodes privées ne peuvent être appelées que par _self , _super et _clone .

Les arguments facultatifs peuvent être déclarés à l'aide de l' _optional instruction. Les arguments optionnels non passés sont attribués par Magik à l'objet spécial _unset (l'équivalent de null). L' _gather instruction peut être utilisée pour déclarer une liste d'arguments facultatifs.

  _method my_object.my_method(_gather values)     
  _endmethod

Itération

En Magik le _while , _for , _over , _loop et les _endloop états itération permettent.

_block
	_local s << 0 
	_local i << 0
	_while i <= 100
	_loop 
		s +<< i 
		i +<< 1 
	_endloop
>> s
_endblock

Ici, le _ while est combiné avec _loop et _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

Ici values.elements () est un itérateur qui permet d'itérer les valeurs.

Dans Magik , les méthodes génératrices sont appelées méthodes itératrices. De nouvelles méthodes d'itérateur peuvent être définies à l'aide des instructions _iter et _loopbody :

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

Procédures

Magik prend également en charge des fonctions appelées procédures. Les procédures sont également des objets et sont déclarées à l'aide des instructions _proc et _endproc . Les procédures sont affectées à des variables qui peuvent ensuite être appelées:

  my_procedure << _proc @my_procedure(a, b, c)
    _return a + b + c
  _endproc

  x << my_procedure(1, 2, 3) # x = 6

Expression régulière

Magik prend en charge // la syntaxe des expressions régulières:

_if /Hello\,\s(\w)+!/.matches?("Hello, Magik!") _then
    write("Got a match!")
_endif 

et pour capturer des groupes dans Regex:

/sw([0-9]+)-([0-9]+).*/.replace_all("sw65456-324sss", "$1") # "65456"
/sw([0-9]+)-([0-9]+).*/.replace_all("sw65456-324sss", "$2") # "324"

Bibliothèque HTTP

Magik prend en charge les requêtes HTTP ou HTTPS via la bibliothèque http, voir les exemples ci-dessous:

magikhttp << http.new()
magikhttp.url("https://www.google.com").get()
magikhttp.url("https://www.google.com").post({"User-agent", "Bot"}, "some data")

Bizarreries linguistiques

Comme Magik a été développé à l'origine en Angleterre, les méthodes des bibliothèques de base de Smallworld sont orthographiées en anglais britannique . Par exemple:

  Use "initialise", not "initialize".

Les collections

Comme tout autre langage de programmation, Magik a aussi des collections. Ils comprennent les éléments suivants:

  • Vecteur simple
  • Corde
  • Table de hachage
  • Liste des propriétés
  • Ensemble égalité
  • Sacs

Exemple Hello World

Voici un exemple du programme Hello world écrit en Magik:

 write("Hello World!")

Les références

Liens externes