2009-07-03 7 views
9

Existe-t-il un langage de programmation (ou système de type) dans lequel vous pouvez exprimer les fonctions Python suivantes de manière statique et sécurisée (sans avoir à utiliser les conversions, les contrôles d'exécution, etc.)?Comment sécuriser ces fonctions typées dynamiquement?

#1:

# My function - What would its type be? 
def Apply(x): 
    return x(x) 

# Example usage 
print Apply(lambda _: 42) 

#2:

white = None 
black = None 

def White(): 
    for x in xrange(1, 10): 
     print ("White move #%s" % x) 
     yield black 

def Black(): 
    for x in xrange(1, 10): 
     print ("Black move #%s" % x) 
     yield white 

white = White() 
black = Black() 

# What would the type of the iterator objects be? 
for it in white: 
    it = it.next() 
+1

Est-ce que c'est un devoir? –

+2

Non! Pourquoi penses-tu ça? – Dario

+0

Ceux-ci devraient être dans deux questions séparées. Les conséquences de leur présence dans la même question sont évidentes, comme la plupart des réponses ci-dessous abordent l'une ou l'autre, mais pas les deux. Donc fermeture comme _too large_. – rightfold

Répondre

4

1 # Ceci n'est pas typable avec un type fini. Cela signifie que très peu de langages de programmation (le cas échéant) pourront taper ceci.

Cependant, comme vous l'avez démontré, il y a un type spécifique pour x qui permet la fonction à taper:

x :: t -> B 

B est un certain type de béton. Il en résulte apply dactylographiés comme:

apply :: (t -> B) -> B 

Notez que Hindley-Milner ne tirera ce type.

2 # Cela est facile à représenter dans Haskell (laissé en exercice au lecteur ...)

+0

À # 2: Pourriez-vous donner un exemple concret? Je pense que l'on implémenterait ceci dans Haskell d'une manière tout à fait différente (monades/continuations), mais ne pas taper les itérateurs soit le même problème qu'en # 1? – Dario

0

En ce qui concerne l'exemple # 1, vous devez spécifier le type de retour de apply(), et toutes les fonctions x que vous passe aussi doit retourner cela. La plupart des langages typés statiquement ne pourraient pas le faire en toute sécurité sans contrôles, car la fonction x que vous transmettez peut renvoyer n'importe quoi.

Dans l'exemple 2, le type des objets de l'itérateur est qu'ils sont des itérateurs. Si vous voulez dire ce qu'ils reviennent, ils retournent des itérateurs. Je ne vois pas pourquoi cela ne serait pas possible dans un système statique, mais peut-être qu'il me manque quelque chose.

+0

Les itérateurs sont également génériques car vous devez connaître le type de la valeur qu'il contient (Iterator ). – Dario

+0

contient? Pourquoi? Vous devez savoir ce qu'ils retournent, et dans ce cas ils retournent un autre itérateur. –

+0

Attendez, vous voulez dire que nous ne pouvons pas être sûrs que l'itérateur renvoyé par l'itérateur renvoie un itérateur, et c'est vrai. En bref, non, dans un langage statique, si vous utilisez des fonctions génériques et passez-les, alors non, vous ne savez pas ce qu'ils retournent. En fait, c'est typiquement quelque chose que vous faites dans un langage statique lorsque vous avez besoin de fonctionnalités dynamiques. ;) –

2

J'ai trouvé une solution pour Haskell # 1 utilisant Rank-N-Types (juste pour GHCi)

{-# LANGUAGE RankNTypes #-} 
apply :: (forall a . a -> r) -> r 
apply x = x x 

apply $ const 42 -- Yields 42 
Questions connexes