Q: dealing with name conflict between scope object's fields and registered factories
For example if I registered a factory with name 'date' and then pass an object with date field:
math.import([
factory('date', ['typed'], () => { ... })
]);
math.evaluate("date(date)", { date: '2021-10-01' });
the library obviously can't understand what to use. Currently it throws " (intermediate value)(intermediate value)(intermediate value) is not a function " error.
Is there any way to explicitly describe a symbol in expressions: either it should be coming from the scope or from factories?
For example, evaluate("::date(date)", {date: '2021-10-01'})
or
evaluate("date(scope:date)", {date: '2021-10-01'})
Thanks, interesting question.
The vague error message is really unfortunate, I've seen that more often. Would be nice to improve on that.
As for having multiple "things" with the same name: even if it is possible to change mathjs to allow a variable having the same name as a function, I think it's something that is best avoided since it leads to confusion. Similar to shadowing variable names in a programming language.
So I would say: just keep things simple and give one of the two a differing name so there is no conflict.
Yeah, but in my case for example that scope objects come from external context, so I can't control they don't use any of reserved names. But even if I can it'd be quite hard to do (is there any list of them anywhere?). So ideally we'd have an error message like "You have a name conflict ..." and an ability to change an expression without changing a scope object.
It wouldn't be very hard to validate if there are conflicts I think: you can loop over all values in the provided scope, and check if any of the variables is already defined on the math object.