Rareza de JMP Expr(), ¿alguien puede explicarlo?Esto es principalmente solo una publicación de frustración por la siguiente inconsistencia al insertar expresiones 'IF' en una expresión 'IF'.Tengo entendido que los lenguajes de programación no deberían ser más que consistentes (y soy consciente de muchas otras inconsistencias de JMP, solo que esta no tiene ningún sentido para mí).
/*
What I want is to generate an expression such as the one below programmatically. There of course is a straight-forward work around, I just don't like dealing with special cases especially when they make no sense.
Expr( If( a, If( b, c) ) )<BR />
*/
expr = Expr( If( a ) );
Insert Into( expr, Expr( If( b, c ) ) );
Show( Name Expr( expr ) );
/*
If( a, b, c)
*/
expr = Expr( not an If( a ) );
Insert Into( expr, Expr( If( b, c ) ) );
Show( Name Expr( expr ) );
/*
not an If( a, If( b, c) )
*/
Si alguien tiene alguna idea, o especialmente si conoce una manera de insertar de manera confiable cualquier expresión en cualquier otra expresión (sin usar 'Eval Insert' o cadenas), ¡sería genial!¡Gracias!
Modelado estadístico avanzadoRe: Rareza de JMP Expr(), ¿alguien puede explicarlo?existe una solución alternativa para realizar la tarea solicitada, pero la pregunta real: ¿¡¿POR QUÉ?!? aún no ha sido respondida.
añadido a Pequeñas trampas en Jmp y JSL
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?Otros ejemplos que refutan fácilmente algunas de las hipótesis y añaden más ideas:
expr = Expr( If( a, x ) );
Insert Into( expr, Expr(If( b,c )) );
Show( Name Expr( expr ) ); // if(a,x,b,c)
expr = Expr( If( a ) );
Insert Into( expr, Expr(If( b )) );
Show( Name Expr( expr ) ); // if(a,b)
expr = Expr( List( a ) );
Insert Into( expr, Expr(List( b )) );
Show( Name Expr( expr ) ); // List(a,b)
expr = Expr( Graph Builder( a ) );
Insert Into( expr, Expr(Graph Builder ( b )) );
Show( Name Expr( expr ) ); // Graph Builder(a,b)
expr = Expr( Head( a ) );
Insert Into( expr, Expr(Head( b )) );
Show( Name Expr( expr ) ); // Head(a,b) (!)
expr = Expr( Not( a ) );
Insert Into( expr, Expr(Not( b )) );
Show( Name Expr( expr ) ); // Not(a) (!!)
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?Hola,
Aunque no estoy seguro, me pregunto si este comportamiento se debe a que el fragmento "IF (a)" no es una expresión JSL bien formada. Es decir, la función SI toma 2 argumentos, no uno. JMP no tiene forma de saber si "notAnIf(a)" es una expresión bien formada, por lo que tal vez se encoge de hombros y continúa (?). Total suposición de mi parte.
El hecho de que lo siguiente funcione como usted pretende parece agregar algo de apoyo a esta idea, pero esto no explica por qué @ben_ph La idea funciona, ya que inserta con éxito REPLACE_ME donde me falta.
expr = Expr( If( a, . ) );
Substitute Into( expr, expr(.), expr( If( b, c ) ) );
Show( Name Expr( expr ) );

