# String constructor vs string function

**URL:** <https://discourse.julialang.org/t/string-constructor-vs-string-function/29501>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 4, 2019, 9:35pm UTC](https://discourse.julialang.org/t/string-constructor-vs-string-function/29501 "2019-10-04T21:35:27Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [October 4, 2019, 9:35pm UTC](https://discourse.julialang.org/t/string-constructor-vs-string-function/29501/1 "2019-10-04T21:35:27Z")

</div>

**Context:**

I have two enums as follows:

```julia
@enum HouseSize SMALL_HOUSE MEDIUM_HOUSE LARGE_HOUSE
@enum HouseEfficiency LOW_EFFICIENCY MEDIUM_EFFICIENCY HIGH_EFFICIENCY

```

If I just had the `HouseSize` enum, then I could simplify the levels to `SMALL`, `MEDIUM`, and `LARGE`, but since I also have `HouseEfficiency`, I need to disambiguate the `MEDIUM` levels. Anyhow, for use in plot titles I’ve implemented a `String` constructor as follows:

```julia
function String(hs::HouseSize)
    if hs == SMALL_HOUSE
        "small"
    elseif hs == MEDIUM_HOUSE
        "medium"
    else
        "large"
    end
end

```

**Question:**

I’m also aware of the `string` function, which turns arbitrary objects into strings by using their `print` methods. Should I be overloading `print` instead of `String`?

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [October 4, 2019, 10:19pm UTC](https://discourse.julialang.org/t/string-constructor-vs-string-function/29501/2 "2019-10-04T22:19:18Z")

</div>

Best practice is probably to [overload `show`](https://docs.julialang.org/en/v1.1/manual/types/#man-custom-pretty-printing-1) instead. I’m not entirely sure how you’re using this in plot titles, but in general if you’re just interested in displaying something rather than getting a `String` to do further processing on, it’s probably better to use the `show`/`display` machinery.

As an additional note, any reason you can’t substitute a single enum for your two as shown below? Seems cleaner to me since the enums are representing relatively similar things. I guess if you’re really attached to displaying “small” for sizes and “low” for efficiency, that wouldn’t work.

```julia
@enum Levels SMALL MEDIUM LARGE
const LOW = SMALL

```

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [October 4, 2019, 10:49pm UTC](https://discourse.julialang.org/t/string-constructor-vs-string-function/29501/3 "2019-10-04T22:49:49Z")

</div>

> [@non-Jedi](#):
>
> I’m not entirely sure how you’re using this in plot titles

I’m using something like the following for plot titles (yes, I know I could be using Plot Recipes):

```julia
function plot(::MyType; kwargs...)
    plot(
        ...,
        title = "blah blah $(String(size)) size house, $(String(efficiency)) efficiency"
    )
end

```

So, I don’t think this is a use-case for `show`. I should probably overload `print` and do

```julia
title = string("blah blah ", size, " size house, ", efficiency, " efficiency")

```

> [@non-Jedi](#):
>
> any reason you can’t substitute a single enum for your two as shown below?

I have various methods that dispatch on `::HouseSize` and `::HouseEfficiency`, so I need both.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [October 5, 2019, 1:23am UTC](https://discourse.julialang.org/t/string-constructor-vs-string-function/29501/4 "2019-10-05T01:23:07Z")

</div>

> [@CameronBieganek](#):
>
> So, I don’t think this is a use-case for `show`

Actually, this is a perfect use-case for defining a `show` method, and you almost never want to overload `print` (the standard definition of `print` is basically `print(io::IO, x) = show(io, x)` with error handling).

If you define `Base.show(io::IO, hs::HouseSize)`, you can directly do `plot(..., title="blah blah $size")`.

EDIT: As for when you might want to define `print` rather than `show`, the docstring of `print` says:

> `print` falls back to calling `show`, so most types should just define  
> `show`. Define `print` if your type has a separate “plain” representation.  
> For example, `show` displays strings with quotes, and `print` displays strings  
> without quotes.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [October 5, 2019, 2:42am UTC](https://discourse.julialang.org/t/string-constructor-vs-string-function/29501/5 "2019-10-05T02:42:03Z")

</div>

> [@non-Jedi](#):
>
> If you define `Base.show(io::IO, hs::HouseSize)` , you can directly do `plot(..., title="blah blah $size")` .

Oh yeah, good point about the interpolation! I had a brain fart there. Though that interpolation syntax also works properly if you overload `print` instead of `show`.

To add to your quote from the docstring:

> The representation used by `print` includes minimal formatting and tries to avoid Julia-specific details.

So it all comes down to whether I think the print/show method that I’m defining is a separate “plain” representation that avoids Julia-specific details. That’s a bit of a grey area, but in this case it seems to me that I’m defining the “plain” representation of my enum levels.

Also, of course, if I overload `show` it will affect printing at the REPL. In this case, I would prefer REPL printing to fall back to the `show` method for `Enum`. That won’t happen if I overload `show`:

```julia
julia> @enum HouseSize SMALL_HOUSE

julia> SMALL_HOUSE
SMALL_HOUSE::HouseSize = 0

julia> Base.show(io::IO, ::HouseSize) = print(io, "small")

julia> SMALL_HOUSE
small

```

It’s interesting to see what happens to REPL printing when I overload `print` instead of `show`:

```julia
julia> @enum HouseSize SMALL_HOUSE

julia> SMALL_HOUSE
SMALL_HOUSE::HouseSize = 0

julia> Base.print(io::IO, ::HouseSize) = print(io, "small")

julia> SMALL_HOUSE
small::HouseSize = 0

```

Now the prefix in the REPL output went from `SMALL_HOUSE` to `small`! Apparently the `Enum` show method calls `print` for that portion of the output.
