2.33        J

J è l’evoluzione di APL  ad opera di Ken Iverson e Roger Hui nel 1990  a partire da APL90.

Come APL, J tratta principalmente array di numeri (interi, floating e complessi) o di caratteri, l’equivalente delle stringhe, ma se ne differenzia per l’utilizzo di soli simboli ASCII per il nome delle funzioni, al posto dei caratteri “esoterici” di APL.

Oltre alle strutture con dimensioni, gli array, ci sono gli atomi, un numero o un carattere o un box; quest’ultimo è una struttura atomica che può contenere atomi o array.

J ha conservato di APL l’interpretazione delle istruzioni, da destra verso sinistra e senza precedenze fra gli operatori, la distinzione delle funzioni in monadiche (fnz op), e diadiche (op1 fnz op2) e l’utilizzo dello stesso simbolo per funzioni diverse, seppure generalmente correlate. J offre un numero di funzioni primitive molto più esteso rispetto ad APL, tramite l’utilzzo di . e : postfissi (inflection), in tal caso, per ogni simbolo, al posto di due funzioni, la monadica e la diadica, in teoria ne sono disponibili 6. Qui di seguito alcune funzioni.

Simbolo

Monadico

Diadico

Monadico.

Diadico.

Monodico:

Diadico:

=

 

uguaglianza

 

 

assegnazione locale

assegnazione globale

<

crea box

minore di

intero minore

minore fra

decremento

minore o uguale

+

coniugato immaginario

addizione

componenti immaginario

MCD o OR

doppio

NOT OR

-

sottrae da 0

sottrazione

sottrae da 1

sottrazione fra insiemi

dimezza

uguaglianza dell’oggetto

*

segno

prodotto

coordinate polari

MCM o AND

quadrato

NOT AND

%

reciproco

divisione

matrice inversa

divisione di matrici

radice quadrata

radice

 

t=:'Condor Informatique - Turin'

   right=: 4 :0

