Indice articolo

Nell’articolo generale su Kokos è stato accennato parzialmente il concetto di poliglottismo, ora abbiamo la possibilità di entrare più nel dettaglio.

Per poliglottismo, nell’ambito della programmazione, si intende la capacità di un software di dirottare l’esecuzione da un programma scritto con un determinato linguaggio, ad un altro basato su un linguaggio differente, in maniera del tutto trasparente.

Per esempio, possiamo scrivere un programma Java in cui dichiariamo una variabile di tipo String e, successivamente, andare a richiamare un programma JavaScript passandogli la stessa variabile. Noteremo che, nel caso in cui l’esecuzione avvenga in ambiente poliglotta, il programma JavaScript avrà accesso a quella determinata variabile e potrà usarla a piacimento.

In Kokos avviene proprio la stessa cosa. L’applicazione viene eseguita in un ambiente poliglotta per mezzo di Oracle Graal VM ed al suo interno i programmi scritti in linguaggi differenti si possono richiamare tra loro.

schema che mostra il poliglottismo di Kokos

Vantaggi

I vantaggi di un’architettura del genere sono molteplici: basta pensare a tutte le volte che sviluppiamo qualcosa e ci chiediamo che linguaggio utilizzare. Kokos, essendo utilizzato come base per software gestionali, deve essere in grado di offrire il maggior numero di servizi di qualità possibile. Questi ultimi però, essendo di natura diversa (contabilità, integrazione, ecc.), possono essere sviluppati nel migliore linguaggio disponibile.

Per esempio, se avessi bisogno di sviluppare un calcolo molto avanzato per la contabilità, potrei utilizzare Python che mi permette di essere più preciso, affidabile e veloce.

Programmazione poliglotta in kokos

Ed ora passiamo al pratico. In Kokos gli attuali linguaggi supportati sono i seguenti:

  • Java;
  • Rpgle;
  • JavaScript.

Ciò significa che tutti e tre i linguaggi possono richiamarsi tra di loro in maniera trasparente. Ora vediamo come.

Program Registry

Alla base del concetto di poliglottismo di Kokos c’è un file di configurazione molto importante che si chiama register.yml. Qui vengono mappati i servizi ed i programmi con il relativo runtime di esecuzione.

programs:
- name: B£K10G
  runtime: RPGLE
- name: B£K11G
  runtime: JAVA

services:
- name: "*SCO"
  interpreter: JAVA
- name: "LOSER_09"
  interpreter: JS

Kokos andrà a leggere automaticamente il file di configurazione del registro e saprà che per esempio il programma B£K10G deve essere eseguito come un programma rpgle, mentre il servizio *SCO deve essere eseguito come un servizio Java. Così facendo non abbiamo la necessità di conoscere quale servizio di Kokos deve eseguire un determinato programma perché ci pensa lui automaticamente.

Alcuni esempi di poliglottismo

Rpgle to JavaScript

register.yml

programs: 
- name: PIPPO
  runtime: RPGLE 
- name: PLUTO
  runtime: JS
PIPPO.rpgle

     D VAR1            S             10
      *
     C                   EVAL      VAR1='Hello' 
      *
     C                   CALL      'PLUTO'
     C                   PARM                    VAR1
PLUTO.mjs
(function (params, context) {
	console.log(params.get("VAR1").asString().getValue()); // Hello
});

Rpgle to Java

register.yml

programs: 
- name: PIPPO
  runtime: RPGLE 
- name: PLUTO
  runtime: JAVA
PIPPO.rpgle

     D VAR1            S             10
      *
     C                   EVAL      VAR1='Hello' 
      *
     C                   CALL      'PLUTO'
     C                   PARM                    VAR1
PLUTO.java
public class PLUTO implements Program {

	public PLUTO(ExecutionContext context){
	}
	
	public List<Value> execute(SystemInterface systemInterface, LinkedHashMap<String, Value> parms) {
        System.out.println(params.get("VAR1").asString().getValue()); // Hello

		ArrayList<Value> arrayListResponse = new ArrayList<Value>();
		arrayListResponse.add(new StringValue("", false));
		return arrayListResponse;
	}

	public List<ProgramParam> params() {
		ArrayList<Value> arrayListInput = new ArrayList<Value>();
		arrayListInput.add(new StringType("VAR1", 10));
		return arrayListInput;
	}
}