<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">Moved from: "Initialize/Finalize management operators and Default intrinsic". I'd like to keep Initialize/Finalize topic more clear ;P</div><div class="gmail_quote"><br></div><div class="gmail_quote">Small introduction:</div><div class="gmail_quote"><br></div><div class="gmail_quote"><div class="gmail_quote" style="font-size:12.8px"><div>for selected language elements in Delphi is possible to use attributes. For example in Delphi we have:</div><div><br></div><div> TCustomAttribute = class(TObject)</div><div> end;</div><div> WeakAttribute = class(TCustomAttribute);</div><div> UnsafeAttribute = class(TCustomAttribute);</div><div> RefAttribute = class(TCustomAttribute);</div><div> VolatileAttribute = class(TCustomAttribute); </div><div><br></div><div>which is used like this:</div><div><br></div><div>procedure Foo([ref] const X: TFoo); // AFAIK FPC equivalent is procedure Foo(constref X: TFoo); </div><div><br></div><div>or like this for TObject field for ref. count for ARC:</div><div><br></div></div><span style="font-size:12.8px">[Volatile] FRefCount: Integer;</span><br></div><div class="gmail_quote"><span style="font-size:12.8px"><br></span></div><div class="gmail_quote">Michael Van Canneyt really doesn't like them :) :<span style="font-size:12.8px"><br></span></div><div class="gmail_quote"><br></div><div class="gmail_quote"><div class="gmail_quote">2016-04-12 15:37 GMT+02:00 Michael Van Canneyt <span dir="ltr"><<a href="mailto:michael@freepascal.org" target="_blank">michael@freepascal.org</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=""><br><br>On Tue, 12 Apr 2016, Maciej Izak wrote:<br><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">2016-04-12 14:48 GMT+02:00 Michael Van Canneyt <<a href="mailto:michael@freepascal.org" target="_blank">michael@freepascal.org</a>>:<br><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">I really don't think you should delegate such things to attributes. You<br>make 2 completely unrelated language constructs suddenly related. A bad<br>design decision.<br></blockquote><br><br>I think you are wrong. Attributes are not only dedicated to RTTI just look<br>at other languages: Delphi, C#, Java. Instead of extending language into<br>infinity you can use simple attribute with parameter. I don't see any<br>reason why don't use attributes to describe some compiler/RTL behavior? Any<br>attribute can be easier placed in many language structures without breaking<br>language syntax. That is much harder with new keywords.<br><br>Maybe that is not ideal but works excellent.<br></blockquote><br></span>Nono.<br><br>You deviate from an important design principle: orthogonality.<br><br>By linking 2 concepts, any change in 1 concept risks to influence the other.<br>This is ALWAYS bad. If you implement things orthogonally, a change in 1<br>concept does not risk influencing the other.<br><br>So you will really, really have to provide better arguments than 'but works excellent'.</blockquote><div> <br></div></div></div><div class="gmail_quote"><div>To clarify: I am not a big fan of the attributes syntax. But...<br><br></div><div><div>If attribute is used you already know that it has more "flag idea" (by analogy to RTTI attributes, anyway it does not have to be just like a flag), as in our example presented in "Initialize/Finalize management operators and Default intrinsic" topic - is more visible whole context. Introducing many new keyword is the waste and can collide with existing keywords. </div><div><br></div><div></div><div>I don't want the language with thousands of keywords, some things can be delegated to attributes. *That helps to keep main language more clear*.</div><div><br></div><div>Usage of attributes is more readable than mix of many keywords (it depends of context ofc). I think in many areas it is matter of taste. Of course is possible to implement new keywords, but <br>*the main idea of using attributes for syntax elements is to omit explosion of new keywords*... Just imagine this as attributes for nodes of compiler. Pure theory:<br><br></div><div> // open mp - attributes way<br> [OmpParallel]<br> begin<br> [OmpFor]<br> for i := 1 to 10 do<br> WriteLn(i);<br> end;<br><br></div><div> // new keywords way ? set of keywords?...<br></div><div> ompparallelbegin<br></div><div> ompfor i := 1 to 10 do <br></div><div> WriteLn(i);<br></div><div> end;<br></div><div> // or...<br><div> omp parallel begin<br></div><div> omp for i := 1 to 10 do<br></div><div> WriteLn(i);<br></div> end;<br></div><div><br></div><div>// another example<br>//Throws - like java throws - used to force the caller of the method to catch exceptions<br>// JSExport - some special export for JavaScript without deeper sense for non-existing FPC JS target ;)<br><br></div><div>[Throws(EConvertError, EClassNotFound, ECrtSocket)] <br></div><div>[JSExport('Foo')] <br></div><div>class procedure procedure Foo(); stdcall; overloaded; static;<br></div><div><br></div><div>// new keywords ...<br></div><div>class procedure procedure Foo(); stdcall; overloaded; static; throws EConvertError, EClassNotFound, ECrtSocket; {$IFDEF JS}jsexport 'foo';{$ENDIF}<br><br>The line between attribute and keyword is thin. Attribute is always declared "before". You don't need to redesign language to put something new (sometimes it is even impossible or very complicated, so attribute is the only way).</div></div><div><br></div><div>FINAL NOTE: attributes for a language should be introduced with great carefulness.</div><div><br></div><div>FINAL COMPROMISE: is good to allow selected attributes for Delphi compatibility (in Delphi mode only) for example to allow usage of [ref]. I'd like to run my Generics.Collections in Delphi too :). No big deal:</div><div><br></div><div><span style="font-size:12.8px">procedure Foo([ref] const X: TFoo);</span><br></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">can be interpreted just like:</span></div><div><span style="font-size:12.8px"><br></span></div><div><div><span style="font-size:12.8px">procedure Foo(constref X: TFoo);</span><br></div></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">or in the future:</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">[Volatile] FRefCount: Integer;</span><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">can be interpreted like:</span><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">FRefCount: Integer; v</span><span style="font-size:12.8px">olatile;</span><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px"><br></span></div></div>-- <br><div><div dir="ltr"><div>Best regards,<br>Maciej Izak</div></div></div>
</div></div>