COMEFROM

struttura di controllo usata in alcuni linguaggi di programmazione

Nei linguaggi di programmazione, COMEFROM (o COME FROM) è una oscura struttura di controllo usata in alcuni linguaggi di programmazione, originariamente pensata come uno scherzo.

COMEFROM è a grandi linee l'opposto di GOTO in quanto può acquisire lo stato di esecuzione da un punto arbitrario del codice verso una istruzione COMEFROM. Il punto del codice dal quale lo stato attivo viene trasferito è usualmente passato come parametro di COMEFROM. Il fatto che il trasferimento avvenga prima o dopo l'istruzione indicata al punto di origine dipende dal linguaggio utilizzato. Sempre dipendente dal linguaggio, la possibilità di riferire più istruzioni COMEFROM alla stessa origine nel codice può risultare non valida, essere non deterministica, richiamare i vari punti del codice in sequenza o avviare processi in parallelo o concorrente.

Un semplice esempio di istruzione "COMEFROM x" prevede l'utilizzo di un'etichetta, posizionata in un punto del codice altro rispetto al relativo COMEFROM, che agisce come una sorta di "trappola". Quando l'esecuzione del codice raggiunge l'etichetta, l'esecuzione si trasferisce all'istruzione successiva al COMEFROM. L'effetto principale è di rendere il debugging (e la compressione del flusso del software) estremamente difficile, dato che non c'è alcuna indicazione in prossimità dell'etichetta che l'esecuzione misteriosamente possa saltare da un'altra parte del programma.

COMEFROM è stato inizialmente visto in una lista di scherzi in diverse istruzioni assembly (come 'CMFRM'). È stato analizzato in un articolo pubblicato su Datamation da R. Lawrence Clark nel 1973,[1] scritto in risposta alla lettera di Edsger Dijkstra Go To Statement Considered Harmful. COMEFROM è stata implementata nella variante C-INTERCAL del Linguaggio di programmazione esoterico INTERCAL insieme al più misterioso 'COMEFROM'.

Il 1º aprile 2004, Richie Hindle ha pubblicato un'implementazione delle istruzioni GOTO e COMEFROM per Python.[2] Nonostante sia stato distribuito come pesce d'aprile e non pensato per un utilizzo reale, la sintassi è valida e l'implementazione è completamente funzionante.

Usi pratici

modifica

Seppure COMEFROM è sintatticamente e semanticamente un comando valido, e potenzialmente in grado di rimpiazzare GOTO in alcuni programmi, è molto più difficile gestirlo in fase di progettazione e di sviluppo in un linguaggio di programmazione. L'utilizzo più diffuso di costrutti simili a COMEFROM è l'impostazione di breakpoint in fase di debug. Un'implementazione del FORTRAN ha previsto l'istruzione COMEFROM, con il nome di "AT", come aiuto al debug, con evidenti avvisi che ne sconsigliavano l'utilizzo in codice di produzione. In più, molte moderne CPU hanno un supporto hardware per i breakpoint.

Alcuni elementi di Programmazione orientata agli aspetti sono stati paragonati alle istruzioni COMEFROM.[3]

Nei compilatori che usano SSA, un nodo phi è sostanzialmente simile ad un comando COMEFROM. Elenca da quali basic block l'attuale basic block avrebbe potuto essere raggiunto e il valore associato da usare per farlo.

Il codice di seguito è un esempio di programma in un ipotetico dialetto BASIC con l'utilizzo di "COMEFROM" al posto di "GOTO".

10 COMEFROM 40
20 INPUT "WHAT IS YOUR NAME? "; A$
30 PRINT "HELLO, "; A$
40 REM

Il programma ipoteticamente richiede all'utente il suo nome per poi salutarlo, e ripetere l'operazione all'infinito. L'istruzione "REM" alla linea 40 è semplicemente un comando di tipo NOP — l'istruzione "COMEFROM" alla linea 10 richiama l'esecuzione di quella riga quando viene raggiunta la linea 40, indipendentemente dal suo contenuto.

