-
Notifications
You must be signed in to change notification settings - Fork 177
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
Rewriting variables in where
and by
#1002
Comments
If you're beginning rewrites that affect scoping, perhaps it is worth opening the discussion of what the scoping rules for mavo should be? In particular, Mavo's procedure for resolving x.foo when x does not have a foo property is to resolve foo in the scope of x which I think is generally wrong and is certainly a big source of bugs. |
Yeah taking a closer look at scoping is definitely a good idea. @karger in the example you provided above, what does it mean that mavo tries to resolve |
@adamjanicki2 it isn't clear it is a good idea because it will be messy and time consuming. but an example can be found here: |
Hmm that's interesting, perhaps we can try to address this if we have time after taking care of the main issue which is moving mavo to ESM |
I agree, but this will be far easier to resolve after these changes (some of it may even resolve itself simply because its root cause is that in |
What's an example when the second clause of the where is not a property of the first? I read the mavo docs and am still confused. I think what I'm confused about is why, if Nevermind I think I get it; there could be cases where unrelated variables are used in the second clause, for example, this expression: My brain is definitely tired today 😆 |
Oh it's super common. E.g. consider |
I frequently end up with really confusing where clauses like item where label=label . I can never remember later which of the two labels is evaluated in the context/scope of item and which refers to some other property to which I'm comparing it. I eveentually figure out that item where item.label=label is clearer. |
Yeah I think in general I'm going to think about this tonight and tomorrow before rushing into implementing it; this is certainly a messy thing to fix |
This is part of #967 and depends on #975.
When we started this effort, I did say that
where
is a little trickier to rewrite. With everything else we can just extract top-level variables, distinguish globals, Mavo functions, and variables that come from properties, prepend them withglobalThis
,$fn
, or$data
accordingly and we're done.Rewriting
where
andby
involves an additional challenge: When we write something likefoo where bar = 3
, we don't know until runtime ifbar
is a property offoo
, or a property in that scope. In the functional form of the filter, this would be clear:filter(foo, foo.bar = 3)
for the former andfilter(foo, bar = 3)
for the latter.Right now this is done by adding a
scope()
function, which can be used independently, implemented entirely in mavoscript.js as a serializer . To implement that, an overcomplicated workaround is used involving anotherwith
, quite possibly the most complicated piece of code in the entire codebase (competing only with the stuff indata.js
andprimitive.js
). It is probably not a good use of your time @adamjanicki2 to try and understand how this code works, since it's written that way to overcome challenges the new approach doesn't have in the first place.Instead, I think it's better to write an algorithm from scratch, keeping in mind that:
$this
should not be touched.Basically, for every top-level variable in the second operand of
where
that is NOT$this
, we want to rewrite it in a way that looks on operand 1 first, then falls back to regular resolution. Essentiallyfoo where bar = 3
would becomefilter(foo, firstDefined(foo.bar, bar) = 3)
wherefirstDefined()
would be something like(...args) => args.find(a => a !== undefined)
, but that won't work becausefoo
andbar
are proxies and never returnundefined
. So it will need some digging to properly tell these cases apart. Also, we don't want to be evaluatingfoo
twice, especially if it's an expression, so we'd need to assign it to a variable.Actually, I think we should do this before #976.
$data.
#976 anyway (i.e. the result of the rewrite will still go through the regular rewriting pipeline, and that is something to keep in mind)While we're at it, we could also fix existing longstanding
where
bugs like #740by
has similar issues, though I think right now we don't treat it the same way and we just assume that every variable in the 2nd operand is implicitly scoped to the first operand.It's unclear if we still need a
scope()
function after this, but it probably wouldn't be too hard to implement if so.The text was updated successfully, but these errors were encountered: