Esistono linguaggi di programmazione che supportano la digitazione statica e dinamica? [duplicare]

16

Essere statici o dinamici dovrebbe essere qualcosa di completamente supportato nella lingua. Statico vs dinamico non dovrebbe essere qualcosa che devi attivare e disattivare, passando da fondamentalmente a 2 lingue.

Sto parlando di follia mista a digitazione mista come questa cosa:

class MyClass {
  function myMethod(x: int, y: int){        # one parameter is typed, the other not
    return <cast_to_int> y.return_integer(x); #casting to guarantee the contract
  }    
}

MyClass static_obj = MyClass();  #statically typed instantiation;
var dynamic_obj = {};   #dynamically typed instantiation
dynamic_obj.return_integer = (function (x) {return x*2}) #dynamic method creation

static_obj.myMethod(3, dynamic_obj)     # This returns 6

dynamic_obj.return_integer = (function (x) {return x+1}); # dynamic member reassignment

static_obj.myMythod(3, dynamic_obj)   # this returns 4


static_obj.myMethod('asdf', dynamic_obj) # This can't compile, because of typing

# and also this crazy thing; Notice that the static interface of the method is respected
if (<user input> == 2){
    static_obj.myMethod = (function (x: int, y){return x + y.yet_some_other_method(x);})
}

# but when the static contract is not respected, it doesn't compile
static_obj.myMethod = (function (a, b, c) {return 'asdf'}) # Compile time error

Sono interessato a questo argomento perché mi piace molto che la rilevabilità dell'API nei linguaggi statici sia ottima (cosa che mi è piaciuta di più su Java, C # e ABAP per un po '), ma mi piace anche testare le cose in fase di esecuzione, patch di scimmia, REPL, riassegnazione e pazza riflessione magica (che mi è piaciuta di JavaScript e Python).

Sono a conoscenza del controllo di tipo statico di Dart, ma non è sufficiente, perché non fornisce garanzie statiche effettive.

Inoltre non sono interessato al tipo di inferenza. Voglio una vera corsa statica accanto al vero comportamento dinamico. Sono anche consapevole di poter utilizzare tipi di mapping come dict di Python, o qualsiasi oggetto JS o HashMap di Java) per passare dati (o anche funzioni), ma i mapping di Java non possono contenere metodi in essi, i dit di Python possono ' t (out of the box) hanno dei metodi al loro interno, e anche se JS ride semplicemente di qualsiasi tipo di restrizioni statiche - l'aggiunta di metodi in fase di esecuzione che ottengono l'accesso tramite la parola chiave this all'oggetto contesto è qualcosa di veramente interessante (lo so Python lo fa anche quando aggiunge funzioni sull'oggetto classe, ma NON su istanze di classe.

La mia curiosità è stata anche scatenata da questo articolo: Digitazione statica ove possibile, digitazione dinamica laddove necessario

E l'argomentazione dell'API sulla reperibilità è venuta dalla mia esperienza personale, ma questo articolo sembra supportarlo: link

    
posta vlad-ardelean 21.12.2014 - 21:35
fonte

4 risposte

30

Sì. C # a partire da 4.0 è probabilmente l'esempio più comune, con la parola chiave dynamic . Ci sono probabilmente altri buoni esempi di cui mi sto dimenticando o che non conosco.

    
risposta data 21.12.2014 - 21:44
fonte
9

Un grande esempio di questo è Dylan . È possibile utilizzare la digitazione statica e dinamica in Dylan, ad es.

define method double(a :: <integer>) => (result :: <integer>)
    2 * a
end

o

define method double(a) => (result)
    2 * a
end

Questo si estende alle variabili, ecc. Un altro esempio più semplice è REBOL, ma solo nelle sue definizioni di funzione, ad esempio,

double: func [a [integer!]] [a * 2]
double: func [a] [a * 2]

I parametri di funzione sono l'unico posto in REBOL è permesso qualsiasi tipo di controllo di tipo (o dichiarazione, per quella materia).

    
risposta data 22.12.2014 - 02:54
fonte
3

Classic Visual Basic e VBA hanno avuto questa capacità sin dal primo giorno.

VB.NET ha avuto questa capacità anche da release (1.0) con l'opzione di "disattivarlo" utilizzando l'istruzione Option Strict On nella parte superiore del file di codice o del progetto nelle proprietà del progetto. Questo in realtà non lo spegne come tale, semplicemente non compilerà una dichiarazione di binding tardiva quando questo è attivo.

C # alla fine ha recuperato qualche tempo dopo nella versione 4.0 con la differenza che devi "permetterlo" usando la parola chiave dinamica.

    
risposta data 22.12.2014 - 17:12
fonte
0

Il tipo di Java ha questo con la classe Object .

int myMethod(int x, Object y) {
  return x > 0 ? x : (int)y;
}

void go() {
  Object obj;
  if(Math.random() > 0.5)
    obj = 3;
  else
    obj = "hello";
  myMethod(-5, obj); // throws ClassCastException if obj is a String
}

In Java 8 vengono introdotte funzioni lambda, quindi puoi inserire funzioni all'interno delle mappe, anche se è un po 'ingombrante:

Map myObj = new HashMap();
myObj.put("add",
          (BiFunction) (Object x, Object y) -> ((Number) x).intValue() + ((Number) y).intValue());
BiFunction addition = (BiFunction) myObj.get("add");
int apply = (int) (Number) addition.apply(3, 2.2);
    
risposta data 22.12.2014 - 03:14
fonte

Leggi altre domande sui tag