Is there a standard way to obtain a list of used symbols from the string or Expression?

Pseudocode:

```
let expr = Infix.parseOrThrow("sin(x) * y")
expr.GetSymbols() //return array [| "x"; "y" |]
```

Is there a standard way to obtain a list of used symbols from the string or Expression?

Pseudocode:

```
let expr = Infix.parseOrThrow("sin(x) * y")
expr.GetSymbols() //return array [| "x"; "y" |]
```

Workaround for me:

```
let getsymbols(expr:Expression) =
let rec loop (expr:Expression) (acc:Symbol list) =
match expr with
|Identifier(x) -> x::acc
|Function(x,y) -> loop y acc
|Product(x)
|Sum(x) -> x |> List.fold(fun t el -> t @ loop el acc) acc
|Power(x,y) -> loop x acc @ loop y acc
|Number(_) -> acc
| _ -> acc
loop expr []
|> Set.ofList
|> Set.toList
```

(I know that some option not checked)

Surprisingly this functionality was indeed missing. I’ve just committed support for this in the `Structure`

module to master and plan to do a new release soon.

The idea is similar to your implementation but reuses the existing `Structure.fold`

function and is a bit more general:

```
let collect (chooser:Expression->'T option) x =
let rec impl (acc:'T list) x =
match chooser x with
| Some result -> result::acc
| None -> fold impl acc x
impl [] x
```

This can then be used to find all identifier as follows (the actual committed implementation also sorts and drops duplicate entries):

```
let collectIdentifiers x =
x |> collect (function | Identifier _ as expr -> Some expr | _ -> None)
let collectIdentifierSymbols x =
x |> collect (function | Identifier symbol -> Some symbol | _ -> None)
```

Test Cases (`==+>`

calls `Infix.print`

on each list entry):

```
collectIdentifierSymbols (x*cos(y)) --> [ Symbol "x"; Symbol "y" ]
collectIdentifiers (x*cos(y)) ==+> [ "x"; "y" ]
collectIdentifiers (z/x*cos(y)**x) ==+> [ "x"; "y"; "z" ]
collectFunctionTypes (x*cos(y)) --> [ Cos ]
collectFunctions (x*cos(y)) ==+> [ "cos(y)" ]
collectNumberValues (x*cos(2*y-4)/3) --> [ -4N; 1N/3N; 2N; ]
collectNumbers (x*cos(2*y-4)/3) ==+> [ "-4"; "1/3"; "2" ]
```

Hmm, I would expect from such input data:

"z *sin(x) + x * cos(y) "

these results:

`["y"; "x"; "z"]`

But I get:

`["y"; "x"; "x"; "z"]`

With the routines I committed to the repo/master, or with the simplified ones I’ve posted here (where I did not include sorting and distinct)?

FYI, I’ve released the changes (including some others) as MathNet.Symbolics v0.8.0.