# Add custom chain method

**URL:** <https://discourse.julialang.org/t/add-custom-chain-method/79589>\
**Category:** New to Julia\
**Created:** [April 17, 2022, 5:07am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589 "2022-04-17T05:07:29Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)\
**Post date:** [April 17, 2022, 5:07am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/1 "2022-04-17T05:07:29Z")

</div>

I have comtom struct:

```julia
struct Ci
    pre::Union{Ci,String}
    next::String
end

```

I can add chain method to construct an instance of it:

```julia
(::Colon)(x::Vararg{String})=begin
    pre=x[1]
    for next_ in x[2:end]
        pre=Ci(pre,next_)
    end
    return pre
end

"a":"b":"c"

Ci(Ci("a", "b"), "c")

```

But it can not be added for this method, which is the same as above with just different unicode

```julia
(..)(x::Vararg{Union{String}})=begin
    pre=x[1]
    for next_ in x[2:end]
        pre=Ci(pre,next_)
    end
    return pre
end

"a".."b".."c"
syntax: extra token ".." after end of expression

```

I can not figure out what is going on?

Would I must to write like this:`("a".."b").."c"`

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [April 17, 2022, 7:22am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/2 "2022-04-17T07:22:53Z")

</div>

See [this post](https://discourse.julialang.org/t/how-to-define-a-new-infix-operator/34803), which references [this post](https://discourse.julialang.org/t/is-not-an-operator/20221), which contains further references.

---

<div class="post-metadata">

**Author:** ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)\
**Post date:** [April 17, 2022, 8:06am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/3 "2022-04-17T08:06:38Z")

</div>

It do a infix operator well:

```julia
"a".."b"
# Ci("a", "b")

```

while fail to this:

```julia
"a".."b".."c"

```

Maybe it is not a problem of infix operator?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [April 17, 2022, 8:36am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/4 "2022-04-17T08:36:01Z")

</div>

Does it work with spaces between the operators?

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [April 17, 2022, 8:42am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/5 "2022-04-17T08:42:40Z")

</div>

> [@Brian1](#):
>
> Maybe it is not a problem of infix operator?

You are probably right. I don’t know enough about `::Colon` and parser restrictions (`..` could clash with the broadcast operator `.` somehow?), but the following variations seem to work

```julia
(&)(pre::Union{String,Ci},next_::String)=return Ci(pre,next_)
    
@show "a"&"b"
@show "a"&"b"&"c"        

(..)(x::Vararg{String})=begin
    pre=x[1]
    for next_ in x[2:end]
        pre=Ci(pre,next_)
    end
    return pre
end

@show ..("a","b")
@show ..("a","b","c")

```

yielding

```julia
"a" & "b" = Ci("a", "b")
("a" & "b") & "c" = Ci(Ci("a", "b"), "c")
"a" .. "b" = Ci("a", "b")
..("a", "b", "c") = Ci(Ci("a", "b"), "c")
Ci(Ci("a", "b"), "c")

```

Edit: switching the operators doesn’t work in both cases…

```julia
(..)(pre::Union{String,Ci},next_::String)=return Ci(pre,next_)
    
@show "a".."b"
@show "a".."b".."c"     

```

fails with

```julia
ERROR: syntax: ".." is not a unary operator

```

and

```julia
(&)(x::Vararg{String})=begin
    pre=x[1]
    for next_ in x[2:end]
        pre=Ci(pre,next_)
    end
    return pre
end

@show "a"&"b"
@show "a"&"b"&"c"

```

fails with

```julia
ERROR: MethodError: no method matching &(::Ci, ::String)

```

---

<div class="post-metadata">

**Author:** ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)\
**Post date:** [April 17, 2022, 9:16am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/6 "2022-04-17T09:16:58Z")

</div>

No, it does not. It appears the same error as above.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [April 17, 2022, 9:48am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/7 "2022-04-17T09:48:29Z")

</div>

~~Note that there is no performance advantage to marking a field with a `Union` type over `Any`. It’s nice because it’s a bit selfdocumenting, but if you want it to be more performant you’ll want a parametric type.~~ TIL

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [April 17, 2022, 10:02am UTC](https://discourse.julialang.org/t/add-custom-chain-method/79589/8 "2022-04-17T10:02:58Z")

</div>

That’s incorrect. Small unions of concrete types may still be stored inline.

Edit: The reason `Ci` here can’t be stored inline is due to it’s self-recursive definition. Annotating the type as a union will still allow the compiler to do union splitting, so it’s still better than `Any` performance-wise.
