# BioSequences upgrade works on 1.0 but not 0.7

**URL:** <https://discourse.julialang.org/t/biosequences-upgrade-works-on-1-0-but-not-0-7/13708>\
**Category:** General Usage\
**Tags:** question, package\
**Created:** [August 19, 2018, 12:06pm UTC](https://discourse.julialang.org/t/biosequences-upgrade-works-on-1-0-but-not-0-7/13708 "2018-08-19T12:06:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ward9250](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ward9250/32/42768_2.png) [@Ward9250](https://discourse.julialang.org/u/Ward9250)\
**Post date:** [August 19, 2018, 12:06pm UTC](https://discourse.julialang.org/t/biosequences-upgrade-works-on-1-0-but-not-0-7/13708/1 "2018-08-19T12:06:06Z")

</div>

Hi,

We’ve been upgrading BioSequences for julia 0.7/1.0 at this PR: [https://github.com/BioJulia/BioSequences.jl/pull/41](https://github.com/BioJulia/BioSequences.jl/pull/41)

I’ve managed to get tests on TravisCI passing for julia 1.0 but oddly not 0.7. The error that throws for 0.7 is:

```julia
ERROR: LoadError: LoadError: LoadError: syntax: invalid variable expression in "where"

Stacktrace:

[1] include at ./boot.jl:317 [inlined]

[2] include_relative(::Module, ::String) at ./loading.jl:1038

[3] include at ./sysimg.jl:29 [inlined]

[4] include(::String) at /home/travis/build/BioJulia/BioSequences.jl/src/BioSequences.jl:11

[5] top-level scope at none:0

[6] include at ./boot.jl:317 [inlined]

[7] include_relative(::Module, ::String) at ./loading.jl:1038

[8] include at ./sysimg.jl:29 [inlined]

[9] include(::String) at /home/travis/build/BioJulia/BioSequences.jl/src/BioSequences.jl:11

[10] top-level scope at none:0

[11] include at ./boot.jl:317 [inlined]

[12] include_relative(::Module, ::String) at ./loading.jl:1038

[13] include(::Module, ::String) at ./sysimg.jl:29

[14] top-level scope at none:2

[15] eval at ./boot.jl:319 [inlined]

[16] eval(::Expr) at ./client.jl:399

[17] top-level scope at ./none:3

in expression starting at /home/travis/build/BioJulia/BioSequences.jl/src/bioseq/constructors.jl:65

in expression starting at /home/travis/build/BioJulia/BioSequences.jl/src/bioseq/bioseq.jl:119

in expression starting at /home/travis/build/BioJulia/BioSequences.jl/src/BioSequences.jl:208

```

Yet this does not happen on Julia 1.0.

What’s more, the methods indicated in the stacktrace, at `BioSequences.jl/src/bioseq/constructors.jl:65`, do not  
use the “where” syntax. I’m struggling to see if this is an error that is the fault of BioSequences code or a quirk of 0.7 that got fixed in 1.0, could I ask a few extra eyes to pass over this and see if (likely) and where I’m being silly? The actual branch with the upgrade changes is at:

```julia
(v1.0) pkg> add https://github.com/dcjones/BioSequences.jl.git#julia1

```

Thanks!

---

<div class="post-metadata">

**Author:** ![miguelraz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miguelraz/32/631_2.png) [@miguelraz](https://discourse.julialang.org/u/miguelraz)\
**Post date:** [August 19, 2018, 3:05pm UTC](https://discourse.julialang.org/t/biosequences-upgrade-works-on-1-0-but-not-0-7/13708/2 "2018-08-19T15:05:50Z")

</div>

I have a local patch where it passes tests on v0.7 - it seems you got bit by the constructors no longer having the `convert fallback:  
Testing my local patch:

```julia
┌ Warning: Constructors no longer fall back to `convert`. A constructor `BioSequences.BioSequence{BioSequences.DNAAlphabet{2}}(::BioSequences.BioSequence{BioSequences.DNAAlphabet{4}})` should be defined instead.
│ caller = convert(::Type{BioSequences.BioSequence{BioSequences.DNAAlphabet{2}}}, ::BioSequences.BioSequence{BioSequences.DNAAlphabet{4}}) at conversion.jl:25
└ @ BioSequences ~/.julia/packages/BioSequences/lsGtC/src/bioseq/conversion.jl:25
┌ Warning: Constructors no longer fall back to `convert`. A constructor `BioSequences.BioSequence{BioSequences.DNAAlphabet{2}}(::BioSequences.BioSequence{BioSequences.DNAAlphabet{4}})` should be defined instead.
│ caller = convert at conversion.jl:25 [inlined]
└ @ Core ~/.julia/packages/BioSequences/lsGtC/src/bioseq/conversion.jl:25

```

This is after I patched the constructor methods from

```julia
function BioSequence{DNAAlphabet{4}}(seq::BioSequence{DNAAlphabet{2}}) 
    newseq = BioSequence{DNAAlphabet{4}}(length(seq))
    for (i, x) in enumerate(seq)
        unsafe_setindex!(newseq, x, i)
    end
    return newseq
end

```

to

```julia
function BioSequence{DNAAlphabet{N}}(seq::BioSequence{DNAAlphabet{M}}) where {N<:Int,M<:Int}
    @assert N == 4 && M == 2
    newseq = BioSequence{DNAAlphabet{4}}(length(seq))
    for (i, x) in enumerate(seq)
        unsafe_setindex!(newseq, x, i)
    end
    return newseq
end

```

The code ran [with the rest of the methods patched as in this gist](https://gist.github.com/miguelraz/7645239f97a5a19cc196bdd55ed6b4e8), but tests hung until quitting 😕, and don’t know what to do next.

---

<div class="post-metadata">

**Author:** ![Ward9250](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ward9250/32/42768_2.png) [@Ward9250](https://discourse.julialang.org/u/Ward9250)\
**Post date:** [August 19, 2018, 7:22pm UTC](https://discourse.julialang.org/t/biosequences-upgrade-works-on-1-0-but-not-0-7/13708/3 "2018-08-19T19:22:55Z")

</div>

That’s really interesting, but how does it now which method to dispatch to when there are multiple methods since N and M can be any int value, until the assert statements are run?

---

<div class="post-metadata">

**Author:** ![Ward9250](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ward9250/32/42768_2.png) [@Ward9250](https://discourse.julialang.org/u/Ward9250)\
**Post date:** [August 19, 2018, 7:24pm UTC](https://discourse.julialang.org/t/biosequences-upgrade-works-on-1-0-but-not-0-7/13708/4 "2018-08-19T19:24:08Z")

</div>

@jgreener64 also had a shot at this and found that the following would work on 0.7 and 1.0:

```julia
abstract type Alphabet end
abstract type Sequence end

struct DNAAlphabet{n} <: Alphabet end

mutable struct BioSequence{A<:Alphabet} <: Sequence
    data::Vector{UInt64} # encoded character sequence data
    part::UnitRange{Int} # interval within `data` defining the (sub)sequence
    shared::Bool # true if and only if `data` is shared between sequences

    function BioSequence{A}(data::Vector{UInt64},
                            part::UnitRange{Int},
                            shared::Bool) where A
        return new(data, part, shared)
    end
end

function BioSequence{A}(seq::BioSequence{DNAAlphabet{2}}) where A <: DNAAlphabet{4}
    newseq = BioSequence{A}(length(seq))
    for (i, x) in enumerate(seq)
        unsafe_setindex!(newseq, x, i)
    end
    return newseq
end

```

Although using a parametric constraint and a “where” where only one possiblity is allowed is not ideal.

---

<div class="post-metadata">

**Author:** ![Ward9250](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ward9250/32/42768_2.png) [@Ward9250](https://discourse.julialang.org/u/Ward9250)\
**Post date:** [August 19, 2018, 8:31pm UTC](https://discourse.julialang.org/t/biosequences-upgrade-works-on-1-0-but-not-0-7/13708/5 "2018-08-19T20:31:56Z")

</div>

Interestingly, @jgreener64’s version made me think of the following alternative, which passes on both 0.7 and 1.0:

```julia
abstract type Alphabet end
abstract type Sequence end

struct DNAAlphabet{n} <: Alphabet end

mutable struct BioSequence{A<:Alphabet} <: Sequence
    data::Vector{UInt64} # encoded character sequence data
    part::UnitRange{Int} # interval within `data` defining the (sub)sequence
    shared::Bool # true if and only if `data` is shared between sequences

    function BioSequence{A}(data::Vector{UInt64},
                            part::UnitRange{Int},
                            shared::Bool) where A
        return new(data, part, shared)
    end
end

function (::Type{BioSequence{DNAAlphabet{4}}})(seq::BioSequence{DNAAlphabet{2}})
    newseq = BioSequence{DNAAlphabet{4}}(length(seq))
    for (i, x) in enumerate(seq)
        unsafe_setindex!(newseq, x, i)
    end
    return newseq
end

```
