compute-engine
                                
                                 compute-engine copied to clipboard
                                
                                    compute-engine copied to clipboard
                            
                            
                            
                        API to get a list of all free variables for an expression
I have a use-case with ce.defaultDomain = null where I am trying to parse a latex string and get a list of all symbols which are free-variables
This has been my partial attempt by following the documentation but I feel it is not quite right
import {ComputeEngine} from '@cortex-js/compute-engine';
const ce = new ComputeEngine();
ce.defaultDomain = null;
const expr = ce.parse('x + 1');
// Following that the root expression is a function ops will contain the symbols and values. 
// Might have to traverse recursively all BoxedExpressions in the ops. 
const symbols = expr.ops?.filter((e) => e.head === 'Symbol');
// How do I know if the symbol is a free variable 🤔 ? 
... 
Although it seems obvious that there should be a way to find it out easily, but I might be wrong. Feel free to let me know if it is indeed an absurd request 😅. Thanks!
You're on the right track...
A free variable is a symbol that does not have a value. It may still have a domain. In fact, having a domain is often very useful. For example, in the expression x + 1, that is ["Add", "x",  1], the Add function cannot be interpreted correctly if the domain of x is not known: it could be a number, but it could also be a matrix, or some other mathematical object.
So, you do not need to set the ce.defaultDomain to null in order to have free variables.
In order to get all the free variables in an expression, you do need to recursively examine the elements of the expression, and filter out all the symbols that have no value. To identify a symbol, you can indeed check that e.head === 'Symbol', or you can also check that e.symbol is not null. Furthermore, you need to check that e.value is not null.
I will add a expr.symbols property that will return all (recursively) the symbols in an expression and a expr.isFree property that will be true if the symbol has no value. Once that's in, you will be able to get all the free variables of an expression with expr.symbols.filter(x => x.isFree).
Thanks @arnog. I will give e.value a try.
Looking forward to the symbols property. It will definitely make my life easier.
The expr.symbols property is available in v0.8.0. Note also that the expr.subexpressions property may be useful.