Salud,
Brady
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?Como solución alternativa sin usar cadenas, podrías hacer algo como
expr = Expr( If( a ) );
Insert Into( expr, Expr( REPLACE_ME ) );
Substitute Into( expr, Expr( REPLACE_ME ), Expr( If( b, c ) ) );
Name Expr( expr );
// If( a, If( b, c ) )
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?Esto es relacionado cercanamente a lo mismo que Cómo insertar una lista en otra lista . Con su pregunta, ahora sospecho que hay una excepción especial para los nombres de funciones integradas que muestra este comportamiento.
expr = Expr( not an If( a ) );
es lo mismo que
expr = Expr( NotAnIf( a ) );
hacer que NotAnIf (o no un if) sea un nombre de función que JMP no reconoce como incorporado. En el ejemplo de { list }, {...} es lo mismo que List(...) y es un nombre de función incorporada.
expr = Expr( suma( a ) );
Insertar en( expr, Expr( suma( b, c ) ) );
Mostrar( Nombre Expr( expr ) );
/*:
Nombre Expr(expr) = Suma(a, b, c);
//:*/
expr = Expr( suma1( a ) );
Insertar en( expr, Expr( suma1( b, c ) ) );
Mostrar( Nombre Expr( expr ) );
/*:
Nombre Expr(expr) = suma1(a, suma1(b, c));
A mí tampoco me gusta.
@XanGregg
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?La coherencia entre versiones también es importante. Cada idioma tiene algunos defectos de diseño que se cometen desde el principio. Alguien (normalmente un desarrollador y un especialista en soporte técnico o un ingeniero de ventas) decide si
LongTermGainFromFixing - CostsOfFixing > CostOfDoingNothing
CostsOfFixing es realmente complicado, tiempo del desarrollador + tiempo de prueba + tiempo de documentación + tiempo de soporte técnico a corto plazo + irritación del cliente porque el JSL que funcionó antes ahora falla + oportunidades perdidas + el riesgo de empeorarlo.
CostOfDoingNothing también es complicado: cuánto soporte técnico se requiere, para siempre en el futuro, la cantidad de usuarios que alguna vez se enfrentarán al problema y qué tan difícil es entenderlo y solucionarlo. Más conjeturas.
Este foro, el foro de la lista de deseos, su representante de JMP y las reuniones del grupo de usuarios ayudan a orientar esa decisión. Gracias @hogi ¡Por ayudarme a conducir!
@Julian
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?Éste es un problema interesante.Podrías crear tu propia función para realizar la inserción, que funciona como se esperaba [creo], para todos los casos excepto el último de @hogi .En ese caso, sin embargo, la función devuelve el mismo resultado que cuando se llama a esa expresión usando Name Expr directamente, por lo que se podría argumentar que este es el resultado "correcto".
Names default to here(1);
// Make a new function to show each step of Insert Into:
New Insert Into = function( {exp, newarg, debug = 0 }, local({hd, ar, ne},
//Get the outermost function
hd = Head(exp);
if(debug, show(name expr( hd ) ) );
//Replace that function with a list so insert into works as expected
ar = substitute(name expr( exp ), name expr( hd ), {});
if(debug, show(name expr( ar ) ) );
//Now add the new argument
Insert Into( ar, name expr( newarg ) );
if(debug, show(name expr( ar ) ) );
//and put the orignial function back
ne = substitute(name expr( ar ), {}, name expr( hd ));
if(debug, show(name expr( ne ) ) );
Name expr( ne );
) );
// Test with the examples in the original post, note that they match:
Show( New Insert Into( Expr( If( a ) ), Expr( If( b, c ) ) ) ); // If(a, If(b, c))
Show( New Insert Into( Expr( Not an If( a ) ), Expr( If( b, c ) ) ) ); // Not an If(a, If(b, c))
// Additional examples from hogi post
Show( New Insert Into( Expr( If( a, x ) ), Expr( If( b, c ) ) ) ); // If(a, x, If(b, c))
Show( New Insert Into( Expr( If( a ) ), Expr( If( b ) ) ) ); // If(a, If
Show( New Insert Into( Expr( List( a ) ), Expr( List( b ) ) ) ); // List(a, b)
Show( New Insert Into( Expr( Graph Builder( a ) ), Expr( Graph Builder( b ) ) ) ); // Graph Builder(a, Graph Builder(b))
Show( New Insert Into( Expr( Head( a ) ), Expr( Head( b ) ) ) ); // Head(a, Head(b))
Show( New Insert Into( Expr( Not( a ) ), Expr( Not( b ) ) ) ); // !a
// The last one doesn't seem right but that it is actually being 'fixed' after as it is created:
Show( New Insert Into( Expr( Not( a ) ), Expr( Not( b ) ), debug = 1 ) ); // !a
// This is the same result as if you just call that directly, so I think this is the 'correct' result
Name Expr( Not(a, !b) ); // !a
// This function replaces all the Head expressions, which I think is okay, note this line:
// Name Expr(ar) = {a, {b, c}}
Show( New Insert Into( Expr( If( a, If( b, c ) ) ), Expr( If( d, e ) ), 1 ) ); // If(a, If(b, c), If(d, e))
Aquí está la misma función sin el material de depuración:
New Insert Into = function( {exp, newarg }, local({hd, ar, ne},
hd = Head(exp);
ar = substitute(name expr( exp ), name expr( hd ), {});
Insert Into( ar, name expr( newarg ) );
ne = substitute(name expr( ar ), {}, name expr( hd ));
name expr( ne );
) );
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?Esto soluciona el problema con el doble del mismo tipo de expresión. Sí.
Pero me temo que no es un reemplazo tan universal para Insertar en como uno podría desear.
Show( New Insert Into( Expr( If( a )), Expr( List( b,c )) ) ); // If(a,b,c)
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?Sin embargo, mi principal intención aquí:
Entender POR QUÉ Insertar en aplana la estructura, de modo que cada vez que use la función en el futuro, pueda estar seguro de que hará lo correcto.
Para 2 listas, parece una función útil: genera automáticamente una lista aplanada.
Hm, tan útil como el ajuste de rango automático en Graph Builder, es decir: para el 93% de los casos ayudará, para los demás casos...
Mapa de calor - opción: espaciado de ticks fijo (área de agregación)
¿Hay algo más detrás de esto que intentar ser "útil"?
Lo nuevo para mí fue que no se trata solo de ayudar con la lista...
En cuanto a las "soluciones" para Insertar en con el caso especial de 2x el mismo tipo de expresión:
- Quizás haya una opción oculta: no aplanar(0|1) ?
expr = Expr( If( a ) );
Insert Into( expr, Expr( REPLACE_ME ) );
Substitute Into( expr, Expr( REPLACE_ME ), Expr( If( b, c ) ) );
Name Expr( expr );
es maravilloso 
NÓTESE BIEN:
@ih escribió:
... sólo se debe reemplazar la primera instancia.
Tuve un problema similar hace unos días y se me ocurrió la idea: Indexación de expresiones: acceso de lectura y escritura.
Podría llevar el manejo de expresiones en Jmp/JSL a un nuevo nivel. Si lo encuentras útil, puedes votar por él...
[Agregué un comentario con un enlace a esta publicación.]
Re: Rareza de JMP Expr(), ¿alguien puede explicarlo?
@hogi escribió:
Con respecto a las "soluciones" para Insertar en con el caso especial de 2 veces el mismo tipo de expresión:
- ¿Quizás haya una opción oculta: flatten(0|1) ?
No lo parece...
Aquí está el deseo de obtener dicha opción: Insertar en: Aplanar(0|1)