# ValueSymbols

The module `ValueSymbols`

provides a wrapper type `ValueSymbol`

for
Julia Symbols, implemented as pointerfree "bitstype". This allows
storing `ValueSymbol`

objects very efficiently in immutable types or
tuples with other bitstype types. Regular `Symbol`

objects are stored
as pointers, hence are not bitstypes, and hence currently require heap
allocation.

```
using ValueSymbols
sym = :car
isbits(sym)
vsym = ValueSymbol(sym)
isbits(vsym)
```

`ValueSymbol`

is a bitstype, while `Symbol`

is not.

This is the practical consequence:

```
@time Pair{Symbol,Int}[:car => i for i in 1:1000000];
0.082046 seconds (1.00 M allocations: 38.147 MB, 79.57% gc time)
@time Pair{ValueSymbol,Int}[ValueSymbol(:car) => i for i in 1:1000000];
0.006780 seconds (2 allocations: 15.259 MB)
```

Creating tuples or pairs containing symbols requires one heap
allocation per tuple or pair. If you use a `ValueSymbol`

instead,
these allocations are avoided.

## Examples

Convert between symbols and value symbols:

```
using ValueSymbols
sym = :car
vsym = ValueSymbol(sym)
sym2 = Symbol(vsym)
@assert sym2 === sym
```

Converting to a value symbol and back gives the original symbol.

Comparisons:

```
using ValueSymbols
sym = :car
vsym = ValueSymbol(sym)
@assert vsym == sym
```

Value symbols and symbols can be compared directly. Note that this
works only with the regular comparison operator `==`

, not with the
object identity comparison `===`

, as the latter is always different
for different types.

Value symbols also define an ordering. This ordering is based on the symbols' name, same as for Julia's regular symbols:

```
@assert :car < :plane
@assert ValueSymbol(:car) < ValueSymbol(:plane)
```