Cuando intento crear DSL internas en Scala, me encuentro con un problema común y no he podido crear una solución. Para hacer las cosas un poco más como un lenguaje típico, me gustaría que la sintaxis para buscar algo como esto:Construya una lista a partir de una serie de expresiones en Scala
model 'Foo {
decl 'Real 'x;
decl 'Real 'y;
}
En la práctica, hay varias cuestiones. El primer problema es obtener un objeto model
aquí para tomar dos argumentos de esta manera. Si alguien tiene alguna idea, házmelo saber. Pero lo que he hecho en cambio, es hacer algo un poco más como esto:
model('Foo) {
...
}
Dónde modelo es ahora una función que devuelve un objeto con un método apply
que luego consume la lambda que sigue. Con lo que puedo vivir Podría vivir con un problema similar dentro de la lambda, así que cosas como decl 'Real 'x
o decl('Real,'x)
en el interior. Pero lo que quiero hacer es obtener los resultados de todas esas expresiones dentro de las llaves onduladas para "devolver" como una lista. En otras palabras, lo que quiero es escribir algo como esto:
model 'Foo {
decl('Real,'x);
decl('Real,'y);
}
donde decl(...)
devuelva algo de tipo Declaration
y la {...}
continuación, se evalúa como List[Declaration]
. Sospecho que hay alguna forma de utilizar implícitos para hacer esto, pero no he podido encontrarlo. En resumen, me gustaría hacer:
model 'Foo {
decl('Real,'x);
decl('Real,'y);
}
... se evalúan como el equivalente de ...
model 'Foo {
decl('Real,'x) ::
decl('Real,'y) ::
Nil
}
Comentarios o sugerencias?
Sí, he visto este enfoque con algunas de las DSL de GUI declarativas también. Estoy de acuerdo con que esto está cerca. Esperaba no tener que introducir() todo el asunto y la necesidad de usar "," es problemático porque cada vez que quiera agregar o quitar, debe preocuparse por tener "," s entre las cosas, pero no al final. –
Modifiqué mi respuesta para responder a tu comentario. – paradigmatic
Ah, muy inteligente. Usando la sintaxis del constructor y los métodos definidos localmente. Me gusta y creo que podría funcionar. De hecho, puedo simplificarlo hasta "nuevo modelo ('Foo) {...}" que corta el código. Una buena manera de explotar el hecho de que las llaves onduladas en un contexto constructor te permiten introducir cosas fácilmente en ese ámbito. Me pregunto si las macros Scala 2.10 harán esto aún más simple. –