(-x.){.y.

)

   left=: {.

   mid=: dyad define NB. start ll mid stringa

cm=:0{(($y.)<.(0{x.)-1)

NB. cm minimo (-1) fra inizio e ll stringa

cm2=:i.(1{x.,(($t)-cm))<.(($t)-cm)

NB. cm2 = 0 1 2 ... ll-1

(cm+cm2){y.     

)

   load 'c:\j502a\string.ijs'

   t

Condor Informatique - Turin

   13 mid t

matique - Turin

   11 7 mid t

ormatiq

   8 left t

Condor I

   8 right t

 - Turin

Fortunatamente è possibile definire le funzioni con nomi significativi e utilizzare nomi già predefiniti; nella Figura 23 sono riportate la definizione delle funzioni left, right e mid, in particolare left è la semplice ridefinizione (definizione tacita) del verbo take {., right e mid sono invece definite esplicitamente dal blocco nomefnz=: n :0 ... ) (dyad define sono la ridefinizione rispettivamente di 4 e :0).

Figura 23

verbo (verb)

funzione

avverbio (adverb)

funzione su funzione

nome (noun)

costante

pronome (pronoun)

variabile

gerundio[1] (gerund)

case di funzioni

Figura 24

La descrizione ufficiale del linguaggio adotta una terminologia linguistica, si è già accennato ai postfissi; gli elementi sintatticamente più significativi sono riportati nella Figura 24 , esistono ancora le congiunzioni che indicano funzioni miste di funzione e variabile.

Ovviamente un  istruzioni è detta frase (sentence), ed i suoi componenti sono detti parole (word).

Gli operatori i cui operandi sono funzioni, generano delle nuove funzioni dette avverbi, in quanto modificano il comportamento di un verbo, uno di questi è / (insert) che inserisce il verbo fra gli operandi: +/ lista fornisce la somma dei costituenti la lista:

   +/1+i.10 NB. i.10 genera la lista 0 1 ... 9

55 

L’operatore & è utilizzato per rendere monadica una funzione diadica fissandone un operando, nella terminologia J & è detta congiunzione:

   sconto=.0.90&*

   sconto 100 NB. invece di 0.9 * 100

90

Possono essere create delle nuove funzioni giustapponendo semplicemente il nome delle funzioni ed assegnandolo ad una variabile (train), ma con una grave incongruenza di valutazione fra una funzione definita e gli stessi simboli eseguiti nativamente:

   isq=:%%: NB. definizione di x diviso radice di x (radice di x)

   isq 64

8

   %%:64 NB. inverso di radice

0.125

Ciò è dovuto alla particolare interpretazione dei train: se f, g e h sono funzioni e var è l’operando, si ha:

fg var  equivale a var f (g var) NB. Hooks

fgh var  equivale a (f var) g (h var) NB. Fork

Per train con oltre 3 funzioni lo schema è ricorsivamente analogo ai due casi visti.

L’operatore @ (compose) realizza le funzioni di funzioni: isq=:%@%: è l’inverso (%) della radice quadrata (%:). L’operatore @. ha come operando  di sinistra un train di funzioni separate dall’operatore ` (tie) ed a destra un indice che sceglie la funzione da utilizzare, di fatto realizzando il comando case.

La flessibilità nella combinazione di funzioni e il fatto che le operazioni di confronto sono funzioni numeriche, permettono di evitare costrutti condizionali ed iterativi, ad esempio +/'o'=t  conta quante ‘o’ ci sono nella stringa t, tuttavia questi esistono, ma sono utilizzabili solo nelle funzioni:

NB. T, T0, ... sono condizioni; B, B1, ... sono blocchi di istruzioni

for.     T do. B end.

for_xyz. T do. B end.  NB. xyz è la variabile contatore del ciclo

if. T do. B [else. B1] end.

if.     T  do. B

elseif. T1 do. B1

elseif. T2 do. B2

end.

select. T

 case.  T0 do. B0

 fcase. T1 do. B1  NB. Bizzarro: esegue anche il case successivo

 ...

end.

try. B catch. B1 catchd. B2 catcht. B3 end. NB. Se fallisce B1 allora B2 o B3

while.  T do. B end.

whilst. T do. B end.

L’esempio di Figura 25 illustra l’utilizzo di J per applicazioni grafiche.

NB. J 5.02

LANCI=:'30'

NB. cc genera oggetti della form di posizione e dimensioni date da xyhw

DADI=: 0 : 0

pc dadi closeok;pn "Test generatore numeri a caso";

xywh 130 23 40 12;cc Va button leftmove rightmove;cn "Va";

xywh 130 40 40 12;cc Fine button leftmove rightmove;cn "Fine";

xywh 130 9 30 11;cc numero edit;

xywh 7 25 118 100;cc lanci static;

xywh 7 125 118 40;cc casi static;

xywh 7 9 118 11;cc Label static;

pas 4 2;pcenter;

rem form end;

)

dadi_run=: 3 : 0

wd DADI

wd 'set numero *',LANCI

wd 'set Label *Immettere numero lanci'

wd 'setfocus numero'

wd 'pshow;'

)

dadi_Fine_button=: wd bind 'pclose' NB. Fine, chiusura della form

dadi_Va_button=: 3 : 0 NB. Gestione del bottone Va

". 'N=:',numero NB. ". interpreta una stringa (execute)

A=: ?N$6    NB. N numeri a caso fra 0 e 5

wd 'set lanci *Lanci: ',":A  ": trasforma numero in stringa (format)

":A=: =(A/:A) NB. ordina per valore

B=: +/|:A   NB. somma

wd 'set casi *Casi: ',":B

wd 'mb "Test Chi Quadro"',":(+/(B-N%6)^2)%(N%6)

)

dadi_run'' NB. partenza programma

Figura 25

L’operatore !: (foreign conjunction) è utilizzato per interagire con il sistema operativo, in particolare:

0!:n   controllo dell’esecuzione di scripts

1!:n   gestione dei files

6!:n   funzioni su data e ora

9!:n   variabili d’ambiente

11!:n  ambiente grafico statico ed interattivo

13!:n  debug

15!:n  gestione delle Dynamic Link Library

 

Anche qui una incongruenza, il blocco m!:n è un verbo monadico e non una funzione diadica.

J è predisposto alle applicazioni grafiche tramite una semplice gestione di proprietà, metodi ed eventi realizzata col verbo 11!:0 o il suo sinonimo wd, il cui operando è una stringa di comandi per l’interprete grafico (v.Figura 25 ).

 

Nell’esempio seguente un esempio di crittografia a doppia chiave .

NB. J 5.02

P=: 3 : 0  NB. debugger

  y. 1!:2 <2

)

Encrypt=: 3 : 0

'q p p1' =. 29 37 41 NB. assegnazione multipla

Testo=.y.

if. (#Testo) = 0 do.

      Testo=.'Condor Informatique - Turin'

end.

if. (#Testo) > q do.

      Testo=. q {. Testo NB. prelevo i primi q caratteri

else. Testo=. Testo,(q-#Testo)$'*'

end.

P 'Testo originale  ',Testo

P 'crypt. con p  -> ',Testo=.Testo(q|(i.$Testo)*p)}Testo NB. chiusura mittente

P 'crypt. con p1 -> ',Testo=.Testo(q|(i.$Testo)*p1)}Testo NB. chiusura ricevente

P 'decri. con p  -> ',Testo=.Testo(/:(q|(i.$Testo)*p))}Testo NB. apertura mitt.

'decri. con p1 -> ',Testo=.Testo(/:(q|(i.$Testo)*p1))}Testo NB. apertura ricev.

)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

   Encrypt ''

Testo originale  Condor Informatique - Turin**

crypt. con p  -> CrToinn omurq*f-nar u*o dtiIe

crypt. con p1 -> CanouI-ouot*rrn reni*mifT  dq

decri. con p  -> CurTo*id-niaoe ur*qo fntn Irm

decri. con p1 -> Condor Informatique - Turin**

   Encrypt 'Storia dei linguaggi'

Testo originale  Storia dei linguaggi*********

crypt. con p  -> Sl*iu*eiti*aa*i*on* g* *rg*dg

crypt. con p1 -> Sn* *d*igtg*l*e*agou*i*i* ira

decri. con p  -> Sga* *ur*e*ntg *l*ai*i*goid*i

decri. con p1 -> Storia dei linguaggi*********

   Encrypt 'Nel mezzo del cammin di nostra vita'

Testo originale  Nel mezzo del cammin di nostr

crypt. con p  -> Neimasonel emt  l nzmrdd cozi

crypt. con p1 -> N sd z mmectenodeilarlo izn m

decri. con p  -> Nmeidta  oo eiz ermmd sclnznl

decri. con p1 -> Nel mezzo del cammin di nostr

Ed il risultato è:



[1] Si è tradotto gerund con gerundio, in realtà il gerundio inglese è tradotto con l’infinito in italiano ad esempio: the Art of programming.