# Confused by the various string "factory" functions - shouldn't these play nice together?

**URL:** <https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591>\
**Category:** General Usage\
**Tags:** strings\
**Created:** [March 10, 2017, 3:11pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591 "2017-03-10T15:11:56Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [March 10, 2017, 3:11pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/1 "2017-03-10T15:11:56Z")

</div>

I’ve stumbled onto some things that I don’t quite understand - it all started with me trying to get `join` to generate empty strings `""` when joining `nothing`s (`Void`s).

Between `string`, `String`, `convert` and string generating functions like `join`, it seems to me that behaviour should be consistent.

Example:

```julia
julia> test_arr = [nothing, nothing]
2-element Array{Void,1}:
 nothing
 nothing

julia> join(test_arr)
"nothingnothing"

julia> import Base.string

julia> string(::Void) = ""
string (generic function with 14 methods)

julia> string(nothing)
""

julia> join(test_arr)
"nothingnothing"

julia> convert(String, n::Void) = ""
convert (generic function with 1 method)

julia> join(test_arr)
"nothingnothing"

julia> String(nothing)
------ MethodError --------------------- Stacktrace (most recent call last)

 [1] — String(::Void) at sys.dylib:?

 [2] — String(::Void) at sysimg.jl:53

MethodError: Cannot `convert` an object of type Void to an object of type String
This may have arisen from a call to the constructor String(...),
since type constructors fall back to convert methods.

```

1. `join` does not use my `string` nor my `convert` functions - I’m wondering what _does_ it use to convert to strings?
2. `String` doesn’t use my convert function either?

What am I missing?

Thanks  
A

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 10, 2017, 3:30pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/2 "2017-03-10T15:30:04Z")

</div>

See [doc of `string`](http://docs.julialang.org/en/latest/stdlib/strings.html#Base.string) In general you should overload [how printing is done](http://docs.julialang.org/en/latest/manual/types.html#Custom-pretty-printing-1)

`String` is totally different. It is an explicit conversion and not printing.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [March 10, 2017, 3:52pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/3 "2017-03-10T15:52:26Z")

</div>

Thanks, I’ll give it a go.

So then, `join` uses internally one of the `print`, `show`, `display`, etc family of functions?

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [March 10, 2017, 3:57pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/4 "2017-03-10T15:57:17Z")

</div>

Hmmm, looking into the docs:

> String(s::AbstractString)  
> Convert a string to a contiguous byte array representation encoded as UTF-8 bytes. This representation is often appropriate for passing strings to C.

Due to the uppercase “S” I expected this to be a `string` constructor, similar to `SomeType(...)` - and thus behave pretty much like `string`. It seems that’s not the case.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [March 10, 2017, 4:02pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/5 "2017-03-10T16:02:54Z")

</div>

@yuyichao

Just to be 100% clear, my issue is not one of printing in the REPL. It is about changing the actual value returned by `join([nothing])`, from “nothing” to “”.

My use case is closer to this:

```julia
julia> [if false
       "moo"
       end] |> join
julia> "nothing"

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 10, 2017, 4:16pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/6 "2017-03-10T16:16:28Z")

</div>

> [@essenciary](#):
>
> I expected this to be a string constructor, similar to SomeType(…)

Yes, though not because of the upper case, it is the constructor.

> [@essenciary](#):
>
> and thus behave pretty much like string.

No. A constructor is basically an explicit constructor. Printing is totally different and that’s what `string` does as shown in the doc.

> [@essenciary](#):
>
> not one of printing in the REPL

That’s not what I’m talking about either. All of the functions you mentioned are wrappers around printing objects and so that’s what you should overload. If you overload one of the wrappers (e.g. `string`) to not do what the doc says the functions should be doing, it’ll certainly not be consistent with other functions anymore.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 10, 2017, 4:21pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/7 "2017-03-10T16:21:09Z")

</div>

And as for the `convert`. You are overloading (or not overloading at all) the wrong function with the [wrong syntax](http://docs.julialang.org/en/latest/manual/methods.html). Use `Base.convert(::Type{String}, ::Void)`. Also note that you should not overload this particular method other than for test purposes.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [March 10, 2017, 4:37pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/8 "2017-03-10T16:37:46Z")

</div>

Thanks very much @yuyichao

You’re right 😄 I don’t know what the heck I was trying to do with that `convert`! Thanks for pointing that out 😊

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 11, 2017, 2:54am UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/9 "2017-03-11T02:54:39Z")

</div>

> [@essenciary](#):
>
> It is about changing the actual value returned by `join([nothing])`, from `"nothing"` to `""`.

Usually it is a bad idea to change the behavior of a function from another module (here, `Base.join`) with a type from another module (here, `[nothing]` is of type `Base.Array{Void,1}`). It is fine to overload a function from another module, but the rule of thumb is that at least one of the argument types should be specific to your module.

Probably there is a better way to do what you are trying to do. What underlying problem are you trying to solve?

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [March 11, 2017, 5:01pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/10 "2017-03-11T17:01:45Z")

</div>

@stevengj Thanks!

I’m building a templating system (think Mustache, but more like Haml). It uses Julia itself. It allows doing things like:

```julia
<html_here>
<% if is_logged_in %>
<a href="...">Log off</a>
<% end %>
<more_html_here>

```

The output of the Julia code is inserted into the page - the problem is, if `! is_logged_in` the `if` will return `nothing` which ends up as `"nothing"`.

Of course I could force the developer to always do `if ... else ...` but that’s really ugly.

Or I could define an `if()` function which in the form `if(f::Function, condition::Bool)` which would end up as

```julia
<% if(is_logged_in) do %>
...
<% end %>

```

That’s probably acceptable though not equally nice - nor do I like limiting user’s options.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 11, 2017, 5:08pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/11 "2017-03-11T17:08:11Z")

</div>

You should just have your own wrapper function that turns `nothing` into empty string/ignore it instead of overwriting a base function and breaks every other packages.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 11, 2017, 5:08pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/12 "2017-03-11T17:08:20Z")

</div>

> [@essenciary](#):
>
> The output of the Julia code is inserted into the page - the problem is, if ! is\_logged\_in the if will return nothing which ends up as “nothing”.

The normal approach to this in Julia would be to define your own method, and use dispatch to special-case particular types. For example:

```julia
templateoutput(io, x) = println(io, x)

templateoutput(io, ::Void) = nothing

function templateoutput(io, X::AbstractVector)
    for x in X
        templateoutput(io, x)
    end
end

```

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [March 11, 2017, 6:21pm UTC](https://discourse.julialang.org/t/confused-by-the-various-string-factory-functions-shouldnt-these-play-nice-together/2591/13 "2017-03-11T18:21:03Z")

</div>

Thanks for your help, much appreciated – I ended up defining my own function, no messing around with `Base`. ☀
