programación funcional (o funciones que generan funciones)Tengo un problema donde la solución que quiero es usar una función para generar una función diferente. Aquí tienes un ejemplo de juguete. Espero que vuelva [3,4,5]. no funciona como esperaba porque aparentemente el argumento pasado (compensación) no está disponible para la función anónima que se devuelve. Supongo que hay una manera de hacer esto con la sustitución, pero no pude entenderlo.
funWrapper = Function({array, fun},
fun(array);
);
funFunctional = Function({offset},
Function({x},
x + offset;
);
);
funWrapper([1,2,3], funFUnctional(2));ScriptingRe: programación funcional (o funciones que generan funciones)Hice algunos experimentos: Cómo utilizar Definir clase y Programación funcional usando objetos JSL
Vuelva a publicar si encuentra más del rompecabezas; en este punto no estoy usando mucho las clases JSL, pero pueden ser la mejor manera de hacer lo que quieres. Los espacios de nombres pueden ser equivalentes, sin algunas de las ideas de subclasificación. Cualquiera de los dos le permitirá empaquetar una función y datos juntos, y pasar el paquete a otra función por referencia.
Re: programación funcional (o funciones que generan funciones)Gracias por compartir estas interesantes viñetas, Craige.
Aquí hay soluciones que utilizan ambos enfoques. Las clases me parecen más intuitivas (y "this" es ciertamente más fácil de escribir que el espacio de nombres (expr (ns << get name))).
Probado tanto en JMP 14 Pro como en JMP 12 Pro. Las clases no están disponibles en JMP 12 Pro.
funOffsetAdder = Function({offset},
ns = NewNamespace();
ns:offset = offset;
ns:theMethod = EvalExpr(
Function({x},
this = namespace(expr(ns<<GETNAME></GETNAME>Re: programación funcional (o funciones que generan funciones)Hola @Mittman ,
No estoy seguro de si esto es exactamente lo que quieres, pero funciona para resolver al menos el ejemplo que das en tu publicación original.
Names Default to Here (1);
fWrap = Function({array, offset}, fFun(array offset));
fFun = Function({x, offset}, x + offset);
fWrap([3, 4, 5, 6], 5 );Esto devolverá [8, 9, 10, 11].
Es un tema interesante de considerar. Si puede compartir por qué tendría que hacerlo de esta manera, tengo mucha curiosidad.
¡Espero que esto ayude!,
DS
Re: programación funcional (o funciones que generan funciones)Hola @DiedrichSchmidt , gracias por la respuesta. Sin embargo, esto no funciona para mi caso de uso real. Quiero poder pasar una función arbitraria (monótona) como argumento a una función que encuentra el cero. Esto es bastante sencillo si defino explícitamente cada función, pero tuve problemas cuando quería escribir una función para crear una instancia de una función a partir de una clase parametrizada. Crecí en R, que no es realmente OO, pero donde las reglas de alcance permiten un código como el que tenía en la publicación original.
- EM
Re: programación funcional (o funciones que generan funciones)Hola @Mittman ,
Parece que estás tratando de resolver las raíces de una ecuación (función en este caso, no Función JSL ()), ¿es correcto?
Hay una función JSL incorporada llamada Minimize () a la que puede pasar su función con puntos de partida para que la función Minimize () comience su rutina de optimización. Esta podría ser una ruta más fácil de seguir que escribir su propia Función JSL () para eso. Puedes leer una publicación de blog al respecto. aquí .
¡Espero que ayude!,
DS
Re: programación funcional (o funciones que generan funciones)Tenga en cuenta que las clases JMP14 no son completamente funcionales y podría quemarse si confía demasiado en ellas; sin embargo, en JMP12 + puede crear clases (incluyendo herencia, constructores, destructores, etc.) con espacios de nombres y algo de metaprogramación.
Para responder a la pregunta inicial del OP, puede lograr su objetivo con solo ediciones mínimas en su script, solo tenga en cuenta que el valor de retorno de una función JSL se evalúa (con la declaración Eval ()) antes de ser devuelto.Por lo tanto, si su última declaración es una expresión no evaluada (como una Expr (Función (_definición_)), devolverá la función según lo previsto.Solo se necesita un pequeño truco en la segunda función para poder llamar a la función (la declaración "fun = fun").
funWrapper = Function({array, fun},
fun = fun;
fun(array);
);
funFunctional = Function({offset},
Substitute(
Expr(
Function({x},
x + _offset_;
)
)
,
Expr( _offset_ ), offset
)
);
funWrapper([1,2,3], funFUnctional(2));