<p dir="auto">I have tried to make <a href="https://github.com/JuliaArrays/StaticArrays.jl">StaticArrays.jl</a> compatible with the functions in <code class="notranslate">Base.LinAlg</code> but I get hung up on some inconsistencies.</p>
<p dir="auto">The functions <code class="notranslate">lufact()</code>, <code class="notranslate">qr()</code> and <code class="notranslate">svd()</code> all use <code class="notranslate">similar()</code> to construct a (mutable) array for working with and returning output. In <em>StaticArrays</em> that would be e.g. the <code class="notranslate">MMatrix</code> type for a matrix. However, internal types like <code class="notranslate">Base.LinAlg.SVD</code> have fields which must be of type <code class="notranslate">Array</code>.</p>
<p dir="auto">I consider this a bug since, according to the docs, <code class="notranslate">similar</code> should "Create an uninitialized mutable array with the given element type and size" and is not bound to return <code class="notranslate">Array</code>. We should widen the array field types in <code class="notranslate">SVD</code> and <code class="notranslate">LU</code> using an extra type parameter like in <code class="notranslate">Eigen</code>, and do something to fix the problem with <code class="notranslate">qr()</code> (also, there may be other functions with <em>similar</em> problems).</p>
<p dir="auto">Alternatively we could use <code class="notranslate">Array</code> constructors where they are required, but I think this is not preferable. Julia is meant to be a generic language.</p>
<p dir="auto">Examples:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type &quot;?help&quot; for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.5.1-pre+2 (2016-09-20 03:34 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit f0d40ec (13 days old release-0.5)
|__/                   |  x86_64-linux-gnu

julia&gt; using StaticArrays

julia&gt; m = @SMatrix [1.0 2.0; 3.0 4.0]
2×2 StaticArrays.SMatrix{2,2,Float64,4}:
 1.0  2.0
 3.0  4.0

julia&gt; eig(m) # successfully returns MVector and MMatrix (not Array)
([-0.372281,5.37228],
[-0.824565 -0.415974; 0.565767 -0.909377])

julia&gt; lufact(m)
ERROR: MethodError: no method matching Base.LinAlg.LU{Float64,StaticArrays.MMatrix{2,2,Float64,4}}(::StaticArrays.MMatrix{2,2,Float64,4}, ::StaticArrays.MVector{2,Int64}, ::Int64)
Closest candidates are:
  Base.LinAlg.LU{Float64,StaticArrays.MMatrix{2,2,Float64,4}}{T,S&lt;:AbstractArray{T,2}}(::AbstractArray{T,2}, ::Array{Int64,1}, ::Int64) at linalg/lu.jl:10
  Base.LinAlg.LU{Float64,StaticArrays.MMatrix{2,2,Float64,4}}{T}(::Any) at sysimg.jl:53
 in lufact!(::StaticArrays.MMatrix{2,2,Float64,4}, ::Type{Val{true}}) at ./linalg/lu.jl:20
 in lufact(::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/lu.jl:72

julia&gt; svd(m)
ERROR: MethodError: no method matching Base.LinAlg.SVD{T,Tr,M&lt;:AbstractArray}(::StaticArrays.MMatrix{2,2,Float64,4}, ::StaticArrays.MVector{2,Float64}, ::StaticArrays.MMatrix{2,2,Float64,4})
Closest candidates are:
  Base.LinAlg.SVD{T,Tr,M&lt;:AbstractArray}{T,Tr}(::AbstractArray{T,N}, ::Array{Tr,1}, ::AbstractArray{T,N}) at linalg/svd.jl:10
  Base.LinAlg.SVD{T,Tr,M&lt;:AbstractArray}{T}(::Any) at sysimg.jl:53
 in #svdfact!#32(::Bool, ::Function, ::StaticArrays.MMatrix{2,2,Float64,4}) at ./linalg/svd.jl:19
 in (::Base.LinAlg.#kw##svdfact!)(::Array{Any,1}, ::Base.LinAlg.#svdfact!, ::StaticArrays.MMatrix{2,2,Float64,4}) at ./&lt;missing&gt;:0
 in #svdfact#33(::Bool, ::Function, ::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/svd.jl:37
 in (::Base.LinAlg.#kw##svdfact)(::Array{Any,1}, ::Base.LinAlg.#svdfact, ::StaticArrays.SMatrix{2,2,Float64,4}) at ./&lt;missing&gt;:0
 in #svd#36 at ./linalg/svd.jl:57 [inlined]
 in svd(::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/svd.jl:57

julia&gt; qr(m)
ERROR: TypeError: typeassert: expected Array{Float64,2}, got StaticArrays.MMatrix{2,2,Float64,4}
 in (::Base.LinAlg.#kw##_qr)(::Array{Any,1}, ::Base.LinAlg.#_qr, ::StaticArrays.SMatrix{2,2,Float64,4}, ::Type{Val{false}}) at ./&lt;missing&gt;:0
 in qr(::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/qr.jl:173"><pre class="notranslate"><code class="notranslate">               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.5.1-pre+2 (2016-09-20 03:34 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit f0d40ec (13 days old release-0.5)
|__/                   |  x86_64-linux-gnu

julia&gt; using StaticArrays

julia&gt; m = @SMatrix [1.0 2.0; 3.0 4.0]
2×2 StaticArrays.SMatrix{2,2,Float64,4}:
 1.0  2.0
 3.0  4.0

julia&gt; eig(m) # successfully returns MVector and MMatrix (not Array)
([-0.372281,5.37228],
[-0.824565 -0.415974; 0.565767 -0.909377])

julia&gt; lufact(m)
ERROR: MethodError: no method matching Base.LinAlg.LU{Float64,StaticArrays.MMatrix{2,2,Float64,4}}(::StaticArrays.MMatrix{2,2,Float64,4}, ::StaticArrays.MVector{2,Int64}, ::Int64)
Closest candidates are:
  Base.LinAlg.LU{Float64,StaticArrays.MMatrix{2,2,Float64,4}}{T,S&lt;:AbstractArray{T,2}}(::AbstractArray{T,2}, ::Array{Int64,1}, ::Int64) at linalg/lu.jl:10
  Base.LinAlg.LU{Float64,StaticArrays.MMatrix{2,2,Float64,4}}{T}(::Any) at sysimg.jl:53
 in lufact!(::StaticArrays.MMatrix{2,2,Float64,4}, ::Type{Val{true}}) at ./linalg/lu.jl:20
 in lufact(::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/lu.jl:72

julia&gt; svd(m)
ERROR: MethodError: no method matching Base.LinAlg.SVD{T,Tr,M&lt;:AbstractArray}(::StaticArrays.MMatrix{2,2,Float64,4}, ::StaticArrays.MVector{2,Float64}, ::StaticArrays.MMatrix{2,2,Float64,4})
Closest candidates are:
  Base.LinAlg.SVD{T,Tr,M&lt;:AbstractArray}{T,Tr}(::AbstractArray{T,N}, ::Array{Tr,1}, ::AbstractArray{T,N}) at linalg/svd.jl:10
  Base.LinAlg.SVD{T,Tr,M&lt;:AbstractArray}{T}(::Any) at sysimg.jl:53
 in #svdfact!#32(::Bool, ::Function, ::StaticArrays.MMatrix{2,2,Float64,4}) at ./linalg/svd.jl:19
 in (::Base.LinAlg.#kw##svdfact!)(::Array{Any,1}, ::Base.LinAlg.#svdfact!, ::StaticArrays.MMatrix{2,2,Float64,4}) at ./&lt;missing&gt;:0
 in #svdfact#33(::Bool, ::Function, ::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/svd.jl:37
 in (::Base.LinAlg.#kw##svdfact)(::Array{Any,1}, ::Base.LinAlg.#svdfact, ::StaticArrays.SMatrix{2,2,Float64,4}) at ./&lt;missing&gt;:0
 in #svd#36 at ./linalg/svd.jl:57 [inlined]
 in svd(::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/svd.jl:57

julia&gt; qr(m)
ERROR: TypeError: typeassert: expected Array{Float64,2}, got StaticArrays.MMatrix{2,2,Float64,4}
 in (::Base.LinAlg.#kw##_qr)(::Array{Any,1}, ::Base.LinAlg.#_qr, ::StaticArrays.SMatrix{2,2,Float64,4}, ::Type{Val{false}}) at ./&lt;missing&gt;:0
 in qr(::StaticArrays.SMatrix{2,2,Float64,4}) at ./linalg/qr.jl:173
</code></pre></div>
<p dir="auto">This was reported at Stack Overflow:</p>
<ul dir="auto">
<li><a href="http://stackoverflow.com/questions/35094986/does-macro-hygiene-only-protect-you-in-different-modules" rel="nofollow">http://stackoverflow.com/questions/35094986/does-macro-hygiene-only-protect-you-in-different-modules</a></li>
</ul>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="   _       _ _(_)_     |  By greedy hackers for greedy hackers
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type &quot;?help&quot; for help.
  | | | | | | |/ _' |  |
  | | |_| | | | (_| |  |  Version 0.5.0-dev+2446 (2016-02-01 14:54 UTC)
 _/ |\__'_|_|_|\__'_|  |  custom/a9c732a (fork: 2 commits, 0 days)
|__/                   |  Arch Linux x86_64

julia&gt; macro g(y)
           :((x, $y, $(esc(y))))
       end

       x = 1
       function t()
           x = 2
           println(macroexpand(:(@g(x))))
           println(@g(x))
       end

       t()
       println(x)
(x,x,x)
(2,2,2)
1

julia&gt; workspace()

julia&gt; module A
       macro g(y)
           :((x, $y, $(esc(y))))
       end
       x = 1
       end

       x = 3

       function t()
           x = 2
           println(macroexpand(:(A.@g(x))))
           println(A.@g(x))
       end

       t()
(A.x,A.x,x)
(1,1,2)"><pre class="notranslate">   _       _ <span class="pl-c1">_</span>(_)_     <span class="pl-k">|</span>  By greedy hackers <span class="pl-k">for</span> greedy hackers
  (_)     <span class="pl-k">|</span> (_) (_)    <span class="pl-k">|</span>  Documentation<span class="pl-k">:</span> http<span class="pl-k">:</span><span class="pl-k">//</span>docs<span class="pl-k">.</span>julialang<span class="pl-k">.</span>org
   _ _   _<span class="pl-k">|</span> <span class="pl-k">|</span>_  __ _   <span class="pl-k">|</span>  Type <span class="pl-s"><span class="pl-pds">"</span>?help<span class="pl-pds">"</span></span> <span class="pl-k">for</span> help.
  <span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span><span class="pl-k">/</span> _<span class="pl-k">'</span> <span class="pl-k">|</span>  <span class="pl-k">|</span>
  <span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span>_<span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span> <span class="pl-k">|</span> (_<span class="pl-k">|</span> <span class="pl-k">|</span>  <span class="pl-k">|</span>  Version <span class="pl-c1">0.5</span>.<span class="pl-c1">0</span><span class="pl-k">-</span>dev<span class="pl-k">+</span><span class="pl-c1">2446</span> (<span class="pl-c1">2016</span><span class="pl-k">-</span><span class="pl-c1">02</span><span class="pl-k">-</span><span class="pl-c1">01</span> <span class="pl-c1">14</span><span class="pl-k">:</span><span class="pl-c1">54</span> UTC)
 _<span class="pl-k">/</span> <span class="pl-k">|</span><span class="pl-k">\</span>__<span class="pl-k">'</span>_<span class="pl-k">|</span>_<span class="pl-k">|</span>_<span class="pl-k">|</span><span class="pl-k">\</span>__<span class="pl-k">'</span>_<span class="pl-k">|</span>  <span class="pl-k">|</span>  custom<span class="pl-k">/</span>a9c732a (fork<span class="pl-k">:</span> <span class="pl-c1">2</span> commits, <span class="pl-c1">0</span> days)
<span class="pl-k">|</span>__<span class="pl-k">/</span>                   <span class="pl-k">|</span>  Arch Linux x86_64

julia<span class="pl-k">&gt;</span> <span class="pl-k">macro</span> <span class="pl-en">g</span>(y)
           :((x, <span class="pl-k">$</span>y, <span class="pl-k">$</span>(<span class="pl-c1">esc</span>(y))))
       <span class="pl-k">end</span>

       x <span class="pl-k">=</span> <span class="pl-c1">1</span>
       <span class="pl-k">function</span> <span class="pl-en">t</span>()
           x <span class="pl-k">=</span> <span class="pl-c1">2</span>
           <span class="pl-c1">println</span>(<span class="pl-c1">macroexpand</span>(:(<span class="pl-c1">@g</span>(x))))
           <span class="pl-c1">println</span>(<span class="pl-c1">@g</span>(x))
       <span class="pl-k">end</span>

       <span class="pl-c1">t</span>()
       <span class="pl-c1">println</span>(x)
(x,x,x)
(<span class="pl-c1">2</span>,<span class="pl-c1">2</span>,<span class="pl-c1">2</span>)
<span class="pl-c1">1</span>

julia<span class="pl-k">&gt;</span> <span class="pl-c1">workspace</span>()

julia<span class="pl-k">&gt;</span> <span class="pl-k">module</span> A
       <span class="pl-k">macro</span> <span class="pl-en">g</span>(y)
           :((x, <span class="pl-k">$</span>y, <span class="pl-k">$</span>(<span class="pl-c1">esc</span>(y))))
       <span class="pl-k">end</span>
       x <span class="pl-k">=</span> <span class="pl-c1">1</span>
       <span class="pl-k">end</span>

       x <span class="pl-k">=</span> <span class="pl-c1">3</span>

       <span class="pl-k">function</span> <span class="pl-en">t</span>()
           x <span class="pl-k">=</span> <span class="pl-c1">2</span>
           <span class="pl-c1">println</span>(<span class="pl-c1">macroexpand</span>(:(A<span class="pl-k">.</span><span class="pl-c1">@g</span>(x))))
           <span class="pl-c1">println</span>(A<span class="pl-k">.</span><span class="pl-c1">@g</span>(x))
       <span class="pl-k">end</span>

       <span class="pl-c1">t</span>()
(A<span class="pl-k">.</span>x,A<span class="pl-k">.</span>x,x)
(<span class="pl-c1">1</span>,<span class="pl-c1">1</span>,<span class="pl-c1">2</span>)</pre></div>
<blockquote>
<p dir="auto">I had expected the result to be (1, 1, 2).</p>
<p dir="auto">However, if I define the macro in a different module, it works as expected.</p>
<p dir="auto">Seems the hygiene simply prefix the symbols with the module namespace. Therefore it is impossible for the macro expander to distinguish different scopes in the first case.</p>
</blockquote>