<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2015-07-16 17:23 GMT+02:00 Sven Barth <span dir="ltr"><<a href="mailto:pascaldragon@googlemail.com" target="_blank">pascaldragon@googlemail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class=""><p>Then let me tell you that generic methods will arrive in mode ObjFPC (and thus its syntax) first, because the Delphi syntax is a PITA to parse/handle.<br></p></span><p>
(in fact generic methods are already working in mode ObjFPC in my local repo, I just want to get the Delphi ones working a little bit before commiting to trunk)</p></blockquote><div><br></div><div>@Sven, @Michael</div><div><br></div><div><div>I am using generics all the time for many things.</div><div><br></div><div>IMO using "generic/specialize" syntax because it is more simple to implement in compiler is very strange motivation. Using specialize keyword maybe is good in pure theory but is non practical (generic keyword in type declaration is not so bad).</div><div><br></div><div>You can torture me (!!!) but I will not use so many unnecessary words for simple things.</div><div>By using this complicated syntax you will kill all functional/generic approach.</div><div><br></div><div>Advice "if you like shorter syntax then go to other language" is no solution for me. I like some modern versions of Pascal like presented in Oxygen and till Delphi XE2 (! many things after XE2 is pure evil).</div><div><br></div><div>I am working on smart pointers/objects (some evolution/for the purposes of Generics.Collections). Syntax with generic/specialize is not "smart" for my branch:</div><div><br></div><div>=============== CODE BEGIN ===============</div><div>{$MODE SPARTA}</div><div>var</div><div> X: strong TDictionary<weak TList<Integer>, string>; </div><div>  </div><div>{ sugar syntax for </div><div>var  </div><div> X: SmartObj<TDictionary<WeakObj<TList<Integer>>, string>>;  }</div><div>===============  CODE END  ===============</div><div>  </div><div>so probably in ObjFPC, code above will become: </div><div>  </div><div>=============== CODE BEGIN ===============</div><div>{$MODE OBJFPC}</div><div>type</div><div> TList_Integer = specialize TList<Integer>;</div><div> WeakObj_TList_Integer = specialize WeakObj<TList_Integer>;</div><div> TDictionary_WeakObj_TList_Integer_String = specialize TDictionary<WeakObj_TList_Integer, string>;</div><div> SmartObj_TDictionary_WeakObj_TList_Integer_String = specialize SmartObj<TDictionary_WeakObj_TList_Integer_String>;</div><div>  </div><div>var</div><div> X: SmartObj_TDictionary_WeakObj_TList_Integer_String;</div><div>===============  CODE END  ===============</div><div><br></div><div>Another simple example. Maybe not a good example to follow, but it shows the problems:</div><div><br></div><div>===============FPC CODE BEGIN===============</div><div>type</div><div> generic ISomeInterface<T> = interface</div><div>  function Invoke(AValue: T): Boolean;</div><div> end;</div><div>  </div><div> // arghhhhhh... O____o generics types that are in half generic...</div><div> TList_Integer = specialize TList<Integer>;</div><div> TDictionary_TInteger_List_String = specialize TDictionary<TIntegerList, string>;</div><div> TArray_TList_Integer = specialize TArray<TListInteger>;</div><div> ISomeInterface_TArray_TList_Integer = specialize ISomeInterface<TArrayTListInteger>;</div><div> TEqualityComparer_TList_Integer = specialize TEqualityComparer<TList_Integer>;</div><div> TFunc_TArray_TList_Integer_RESULT_Boolean = specialize TFunc< TArray_TList_Integer, Boolean>; </div><div> TComparer_TList_Integer = specialize TComparer<TList_Integer>;   </div><div><br></div><div>var </div><div> d: TDictionary_TInteger_List_String;</div><div> e: TArray_TList_Integer;</div><div> c: ISomeInterface_TArray_TList_Integer;</div><div> l: TInteger_List;</div><div>begin</div><div> // you are killing future usage of closures</div><div> d := TDictionary_TInteger_List_String.Create(</div><div>   TEqualityComparer_TList_Integer.Construct(</div><div>    function(constref ALeft, ARight: TInteger_List): Boolean</div><div>    begin</div><div>     // ...</div><div>    end,</div><div>     </div><div>    function(constref AValue: TInteger_List): UInt32</div><div>    begin</div><div>     // ...</div><div>    end </div><div>   )</div><div>  );</div><div>   </div><div> // another example with closures</div><div> TFunc_TArray_TList_Integer_RESULT_Boolean(c) </div><div>  := function(AValue: TArray_TList_Integer): Boolean</div><div>    var</div><div>     LIndex: Integer;</div><div>    begin</div><div>     TArray.specialize BinarySearch<TList_Integer>(</div><div>      AValue, SomeList, LIndex, </div><div>      TComparer_TList_Integer.Construct(</div><div>       function(constref Left, Right: TList_Integer): Integer</div><div>       begin</div><div>        // ...</div><div>       end</div><div>      )</div><div>     )</div><div>    end; </div><div>  </div><div> c(l);  </div><div> e := d.Keys.ToArray();</div><div> // you are killing simple things   </div><div> TArray.specialize Sort<TList_Integer>(e, TComparer_TList_Integer.Construct(</div><div>   function(constref Left, Right: TList_Integer): Integer</div><div>   begin</div><div>    // ...</div><div>   end)</div><div>  );</div><div>=============== FPC CODE END ===============  </div><div><br></div><div><br></div><div>===============DELPHI CODE BEGIN===============</div><div>type</div><div> ISomeInterface<T> = interface</div><div>  function Invoke(AValue: T): Boolean;</div><div> end;</div><div><br></div><div>var</div><div> d: TDictionary<TList<Integer>, string>;</div><div> e: TArray<TList<Integer>>;</div><div> c: ISomeInterface<TArray<TList<Integer>>>;</div><div> l: TList<Integer>;</div><div>begin</div><div> d := TDictionary<TList<Integer>, string>.Create(</div><div>   TEqualityComparer<TList<Integer>>.Construct(</div><div>    function(const ALeft, ARight: TList<Integer>): Boolean</div><div>    begin</div><div><br></div><div>    end,</div><div><br></div><div>    function(const AValue: TList<Integer>): Integer</div><div>    begin</div><div><br></div><div>    end</div><div>   )</div><div>  );</div><div><br></div><div> TFunc<TArray<TList<Integer>>, Boolean>(c)</div><div>  := function(AValue: TArray<TList<Integer>>): Boolean</div><div>    var</div><div>     LIndex: Integer;</div><div>    begin</div><div>     TArray.BinarySearch<TList<Integer>>(</div><div>      AValue, l, LIndex,</div><div>      TComparer<TList<Integer>>.Construct(</div><div>       function(const Left, Right: TList<Integer>): Integer</div><div>       begin</div><div>        //...</div><div>       end</div><div>      )</div><div>     )</div><div>    end;</div><div><br></div><div> c(l);</div><div> e := d.Keys.ToArray();</div><div> TArray.Sort<TList<Integer>>(e, TComparer<TList<Integer>>.Construct(</div><div>   function(const Left, Right: TList<Integer>): Integer</div><div>   begin</div><div>    //...</div><div>   end)</div><div>  );</div><div>=============== DELPHI CODE END ===============</div></div><div><br></div><div> </div></div><div class="gmail_signature">Best regards,</div><div class="gmail_signature">Maciej Izak</div>
</div></div>