Quali sono le limitazioni dell'approccio dell'eccezione Java agli errori?

2

Ignora i problemi di rendimento, sono interessante nel flusso di dati, sicurezza, modellazione, ragionamento.

Mi chiedo quali sono le limitazioni dell'approccio alle eccezioni alla segnalazione degli errori implementate come in Java rispetto a Haskell-like (OCaml e Rust usano lo stesso approccio / simile AFAIK).

Per quanto ne so in entrambi i casi, l'errore fa parte della firma della funzione, ma in Haskell devi "gestire" esplicitamente l'errore anche se l'intera "gestione" lo sta solo superando. Vedo una differenza per il lettore, in Java:

try
{
  a = foo();
  b = bar();
}

è impossibile dirlo (solo guardando il codice) se foo e / o bar possono finire con errori, anche in entrambi i casi l'errore può essere passato silenziosamente. Se capisco correttamente in Haskell, il codice della controparte verrebbe messo in monad:

do a <- foo();
   b = bar();

(Sono nuovo di Haskell, quindi perdonami gli errori) ed è chiaro dove si verifica la caduta e quale linea può fallire.

MA - questo è per umani, il compilatore lo sa in entrambi i casi.

Quindi, quando si tratta, ad esempio, di ragionare sul flusso di dati (per il compilatore, non umano), quali sono i limiti dell'approccio Java? In altre parole, cosa non è fattibile in Java che è possibile in Haskell? O quali informazioni ha Haskell che non è presente in Java?

    
posta greenoldman 22.05.2016 - 10:31
fonte

1 risposta

2

Penso che la differenza più interessante tra i due, certamente dal punto di vista di un progettista di linguaggi, è che la gestione degli errori di Haskell non è una funzione linguistica ma fa parte della libreria, eppure gestisce essere altrettanto espressivi e facili da usare come Java. La ragione per cui funziona così bene è dovuta all'ampio utilizzo di Monad da parte di Haskell, che consente due utili proprietà:

  • il codice che implementa il tipo Monad è passato a blocchi di codice (cioè funzioni che operano sui valori memorizzati nella Monade e restituiscono una nuova istanza Monad, concettualmente comparabili alla nozione di un codice blocco o un'affermazione nella maggior parte delle lingue imperative), ed è autorizzato a chiamare quelli uno, nessuno, o in effetti tutte le volte che vuole. In qualsiasi ordine voglia (cf monad di continuazione). Ciò significa che il codice a livello utente può implementare praticamente qualsiasi modello di controllo del flusso di cui ha bisogno.

  • il linguaggio offre uno zucchero di sintassi facile da usare che rende particolarmente facile la scrittura di codice usando Monad.

Un'altra caratteristica interessante della dipendenza di Haskell da un tipo di dati fornito dall'utente per la gestione degli errori è che se si scrive codice generico di tipo dati, il chiamante di quel codice può dettare come vengono gestiti gli errori. Ad esempio, se scrivo una funzione con una firma come questa:

myUsefulFunction :: Monad m => String -> String -> m String

Posso chiamare questa funzione in una varietà di modi ... per esempio, usando maybe defaultString id (myUsefulFunction str1 str2) , che darà il risultato della funzione in caso di successo o un default se fallisce, o usando runError (myUsefulFunction str1 str2) che restituirà un Either contenente il messaggio di errore o il risultato. Ciò consente una scelta più ampia su come strutturare il mio codice, consentendomi di produrre un risultato migliore con un codice di tipo lessiceplan (senza eccezioni di cattura e sostituendo un valore predefinito, ad esempio).

    
risposta data 23.05.2016 - 17:03
fonte

Leggi altre domande sui tag