# When should a function accept a symbol as an argument?

**URL:** <https://discourse.julialang.org/t/when-should-a-function-accept-a-symbol-as-an-argument/43510>\
**Category:** New to Julia\
**Tags:** question, metaprogramming, design\
**Created:** [July 22, 2020, 6:51pm UTC](https://discourse.julialang.org/t/when-should-a-function-accept-a-symbol-as-an-argument/43510 "2020-07-22T18:51:26Z")\
**Posts on this page:** 1\
**Showing post:** 35

<div class="post-metadata">

**Author:** ![Evey](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evey/32/214967_2.png) [@Evey](https://discourse.julialang.org/u/Evey)\
**Post date:** [July 25, 2020, 5:29pm UTC](https://discourse.julialang.org/t/when-should-a-function-accept-a-symbol-as-an-argument/43510/35 "2020-07-25T17:29:30Z")

</div>

The fact that it is a literal is a red herring. This optimisation will also happen if you use a variable:

```julia
const my_real_symbol = :real
f_symbol(x) = f(my_real_symbol, x)

```

In fact, in trying to construct this counter-example, I found that it will also happen with the string, if we modify the code slightly, and instead check if the strings compare equal with the “triple equality” operator, `===`:

```julia
f(s::String, x) = s === "real" ? x + 1 : x + 1im

```

In this case, we now get:

```julia
julia> Base.return_types(f_string, Tuple{Int64})[]
Int64

```

I am actually not entirely sure if there is a way to construct two strings that are equal, but don’t compare equal with `===`, so this example might be too simple.

Something symbols can which strings can’t, though, is appear in type parameters. In practice, you sometimes really need to use this fact for expressibility in a type system. For instance:

```julia
struct MyType{name} end
is_it_a(::MyType{name}, s) where {name} = s == name

x = MyType{:value}()
is_it_a(x, :number) # returns false
is_it_a(x, :value) # returns true

```

Another example is using `Val` from Base. You sometimes have situations where the best way to structure your code is something like:

```julia
@inline f(s::Symbol, x) = f(Val(s), x)
f(::Val{:real}, x) = x + 1
f(::Val, x) = x + 1im

```

The reason for writing code like that can either be due to readability, flexibility, or just because the compiler needs that bit of extra help.

So when you encounter an interface where you are asked to give it a symbol and not a string, these kinds of considerations may have been the underlying reason for choosing such an API. In other cases, as has been pointed out by others in this thread, it may just be that people have become so comfortable with symbols in the community that they don’t see them as something that presents an extra level of mental overhead. But it _is_ the case that there are things you can do with symbols that you can’t do with strings. So I do not think you are ever going to convince people that you should never use them as function input. And I think that once you accept that they might sometimes be used, it is better to use them early and often. That way, users will encounter them, wonder what they are, and hopefully learn it one way or the other. Otherwise, it might end up being something esoteric in the language that feels like magic, when it really isn’t.

---

_[View the full topic](https://discourse.julialang.org/t/when-should-a-function-accept-a-symbol-as-an-argument/43510)._
