title: why two aliases to "array of string" treated differently?
body: <p>In Pascal there are two kinds of type declarations:</p>
  
  <ul>
  <li>type aliases: <em>type NewName = OldType</em></li>
  <li>type creation: <em>type NewType = <strong>type</strong> OldType</em></li>
  </ul>
  
  <p>The former is just creating convenient shorthand, like <em>typedef</em> in C. The aliases are compatible one to another and to their original type. The created types are intentionally incompatible and cannot be mixed without explicit and unsafe by definition typecast.</p>
  
  <pre><code>var
    nn: NewName; nt: NewType; ot: OldType;
  ...
    nn := ot; // should work
    nt := ot; // should break with type safety violation error.
  
    nt := NewType(ot); // Disabling type safety. Should work even if 
    // it has no sense semantically and types really ARE incompatible.
  </code></pre>
  
  <p>Those are Pascal basics as i understand them.</p>
  
  <p>Now let's look at one certain type and two its aliases:</p>
  
  <ul>
  <li>System.Types.TStringDynArray = <strong>array of</strong> string;</li>
  <li>System.TArray&lt;T&gt; = <strong>array of</strong> T;
  
  <ul>
  <li><em>in particular that means</em> TArray&lt;string&gt; = <strong>array of</strong> string; <em>by definition.</em></li>
  </ul></li>
  </ul>
  
  <p>Now let's take function returning the former type alias and feed its result to the function expecting the latter one:</p>
  
  <pre><code>uses Classes, IOUtils;
  
   TStringList.Create.AddStrings(
      TDirectory.GetFiles('c:\', '*.dll') );
  
   TStringList.Create.AddStrings(
       TArray&lt;string&gt;( // this is required by compiler - but why ???
           TDirectory.GetFiles('c:\', '*.dll') ) );
  </code></pre>
  
  <p>1st snippet would not compile due to types violation.
  2nd one happily compiles and works, but is fragile towards future type changes and is redundant.</p>
  
  <p>QC tells that compiler is right and the RTL design is wrong.
  <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=106246" rel="nofollow noreferrer">http://qc.embarcadero.com/wc/qcmain.aspx?d=106246</a></p>
  
  <p>WHY compiler is right here ?
  Why those aliases are incompatible ?
  Even the very manner RTL was designed suggests that they were deemed compatible!</p>
  
  <p>PS. David suggested even simplier example, without using TArray&lt;T&gt;</p>
  
  <pre><code> type T1 = array of string; T2 = array of string;
  
   procedure TForm1.FormCreate(Sender: TObject);
    function Generator: T1;
      begin Result := T1.Create('xxx', 'yyy', 'zzz'); end;
    procedure Consumer (const data: T2);
      begin
        with TStringList.Create do 
        try
          AddStrings(data);
          Self.Caption := CommaText;
        finally
          Free;
        end;
      end;
    begin
      Consumer(Generator);
    end;
  </code></pre>
  
  <p>Same gotcha without explanation...</p>
  
  <p>PPS. There are a number of doc refs now. I want to stress one thing: while this restriction might be indirectly inherited from Pascal Report of 1949, today is 2012 and Delphi used very differently from school labs of half-century ago.
  I named few BAD effects of keeping this restrictions, and yet did not saw any good one.</p>
  
  <p>Ironic thing, that this restricion may be lifted without breaking rules of Pascal: in Pascal there is no such non-strict beast as Open Arrays and Dynamic Arrays. So let those original fixed arrays be restricted as they wish, but Open Arrays and Dynamic Arrays are not Pascal citizens and are not obliged to be limited by its codebook!</p>
  
  <p>Please, communicate Emba in QC or maybe even here, but if u just pass by without expressing your opinion - nothing would change!</p>