Dovrebbe ** legarsi più strettamente di!, ~?

1

Progettando un linguaggio di programmazione, includo l'operatore di esponenziazione ** . In Fortran e Python, le due lingue che conosco hanno questo operatore, che si lega più strettamente di unario meno, il che ha senso per praticità e tradizione.

Dovrebbe legare più liberamente rispetto all'operatore di incremento del prefisso ++ perché l'altro modo non avrebbe senso. Pertanto, il solito livello di precedenza singolo per gli operatori unificati di prefisso viene diviso in due, il che va benissimo.

Includo anche gli operatori non logici e bit a bit ! e ~ . Su quale lato della divisione dovrebbero cadere? Dovrebbero legarsi più liberamente o strettamente di ** ? Non sono stato in grado di trovare né una ragione obiettiva né un precedente rilevante per nessuna delle due opzioni. C'è qualcuno di quello che mi manca? In caso contrario, quali persone troverebbero meno sorprendenti?

    
posta rwallace 26.09.2013 - 08:12
fonte

2 risposte

8

Quando si progetta una lingua, è possibile modificare la precedenza e altre regole per creare un'esperienza elegante. A volte, non consentire determinati costrutti può migliorare la leggibilità, senza sacrificare molta espressività. Perdi le somiglianze con le altre lingue, quindi rendi la tua lingua più difficile da imparare.

Hai stabilito -x**y == -(x**y) . Questo ha senso, poiché questa è la convenzione in matematica.

Stai considerando ++x**y == (++x)**y . L'alternativa non ha senso, perché x**y non è un lvalue. Tuttavia, è possibile considerare di non consentire l'incremento a livello di espressione. Per esempio. Vai prende questa rotta. Ciò evita il problema che x = ++x è un comportamento non definito in molte lingue. Inoltre, x++**y è decisamente brutto; -)

Se hai un tipo di sistema statico e un tipo booleano, allora specificare la precedenza tra ** e ! non ha senso: uno è un operatore numerico, l'altro è logico. < br> Se non si dispone di un tipo booleano o di un sistema di tipo statico, ! dovrebbe avere precedenza inferiore, quindi !x**y è !(x**y) . L'esponenziazione dovrebbe vincolare molto strettamente, solo le chiamate di incremento e metodo dovrebbero avere precedenza più elevata. Inoltre, l'interpretazione (!x)**y è stupefacente: Pochi lo aspetteranno, e generalmente dovresti seguire il principio di sorpresa minima . Questo darebbe anche a ! una precedenza più alta di unario meno ...

Personalmente sono un fan di operatori logici alfabetici come not , and , or con priorità molto bassa. Questo può migliorare la leggibilità.

Non sono un fan degli operatori bit a bit come << , ~ , & perché il bit twiddling è utile solo in pochissimi domini e questi caratteri potrebbero essere utili per altri operatori. << potrebbe essere un operatore di flusso, ~ potrebbe essere una concatenazione di stringhe. Cerca Haskell o Perl6 per idee carine.

Se si desidera includere operatori bit a bit, è necessario che siano correlati in precedenza ai rispettivi equivalenti logici: ! e ~ potrebbero avere la stessa precedenza. ^ (xor) e | dovrebbero avere più o meno la stessa precedenza e legare leggermente più strettamente degli operatori logici || e && . & dovrebbe avere una precedenza maggiore di | , proprio come && di solito ha una precedenza maggiore di || .

Per evitare sorprese, stai vicino a C, in quanto è una delle lingue più influenti. Puoi trovare una tabella delle precedenze su Wikipedia . Confronta con Perl , Python . Ricorda inoltre che alcune lingue della famiglia ML sopravvivono senza tabelle di precedenza elaborate.

    
risposta data 26.09.2013 - 10:34
fonte
2

Non ho nulla a cui fare il backup, ma la mia sensazione mi dice che gli operatori di negazione logica e bit a bit ( ! e ~ ) sono più strettamente correlati al meno unario ( - ) e dovrebbero avere lo stesso livello di precedenza.

    
risposta data 26.09.2013 - 08:39
fonte