title: Julia: how to mimic some "typedef/using" we use in C++ (and without perfs penalty)?
body: <p>Basically, I want to provide some type information in a <code>struct A</code> that will be used later to define the return type of the <code>foo_1</code> function.</p>
  
  <p>Here is the Julia code I have so far:</p>
  
  <pre><code>struct A
      type::DataType
  end
  
  foo_1(a::A)::a.type = 2018
  </code></pre>
  
  <p>Usage example:</p>
  
  <pre><code>julia&gt; a=A(Float64)
  julia&gt; foo_1(a)
  2018.0
  </code></pre>
  
  <p>-> This work as expected: 2018 is converted into <code>a.type</code> type, here a <code>Float64</code></p>
  
  <p>However, my problem/interrogation come from that fact that, when compared with the function <code>foo_2</code> that do basically the same thing without using <code>x.type</code></p>
  
  <pre><code>foo_2(a::A)::Float64 = 2018
  </code></pre>
  
  <p>there is an <strong>important</strong> difference in the generated code:</p>
  
  <pre><code>julia&gt; @code_native foo_2(a)
      .text
  Filename: REPL[4]
      pushq   %rbp
      movq    %rsp, %rbp
      movabsq $139943184603960, %rax  # imm = 0x7F470FCE9B38
  Source line: 1
      movsd   (%rax), %xmm0           # xmm0 = mem[0],zero
      popq    %rbp
      retq
      nopw    %cs:(%rax,%rax)
  </code></pre>
  
  <p>-> This is OK</p>
  
  <p>However for <code>foo_1(a::A)::a.type</code> function:</p>
  
  <pre><code>julia&gt; @code_native foo_1(a)
      .text
  Filename: REPL[3]
      pushq   %rbp
      movq    %rsp, %rbp
      pushq   %r15
      pushq   %r14
      pushq   %rbx
      subq    $56, %rsp
      movq    %rdi, %r14
      movq    %fs:0, %r15
      addq    $-10888, %r15           # imm = 0xD578
      leaq    -48(%rbp), %rdi
      xorps   %xmm0, %xmm0
      movups  %xmm0, -48(%rbp)
      movq    $0, -32(%rbp)
      movq    $8, -72(%rbp)
      movq    (%r15), %rax
      movq    %rax, -64(%rbp)
      leaq    -72(%rbp), %rax
      movq    %rax, (%r15)
      movq    $0, -56(%rbp)
  Source line: 1
      movq    (%r14), %rax
      movabsq $139943153507008, %rcx  # imm = 0x7F470DF41AC0
      leaq    634701288(%rcx), %rdx
      movq    %rdx, -48(%rbp)
      movq    %rax, -40(%rbp)
      movq    %rcx, -32(%rbp)
      movabsq $jl_apply_generic, %rax
      movl    $3, %esi
      callq   *%rax
      movq    %rax, %rbx
      movq    %rbx, -56(%rbp)
      movq    (%r14), %rsi
      movabsq $jl_typeassert, %rax
      movq    %rbx, %rdi
      callq   *%rax
      movq    -64(%rbp), %rax
      movq    %rax, (%r15)
      movq    %rbx, %rax
      addq    $56, %rsp
      popq    %rbx
      popq    %r14
      popq    %r15
      popq    %rbp
      retq
  </code></pre>
  
  <p>-> I am surprised that Julia JIT is not able to generate an optimized function. IMHO it has all the required information at the call site <code>foo_1(a)</code> to do so.</p>
  
  <p>--> I fear that the difference in generated code is so big that I will get bad performance if I use the approach with <code>a.type</code>. </p>
  
  <p><strong>So my questions are:</strong></p>
  
  <ul>
  <li><p>1/ is there a better Julia way to define type information (I am thinking of <code>typedef</code> C++ equivalent)</p></li>
  <li><p>2/ how to explain the generated code difference between foo_1(a) and foo_2(a) </p>
  
  <p>-> My explanation so far: I think that like foo_1 is not a parametric function Julia generates only <strong>one</strong> instance of the function and hence it is obliged to <strong>dynamically</strong> resolves the type (even if struct A is <strong>immutable</strong>). Am I right?</p></li>
  </ul>
  
  <hr>
  
  <p><strong>Note:</strong> I could have written</p>
  
  <pre><code>struct B{T}
  end
  
  foo_3{T}(b::B{T})::T  = 2018
  </code></pre>
  
  <p>That works (in the sense that native code of <code>foo_3</code> is the same as <code>foo_2</code>), however this is an awkward solution to define several types:</p>
  
  <pre><code>struct B{T1,T2,T3,...}
  end
  </code></pre>
  
  <p>C++ equivalent would be, without "parasite" template parameters:</p>
  
  <pre><code>struct B {
      using T1 = ...;
      using T2 = ...;
      using T3 = ...;
      ...
  };
  </code></pre>