Esistono linguaggi di programmazione che utilizzano una valutazione rigorosa con valori di sovraccarico?

0

Haskell supporta valori sovraccaricati, in cui un singolo valore sovraccarico può comportarsi un po 'come una sovrapposizione di valori ognuno con un tipo diverso. Ad esempio, ecco una semplice classe di tipo:

class Truthy t where
  truthy :: Integer -> t

instance Truthy Integer where
  truthy x = x       -- some computation that results in an Integer

instance Truthy Bool where
  truthy x = x /= 0  -- some computation that results in a Bool

Il passaggio di un numero a truthy restituisce un valore sovraccarico di tipo Truthy t => t . Questo stesso valore può essere utilizzato come Integer o Bool :

Prelude> let y = truthy 17
Prelude> if y then y else 42
17

Si noti che y viene utilizzato in un contesto Bool (la condizione) e anche in un valore numerico contesto (la clausola then , che deve corrispondere al tipo del numerico else clausola).

Haskell usa anche una valutazione pigra, quindi non è sorprendente che i due i risultati di truthy 17 sono calcolati pigramente. Questo significa che mentre è sovraccarico value è concettualmente un insieme di valori di tipi diversi, solo le istanze effettivamente utilizzate eseguono il calcolo.

Esistono linguaggi di programmazione con valori sovraccarichi come questo ma che utilizzano una valutazione rigorosa?

Se sì, quali sono le semantiche di valutazione dei valori sovraccaricati come? Sono valori sovraccaricati:

  • strict (significa che devi eseguire calcoli per le istanze che non utilizzerai mai)
  • non-strict (che sarebbe incoerente con valori non sovraccaricati)
  • qualcos'altro?
posta Laurence Gonsalves 23.09.2014 - 22:18
fonte

1 risposta

1

Questa è una bella funzionalità standard di molti linguaggi di programmazione che supporta alcuni tipi di overloading dell'operatore . Tuttavia, la maggior parte delle lingue che lo fanno supporta solo questo per tipi predefiniti come booleani, stringhe o tipi numerici.

In Perl , una variabile in genere non ha un tipo effettivo. Invece, è costretto a vari tipi, ma il contesto lo richiede. L'operatore + costringe i suoi operandi ai numeri, mentre not estrae una rappresentazione booleana. Gli oggetti definiti dall'utente possono agganciarsi a questo processo di coercizione. Esempio:

package Truthy {
    use Scalar::Util 'looks_like_number';

    # this sets up overloading
    use overload '0+' => \&as_num, 'bool' => \&as_bool;

    # ignore this constructor code
    sub new {
        my ($class, $value) = @_;
        # this is as close as vanilla Perl gets to type checking ... bleh.
        die "\$value must be a number" if not looks_like_number $value;
        return bless \$value => $class;
    }

    sub as_num { 
        my ($self) = @_;
        print "called as_num\n";
        return $$self;
    }

    sub as_bool {
        my ($self) = @_;
        print "called as_bool\n";
        return $self != 0;
    }
}

my $y = Truthy->new(17);
print +($y ? $y : 42), "\n";

Mentre Perl è un linguaggio rigoroso, i metodi di coercizione vengono eseguiti solo quando viene effettivamente richiesta la coercizione. Tuttavia, il valore non è memorizzato nella cache in alcun modo.

La lingua Python è simile, tranne per il fatto che il meccanismo di overload utilizza metodi con nomi speciali come __str__ e __int__ .

Un linguaggio interessante che consente effettivamente le coercizioni arbitrarie anche tra tipi definiti dall'utente è Scala . Possiamo registrare metodi "impliciti" che forniscono conversioni. Vengono eseguiti solo quando viene richiesta la conversione, in modo che queste conversioni finiscano per avere la stessa semantica del meccanismo di sovraccarico di Perl o Python.

class Truthy(val x: Int) { }

implicit def asInt(t: Truthy): Int = t.x
implicit def asBool(t: Truthy): Boolean = t.x != 0

val x = new Truthy(17)
val result: Int = if (x) x else 42

Potresti aver notato che non sto usando classi di tipi (o i loro equivalenti in lingue OOP: interfacce, tratti) ovunque. La maggior parte delle lingue non supporta il polimorfismo di tipo restituito. Invece, ho espresso il tuo codice in termini di coercizione che finisce per fare la stessa cosa, con mezzi molto diversi.

    
risposta data 23.09.2014 - 23:03
fonte

Leggi altre domande sui tag