Disons que jesucre pour la création d'Syntactic objet de compilation à Scala
trait fooTrait[T] {
def fooFn(x: T, y: T) : T
}
Je veux permettre aux utilisateurs de déclarer rapidement de nouvelles instances de fooTrait avec leurs propres corps définis pour fooFn. Idéalement, je voudrais quelque chose comme
val myFoo : fooTrait[T] = newFoo((x:T, y:T) => x+y)
de travailler. Cependant, je ne peux pas le faire
def newFoo[T](f: (x:T, y:T) => T) = new fooTrait[T] { def fooFn(x:T, y:T):T = f(x,y); }
parce que celui-ci utilise des fermetures, et donc des résultats dans différents objets lorsque le programme est exécuté plusieurs fois. Ce que je veux, c'est vraiment être capable d'obtenir le classOf de l'objet retourné par newFoo et ensuite le rendre constructible sur une machine différente. Que fais-je?
Si vous êtes intéressé par le cas d'utilisation, je suis en train d'écrire un wrapper Scala pour Hadoop qui vous permet d'exécuter
IO("Data") --> ((x: Int, y: Int) => (x, x+y)) --> IO("Out")
La chose au milieu doit être transformé en une classe implémente une interface particulière et peut ensuite être instanciée sur des machines différentes (en exécutant le même fichier jar) à partir du nom de la classe.
Notez que Scala fait la bonne chose avec le sucre syntaxique qui convertit (x: Int) => x + 5 en une instance de Function1. Ma question est de savoir si je peux reproduire cela sans pirater les internes de Scala. Si c'était lisp (comme je suis habitué), ce serait une macro de compilation triviale ...: sniff:
Souhaitez-vous sérialiser la fonction sur une machine distante? Que voulez-vous dire en instanciant la classe "à partir du nom de classe". Quel est le nom de la classe ou de la classe dans cet exemple? –
Fondamentalement, ce que je veux, c'est avoir du code Foo (Int => Int): String qui retourne quelque chose. Ensuite, sur une machine différente qui a le même fichier jar chargé, je veux exécuter Bar (s: String): FooTrait [Int] sur cette chaîne et avoir Bar (Foo (fn)) retourner un objet qui a fn comme méthode . Une façon de le faire est def Foo (obj: FooTrait [Int]) = classOf (obj) .toString et ensuite Bar créer une nouvelle instance de la classe à partir du nom de la classe, mais cela nécessite de passer dans une classe à Foo, pas un lambda. – bsdfish