Précédent Index Suivant

4.2   Langage de communications

Le langage SCOL est un langage de communication pour la Son noyau est proche de celui de Caml : il est fonctionnel, statiquement typé, polymorphe paramétrique avec inférence de types. Il est "multimedia" grâce à ses API importantes pour le son, la 2D et la 3D. Enfin il est interfacé avec java, javascript et activeX. L'implantation de SCOL est classique, c'est un compilateur de byte-code. La bibliothèque d'exécution possède un GC. Le code peut être téléchargé sous forme de sources, qui sont ensuite compilés puis exécutés. Une version de "démonstration" est téléchargeable sur le site de la société CRYO :
http://www.cryo-networks.com

4.2.1   Utilisation de SCOL

Une fois téléchargé, la version de démonstration de SCOL contient le minimum pour pouvoir développer des programmes. Les fichiers d'extension ".pkg" contiennent des programmes SCOL, les fichiers d'extension ".scm" sont des scripts de lancement des programmes. L'extension ".scm" est liée au démarrage d'une machine SCOL. Voici un exemple d'un script "
mic: more pavage/pavage.scm
_load "locked/lib/const.pkg"
_load "pavage/debug.pkg"
_load "pavage/util.pkg"
_load "pavage/geom.pkg"
_load "pavage/gen.pkg"
_load "pavage/visu.pkg"
_load "pavage/main.pkg"
main
où les différents fichiers ".pkg" sont chargéspuis la fonction main est exécutée.

4.2.2   Noyau fonctionnel et impératif du langage

Un programme SCOL est une suite de déclaration gloables. Elles concernent les variables, les fonctions, les types, les constructeurs de communication et les déclarations avancées. Il n'y a pas de calcul d'expressions au niveau global, ni de déclaration d'exceptions.

variable

typeof x = I;;
var y = 4;;

fonctions

/* fonction succ */
fun succ(x) = x + 1;;
/* fonction add */
fun add(x,y) = x + y;;
/* longueur d'une liste */
fun len (l) = if l == nil then 0
              else 1 + len (tl l);;

types

Les types de base sont les entiers (type I), les flottants (type F), les chaînes (type S), les tuples [ ... ] et les tableaux. Le type d'une valeur fonctionnelle est : fun [ t1 t2 ... tn] tr où les ti sont les types des paramètres et tr le type du résultat.

Il y a 2 types de déclarations de types : les "struct" et les types somme.

struct Point [x:I, y:I] mkPoint;;

typedef Num = mF F
            | mI I;;
Le polymorphisme de Scol diffère de celui de Caml, bien qu'il soit lui aussi polymorphe paramétrique.

Les variables de types sont nommées ui indiquant une i-eme inconnue de type. Elles doivent être liées. Par exemple la fonction id suivante :
 fun id (x) = x;;
a le type fonctionnel : fun [u0] u0 qui se lit tuple des types des paramètres (entre crochets) type du résultat. Les types récursifs, comme les listes, sont décrits par le niveau de récursivité. Par exemple une liste d'entiers : 1:;2::3::nil ou [ 1 [2 [ 3 nil]]] a le type [I [ I [ I]]] que l'on peut noter [ I r1]r1, type du 2eme élément, correspond au type de niveau 1 (c'est à dire une lite d'entiers). Cela permet d'avoir le même type pour des listes d'entiers de longueur quelconque.

Les 'a list de Caml auront le type : [u0 r1]

En résumé, les types sont représentés par un graphe. Les types de base sont des feuilles ainsi que les variables de types. Les tableaux ont un fils (le type des éléments du tableau), les n-tuples ont n fils (chacun correspondant à un élément). Les fonctions ont 2 fils, le premier est le tuple des paramètres, le second le type du résultat.

expressions

La déclaration locale est dans l'ordre inverse de Caml :
     SCOL                CAML
  let e1 -> p in e2      let p = e1 in e2
e1 est le calcul d'une expression, p est le motif qui filtre cette expression et e2 est l'expression à calculer où les variables du motif p sont connues.

