# `Feel.Syntax.NameSet`
[🔗](https://github.com/FeeJai/BDM/blob/feel-v0.1.0/apps/feel/lib/feel/syntax/name_set.ex#L1)

A set of canonical names (see `Feel.Name`) that tells a name from the start of one.

The parser makes a name one token at a time, from the tokens it reads, and has
to know when to stop. A run of name tokens can be as long as the expression
(`x + x + x + …` is all name tokens, since `+` can be a part of a name), so it
cannot try every length of it. What it asks of the names is whether what it has
made is one, only the start of one, or neither (`probe/2`): when it is neither,
no longer name made from it is one either, since each is the start of the next,
and the work for a name is the number of tokens that it has in common with a
known name, not how long the run is and not how long the known names are (D-177,
D-177).

The names are kept in order, so that a string and the names that start with it
are together, and the first name that is not before the string answers for all
of them. Names are added one at a time, as the parser binds the parameters,
iterators and keys that an expression introduces, and the set is a value: adding
a name gives a set and leaves the one it was made from as it was.

# `found`

```elixir
@type found() :: :name | :prefix | :none
```

What the names say of a string.

# `t`

```elixir
@opaque t()
```

# `new`

```elixir
@spec new(Enumerable.t()) :: t()
```

Returns the set of the given names.

    iex> set = Feel.Syntax.NameSet.new(["date and time", "date"])
    iex> Feel.Syntax.NameSet.probe(set, "date")
    :name

# `probe`

```elixir
@spec probe(t(), String.t()) :: found()
```

What the names say of a string: `:name` when it is one (and it may also start a
longer one), `:prefix` when it only starts one, `:none` when no name starts with
it.

    iex> set = Feel.Syntax.NameSet.new(["date and time", "date"])
    iex> Feel.Syntax.NameSet.probe(set, "date")
    :name
    iex> Feel.Syntax.NameSet.probe(set, "date and")
    :prefix
    iex> Feel.Syntax.NameSet.probe(set, "date or")
    :none
    iex> Feel.Syntax.NameSet.probe(Feel.Syntax.NameSet.new(), "date")
    :none

# `put`

```elixir
@spec put(t(), Feel.Name.t()) :: t()
```

Adds a name to the set.

    iex> set = Feel.Syntax.NameSet.put(Feel.Syntax.NameSet.new(), "first name")
    iex> Feel.Syntax.NameSet.probe(set, "first name")
    :name

---

*Consult [api-reference.md](api-reference.md) for complete listing*
