Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

within + count no cuenta llamadas recursivas #345

Open
asanzo opened this issue Apr 13, 2022 · 1 comment
Open

within + count no cuenta llamadas recursivas #345

asanzo opened this issue Apr 13, 2022 · 1 comment

Comments

@asanzo
Copy link
Collaborator

asanzo commented Apr 13, 2022

En este código:

function a(){ a() }

se cumple la expectativa within 'a' count(calls) == 0 y no debería, porque las calls deberían ser 1.
¿Quizás está relacionado con #334 ?

Es por eso que acá tuvimos que hacer la chanchada de hacer within 'a' count(calls) + count(calls 'a') para que diera el valor verdadero.

(por cierto QUE GROSO que tenga esas expresiones, el EDL es posta increíble) 👏 👏 👏

@flbulgarelli
Copy link
Member

flbulgarelli commented Apr 17, 2022

(por cierto QUE GROSO que tenga esas expresiones, el EDL es posta increíble) clap clap clap

Gracias 😄

La respuesta rápida es que no, no es un "bug" (si bien estamos de acuerdo en que no es el el comportamiento más feliz), dado que esto es así por diseño: las expectativas de Mulang siempre empiezan a analizarse en el propio nodo del AST y no en sus descendientes, y por eso cuando usás ciertos predicados (en este caso, estás usando implicitamente el predicado *, es decir, calls *) se excluye automáticamente al identificador usado en el scope (el within o through) de las opciones de búsqueda:

scopeFor :: ([Identifier] -> Inspection -> Inspection) -> Identifier -> Scope
scopeFor f name = (contextualized (f names), andAlso (except (last names)))
where names = splitOn "." name
compileCQuery :: (IdentifierPredicate -> IdentifierPredicate) -> E.CQuery -> Maybe ContextualizedInspection
compileCQuery pm (E.Inspection i p m) = ($ (compilePredicate pm p)) <$> compileInspection (compileVerb i) m
compileCQuery pm (E.AtLeast n q) = contextualized (atLeast (encode n)) <$> compileTQuery pm q
compileCQuery pm (E.AtMost n q) = contextualized (atMost (encode n)) <$> compileTQuery pm q
compileCQuery pm (E.Exactly n q) = contextualized (exactly (encode n)) <$> compileTQuery pm q
compileCQuery pm (E.CNot q) = contextualized never <$> compileCQuery pm q
compileCQuery pm (E.CAnd q1 q2) = contextualized2 andAlso <$> compileCQuery pm q1 <*> compileCQuery pm q2
compileCQuery pm (E.COr q1 q2) = contextualized2 orElse <$> compileCQuery pm q1 <*> compileCQuery pm q2

En otras palabras, con la implementación actual, el "hack" que propusiste es la forma de implementar este chequeo.

Cambiar este comportamiento es trivial, pero tiene un impacto profundo que podría generar ambigüedad en ciertas expectativas, como por ejemplo:

within `a` declares function

Esto hoy en día se interpreta como si hay una declaración de función dentro del contexto de la declaración de a, lo cual daría falso en function a() {} y verdadero en `function a() { function b() {} } . Eliminando la restricción actual ambas expresiones pasarían a producir expectativas verdaderas. ¿Se podría cambiar esto de una forma más inteligente? Sí, claro, se podría hacer que no considere a la propia expresión sino sólo a su contenido, pero es tricky porque ciertas expectativas tienen sentido sólo cuando se analiza el nodo raíz (ejemplo: las relativas a aridad). En otras palabras, la forma correcta de resolver esto requeriría que cada expectativa, en su definición, incluya información sobre dónde empezar a analizar cuando está contextualizada, lo cual es un refactor grande.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants