(My original question seemed a bit convoluted, so I changed it significantly to make it succinct, but the basic questions are the same.)

I’m experiencing a difficulty in extending a `Base`

function type-stably. Not sure if the same difficulty arises for any `Base`

functions, but the one I’m having a difficulty with is `Base.in`

.

Consider the following code where I extend `Base.in`

for four concrete types of the same abstract type `MyAbs`

:

```
abstract type MyAbs end
struct MyType1 <: MyAbs end
struct MyType2 <: MyAbs end
struct MyType3 <: MyAbs end
struct MyType4 <: MyAbs end
Base.in(x::Int, ::MyType1) = x==1
Base.in(x::Int, ::MyType2) = x==2
Base.in(x::Int, ::MyType3) = x==3
Base.in(x::Int, ::MyType4) = x==4
```

Now, I would like to call `in`

with `Int`

and `MyAbs`

using the function below, which takes a vector of `MyAbs`

, iterates over the vector, and executes `in`

for each entry of the vector.

```
function zero_in(mvec::Vector{MyAbs})
# Return true if any element of mvec contains 0
t = false
for m = mvec
t = in(0, m)
t && break
end
return t
end
```

The output of this function turns out to be type-unstable:

```
julia> VERSION
v"0.6.1-pre.0"
julia> mvec = [MyType1(), MyType2(), MyType3(), MyType4()];
julia> @code_warntype zero_in(mvec)
Variables:
#self#::#zero_in
mvec::Array{MyAbs,1}
m::MyAbs
#temp#::Int64
t::Any
Body:
begin
t::Any = false # line 3:
#temp#::Int64 = 1
4:
unless (Base.not_int)((#temp#::Int64 === (Base.add_int)((Base.arraylen)(mvec::Array{MyAbs,1})::Int64, 1)::Int64)::Bool)::Bool goto 17
SSAValue(2) = (Base.arrayref)(mvec::Array{MyAbs,1}, #temp#::Int64)::MyAbs
SSAValue(3) = (Base.add_int)(#temp#::Int64, 1)::Int64
m::MyAbs = SSAValue(2)
#temp#::Int64 = SSAValue(3) # line 4:
t::Any = (0 in m::MyAbs)::Any # line 5:
unless t::Any goto 15
goto 17
15:
goto 4
17: # line 7:
return t::Any
end::Any
```

On the other hand, let’s repeat the same experiment with a non-Base function. Here I define `myfun`

that does exactly the same thing as `Base.in`

above, and also `zero_myfun`

that does exactly the same thing as `zero_in`

above:

```
myfun(x::Int, ::MyType1) = x==1
myfun(x::Int, ::MyType2) = x==2
myfun(x::Int, ::MyType3) = x==3
myfun(x::Int, ::MyType4) = x==4
function zero_myfun(mvec::Vector{MyAbs})
t = false
for m = mvec
t = myfun(0, m)
t && break
end
return t
end
```

Now, unlike the previous experiment, `zero_myfun`

produces a type-stable output:

```
julia> @code_warntype zero_myfun(mvec)
Variables:
#self#::#zero_myfun
mvec::Array{MyAbs,1}
m::MyAbs
#temp#::Int64
t::Bool
Body:
begin
t::Bool = false # line 3:
#temp#::Int64 = 1
4:
unless (Base.not_int)((#temp#::Int64 === (Base.add_int)((Base.arraylen)(mvec::Array{MyAbs,1})::Int64, 1)::Int64)::Bool)::Bool goto 17
SSAValue(2) = (Base.arrayref)(mvec::Array{MyAbs,1}, #temp#::Int64)::MyAbs
SSAValue(3) = (Base.add_int)(#temp#::Int64, 1)::Int64
m::MyAbs = SSAValue(2)
#temp#::Int64 = SSAValue(3) # line 4:
t::Bool = (Main.myfun)(0, m::MyAbs)::Bool # line 5:
unless t::Bool goto 15
goto 17
15:
goto 4
17: # line 7:
return t::Bool
end::Bool
```

Why do these two experiments give different behavior? More importantly, how can I extend `Base.in`

to produce a stable output in the first experiment?