La conditionnelle est classique :
if c then e1 else e2
où c est une expression entière (il n'y a pas le type booléen), et la branche else est obligatoire.

L'application est légèrement différente, ce qui force à parenthéser :
succ 3
add 5 6
len 1::2::3::nil
add len 1::2::3::nil len 2::6::nil
add (len 1::2::3::nil) (len 2::6::nil)
L'affectation d'une variable utilise le mot clé set
set v = 100
Le mot clé mutate permet d'effectuer un effet de bord sur une valeur complexe, le tout avec filtrage :
let [1 2 nil [3 4 ] ] -> t in
  mutate t <- [ _ 5 6 _ ]
Les valeurs fonctionnelles ne sont pas des objets de 1ère classe. Un paramètre fonctionnel se marque avec @f pour parler de la valeur fonctionnelle de f. L'application d'une variable (contenant une valeur fonctionnelle) doit la spécialiser par :
set g = @add
exec g with [4 5]
La séquence de calcul d'expressions est parenthésée, le séparateur des expressions est le ;.

La boucle while est là encore classique :
while e_1 do e_2 
Les tableaux et les structs ont la notation "point" pour accéder à un élément :
t.5
t.(3+5)
set t.1 = 5.45
let mkPoint [2 3] -> p in p.x
Enfin le filtrage utilise la construction match :
match e with
  (p1 -> e1)
| (p2 -> e2)
    ...
| (pn -> en)
C'est tout. Le reste du langage pour la partie communication est décrit à la prochaine section.

4.2.3   Communication et environnement

L'originalité de Scol provient de la communication entre machines virtuelles. La communication entre machines s'effectue à travers des canaux. Un canal est un couple (environnement, liaison réseau). La liaison est une socket (TCP ou UDP). Si la liaison n'existe pas on dit alors que le canal est "unplugged". C'est le cas au démarrage d'une machine SCOL.

Un environnement est associé au canal, s'il vaut nil il ne comprendra que l'environnement minimal. la liai

canaux

_channel : fun [] Chn /* retourne le canal courant */
_setchannel : fun {Chn] Chn /* change le canal courant */
_load : fun [S] I /* chargement d'un fichier SCOL */
_openchannel : fun [S S Env] Chn
La fonction _openchannel prend 3 paramètres : Par exemple pour ouvrir un canal sur le port 2000 de la machine 132.227.89.8, en lui donnant l'environnement minimal, et en compilant le fichier "toto.pkg" et exécuter la fonction main de ce fichier, on écrira :
_openchannel "132.227.89.8:2000" "_load \"toto.pkg\"\nmain" nil

environnement

_envchannel : fun [Chn] Env
_removepkg : fun [Env] Env
_envfirstname : fun [Env] S
_setenv : fun [Chn Env] I
Les différentes fonctions sur les environnements permettent de charger un nouveau fichier (load), de connaître l'environnement d'un canal, de connaître la tête de liste, d'enlever la tête de liste et de modifier l;environnement d'un canal.

Pour créer un canal "unplugged" qui hérite de l'environnement du canal courant et dans lequel on veut charger "toto.pkg", puis exécuter main, on écrira :
_openchannel nil "\load \"toto.pkg\"\nmain" _envchannel _channel

communication

On définit des constructeurs de communication pour passer des valeurs (entières ou chaînes) sur un canal via la fonction _on : fun [Chn Comm] I. Le type Comm correspond à un constructeur de communication appliqué à ses arguments. On les définit de la manière suivante :
defcom X = foo I I S;;
...
  _on TheChannel foo [123 345 "toto"];
...
/* ou */
defcomvar Y = I I S;;
...
  _on TheChannel Y "foo" [123 345 "toto"];
...

serveurs

Pour accepter une connexion, il est nécessaire de faire tourner auparavant un serveur sur la machine où l'on se connecte sur le bon port. La création d'un serveur utilise la fonction :
_setserver : fun [Env I S] Srv
qui hérite de l'environnement passé, exécute le script et ouvre le serveur sur le port,

Quand une connexion est demandée sur le serveur, un nouveau canal est ouvert. Ce canal hérite de l'environnement défini avec le serveur et le script défini avec le serveur est alors exécuté.
_setserver _envchannel _channel 2000 "_load \"toto.pkg\"\nmain"
crée un serveur sur le port 2000 dans l'environnement courant, charge "toto.pkg" et exécute main.

connexion

Quand on ouvre une connexion par _openchannel, le canal est immédiatement créé et la connexion réseau est lancée. Le programme continue son déroulement avant que cette connexion soit effective. Quand elle l'est, la machine SCOL exécute la fonction _connected si elle existe. La fonction _connected : fun [] ? ne prend pas d'arguments et retourne une valeur quelconque.

Le même procédé existe aussi sur le serveur, après l'exécution du script une fonction _connected est aussi exécutée (si elle existe).

Une fois une connexion effectuée, le serveur et le client possèdent chacun un canal de communication de l'un vers l'autre.

4.2.4   API

L'environnement de développement de SCOL est riche. Une des API les plus importantes est l'API 3D qui permet de construire des mondes 3D avec détection des collisions. Le moteur 3D de cette bibliothèque est efficace.

L'API 2D pour les interfaces graphique est assez conséquente.

C'est l'ensemble des possibilités réseau et 3D qui rendent SCOL attrayant.

4.2.5   Les modules distribués


Précédent Index Suivant