Un divertente esempio eseguibile in Python con il modulo/scherzo goto installato (che usa il debugger per controllare l'esecuzione del programma) risulterebbe così:

from goto import comefrom, label

comefrom .repeat
name = raw_input('what is your name? ')
if name:
    print "Hello",name
    label .repeat
print "Goodbye!"

Questa è un'implementazione in Ruby dell'istruzione COME FROM in Interical.

$come_from_labels = {}

def label(l)
    if $come_from_labels[l]
        $come_from_labels[l].call
    end
end

def come_from(l)
    callcc do |block|
        $come_from_labels[l] = block
    end
end

Alcuni esempio delle funzionalità di debug del compilatore Fortran OS/360:[4]

Example 1:

      INTEGER SOLON, GFAR, EWELL
         .
         .
         .
10    SOLON = GFAR * SQRT(FLOAT(EWELL))
11    IF (SOLON) 40, 50, 60
         .
         .
         .
      DEBUG UNIT(3)
      AT 11
      DISPLAY GFAR, SOLON, EWELL
      END

Example 2:

      DIMENSION STOCK(1000),OUT(1000)
         .
         .
         .
      DO 30 I=1, 1000
25    STOCK(I)=STOCK(I) - OUT(I)
30    CONTINUE
35    A = B + C
         .
         .
         .
      DEBUG UNIT(3)
      AT 35
      DISPLAY STOCK
      END

Example 3:

10    A = 1.5
12    L = 1
15    B = A + 1.5
20    DO 22 I = 1,5
         .
         .
         .
22    CONTINUE
25    C = B + 3.16
30    D = C/2
      STOP
         .
         .
         .
      DEBUG UNIT(3), TRACE
C     DEBUG PACKET NUMBER 1
      AT 10
      TRACE ON
C     DEBUG PACKET NUMBER 2
      AT 20
      TRACE OFF
      DO 35 I = 1,3
         .
         .
         .
35    CONTINUE
      TRACE ON
C     DEBUG PACKET NUMBER 3
      AT 30
      TRACE OFF
      END

Nell'esempio 1, i valori di SOLON, GFAR, ed EWELL sono esaminati dopo il completamente dell'istruzione 10. L'istruzione AT rinvia alla riga 11.

Nell'esempio 2, tutti i valori di STOCK sono visualizzati quando viene eseguita la riga 35.

Nell'esempio 3, il TRACE viene eseguito dalla riga 10 alla riga 20. Il tracing viene interrotto durante l'esecuzione del loop e riattivato successivamente. Il tracing viene interrotto definitivamente durante l'esecuzione dell'istruzione alla riga 30.

Implementazioni hardware

modifica

Il DSP del computer SHARC supporta un'istruzione DO..UNTIL, pensata per l'implementazione di cicli di tipo Do While, ma che sono essenzialmente istruzioni COMEFROM. Un esempio:

    LCNTR=42;
    DO x UNTIL LCE;  /* COMEFROM x, unless the loop counter is zero */
    F12=F0*F4, F8=F8+F12, F0=dm(I0,M3), F4=pm(I8,M9);
    IF NZ dm(I2,M2) = F12;
    IF ZF dm(I2,M2) = F1;
x:  R2 = R3 + 76;   /* the label "x" does not exist in the machine code */

È da notare che la condizione per il termine del loop, qui indicata come LCE (loop counter expired), può essere impostata su altri valori, incluso sempre vero o sempre falsa. Con una condizione sempre vera, si realizza nella pratica un'istruzione di tipo COMEFROM. L'hardware supporta fino a sei COMEFROM attivi simultaneamente.

  1. ^ Lawrence Clarke, Datamation (article), Fortran. URL consultato il 10 luglio 2012 (archiviato dall'url originale il 16 luglio 2018)..
  2. ^ Richie Hindle, goto for Python, in Entrian, 1º aprile 2004..
  3. ^ C2:ComeFrom
  4. ^ IBM System/360 and System/370 Fortran IV Language, GC28-6515-10, May 1974

Bibliografia

modifica

Voci correlate

modifica

Collegamenti esterni

modifica
  Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica