Effetto Beaujolais
# Effetto Beaujolais

L'effetto Beaujolais è un comportamento indesiderato presente nella bozza di Jean Ichbiah per lo standard del linguaggio di programmazione Ada, che può consentire un cambiamento tacito di significato di una porzione di codice quando si aggiunge o si toglie una clausola use, rendendo possibili inavvertiti errori semantici. Il nome deriva dal fatto che Ichbiah promise una bottiglia di Beaujolais a chi avesse mostrato l'occorrenza di simili errori nella bozza dello standard. Lo standard Ada 83 soffriva dell'effetto Beaujolais e almeno una bottiglia è stata assegnata in premio, ma in seguito l'analisi effettuata nella redazione del successivo standard Ada 95 ha permesso di eliminare tale comportamento dal linguaggio.

L'effetto Beaujolais è considerato deleterio per il linguaggio in quanto si presume che in fase di manutenzione del codice le clausole possano essere aggiunte o rimosse dalle unità di libreria. In queste situazioni è possibile che alcune istruzioni le quali usano le unità relative a tali clausole sfuggano all'analisi del programmatore. Se il linguaggio consentisse l'effetto Beaujolais, il codice potrebbe rimanere valido sintatticamente ma non semanticamente, continuando a compilare ma introducendo bug di difficile individuazione.

## Descrizione

Ada consente di dividere il programma in unità compilate separatamente, tra le quali i package (che possono contenere subroutine, variabili e altri package). L'implementazione del concetto di namespace prevede che un'unità A possa essere resa visibile in un'altra unità B tramite la clausola with, consentendo di accedere ad un membro M di A tramite la notazione prefissa A.M, mentre la clausola use consente di accedere ai membri senza necessità di specificare il prefisso dell'unità di appartenenza. Poiché Ada supporta l'overriding e l'overloading delle subroutine, può accadere che coesistano diverse funzioni o procedure con lo stesso identificatore (nel caso dell'overloading hanno una firma non ambigua che permetta di distinguerle staticamente in fase di compilazione).

L'effetto Beaujolais insorge quando l'aggiunta o la rimozione di una singola clausola use in un programma Ada è in grado di cambiare la semantica del programma senza violare la sintassi, effetto indesiderato in un linguaggio progettato per offrire la massima precisione semantica. Ichbiah ha lavorato per prevenire un simile comportamento nella bozza dello standard Ada 83, ma è stato successivamente osservato che il problema insorgeva comunque in alcune particolari situazioni (legate alle conversioni da tipi universali a non universali e dovute alla regola RM83-4.6(15) del reference manual) che sono state determinate in seguito con un'analisi matematica del linguaggio, e l'effetto Beujolais è stato rimosso, si ritiene in maniera completa, con lo standard Ada 95. Grazie ad alcune modifiche alle regole sintattiche, il codice Ada 83 che generava una simile situazione viene considerato ambiguo e non compila in Ada 95.

## Esempio

Un esempio di codice che in Ada 83 subisce l'effetto Beaujolais è il seguente:

Nel programma di esempio, nella procedura Main alla riga 7 è dichiarato in overloading l'operatore < con tipo di ritorno Integer. Esistono due dichiarazioni della procedura Q (nel package P, alla riga 2, e nella procedura Main, a riga 8), tuttavia la chiamata alla riga 10 si riferisce in maniera univoca alla procedura dichiarata nel Main stesso, alla riga 8, che è l'unica ad essere direttamente visibile. Se si aggiunge la clausola use P; alla riga 5, sussiste una'ambiguità dovuta al fatto che diventa visibile anche la procedura Q dichiarata in P. Nonostante infatti il tipo di ritorno dell'operatore < definito nel Main alla riga 7 sia Integer, esiste ed è visibile anche l'operatore < definito nel package Standard con parametri Integer'Base e tipo di ritorno Boolean (quindi compatibile con la procedura Q definita in P). Nelle versioni Ada 95 o superiore, questa situazione è rilevata dal compilatore come ambigua e il programma non compila, mentre la versione Ada 83 (in base alla regola di precedenza definita nel reference manual alla voce RM83-4.6(15)) tra le due chiamate sceglieva quella che non richiedeva conversioni implicite: veniva dunque impiegato l'operatore predefinito < con tipo di ritorno Boolean (che non richiede la conversione implicita dei letterali da Universal_Integer a Integer) e di conseguenza la chiamata alla procedura Q definita in P alla riga 2.

