{"id":1207,"date":"2012-09-20T08:20:46","date_gmt":"2012-09-19T20:20:46","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=1207"},"modified":"2012-09-20T09:59:43","modified_gmt":"2012-09-19T21:59:43","slug":"adventures-in-syntax-something-old-something-new-etc","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/1207\/","title":{"rendered":"Adventures in Syntax: Something Old, Something New etc&#8230;"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">8<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>As the post title says, this will be a brief detour through some features of the Pascal language and a presentation of some (theoretical) alternatives that could have been introduced instead.  That is, some are real but little known syntax, others are what I think might be preferable to the syntax we actually have. <\/p>\n<p><!--more--><\/p>\n<p>So, as the old saying goes, let&#8217;s take them in order:  Something Old, Something New, Something Borrowed and Something Blue&#8230;<\/p>\n<h3>Something Old<\/h3>\n<p><strong><em>Parameterless Implementations for Methods With Parameters<\/em><\/strong><\/p>\n<p>Did you know that you can omit the parameters on your method implementations?<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\nunit Parameterless;\r\n\r\ninterface\r\n\r\n  type\r\n    TFoo = class\r\n      procedure Bar(const aParam: Integer);\r\n    end;\r\n\r\nimplementation\r\n\r\n  procedure TFoo.Bar;\r\n  var\r\n   i: Integer;  \r\n  begin\r\n    i := aParam;  \/\/ &lt;&lt; all good, the parameter declaration isn't needed\r\n  end;\r\n\r\nend.\r\n<\/pre>\n<p>I recently saw this described as a bug that was fixed only as recently as Delphi 2007.<\/p>\n<p>Well, it was never a bug and in fact it still compiles just fine even in XE2 and most likely XE3 (on the machine that I am writing this I don&#8217;t have XE3 so cannot verify).  I first came across this language feature in some Delphi 5 code, coincidentally while investigating an issue that <strong>did<\/strong> turn out to be a compiler bug (but entirely unrelated to this language feature).<\/p>\n<p>Ironically the mis-identification of this as a bug came paired with a complaint that the self-documenting interface\/implementation declarations in Pascal resulted in unnecessary duplication of declarations &#8211; something that this particular feature of Pascal is obviously designed to <em>reduce<\/em>.<\/p>\n<p>One problem that this very old feature of the Pascal language suffers from is that in more modern implementations of the language it is now possible to have multiple versions of the same method, each of course having different parameters.  i.e. <strong>overloads<\/strong>.  In that situation the compiler will of course have to insist that you have matching parameter declarations in your implementations, simply so it can match each implementation with the corresponding interface declaration.<\/p>\n<p>But otherwise, the re-declaration of the parameters in the implementation is optional, by design.  Whose design ?  Well, the original language.<\/p>\n<p>In effect &#8211; and in practice &#8211; the interface declaration is a <em>forward declaration<\/em> of the formal parameters for the methods in the class, and ANSI Pascal doesn&#8217;t require the formal parameters to be repeated when the forward declaration is completed by an actual implementation.<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  procedure FooBar(aParam: Integer); forward;\r\n\r\n  procedure FooBar;\r\n  var\r\n      i: Integer;\r\n  begin\r\n    i := aParam * 2;\r\n  end;\r\n<\/pre>\n<p>The <strong>Parameterless<\/strong> unit code (not the code above but the snippet before that) compiles just fine in Lazarus\/FPC with the following syntax settings for the compiler:<\/p>\n<ul>\n<li>Delphi<\/li>\n<li>Turbo Pascal<\/li>\n<li>Mac Pascal<\/li>\n<\/ul>\n<p>It is however rejected when compiling with the remaining syntax options:<\/p>\n<ul>\n<li>ObjectPascal<\/li>\n<li>FPC<\/li>\n<\/ul>\n<p>Note however that just because you can do something is never &#8211; on it&#8217;s own &#8211; a reason to do it.<\/p>\n<p>In this case, although this is something the language supports I cannot think of <em>any<\/em> <strong>good<\/strong> reason why you would omit the parameter declarations on the implementation.  Doing so makes reading the implementation a bit more hazardous (referencing symbols &#8211; i.e. parameters whose origin is not immediately clear).  Not to mention that introducing an overload at some later stage in the evolution of the code will necessitate the introduction of the missing parameters on any initial implementation that omits required parameters.<\/p>\n<p>It is a curiosity of (some implementations of) the language rather than a &#8220;feature&#8221;, imho.  \ud83d\ude42<\/p>\n<h3>Something New<\/h3>\n<p><strong><em><a href=\"http:\/\/theroadtodelphi.wordpress.com\/2012\/09\/05\/exploring-delphi-xe3-record-helpers-for-simple-types-system-sysutils-tstringhelper\" target=\"_blank\">New Delphi XE3 Language Feature: Record Helpers for Non-Records<\/a><\/em><\/strong><\/p>\n<p>We have had class and record helpers in Delphi for a while, and now you can declare a record helper for fundamental types too.  That is, types that are neither records nor classes.<\/p>\n<p>My coverage here will not focus on the syntax or feature itself &#8211; that is adequately <a href=\"http:\/\/theroadtodelphi.wordpress.com\/2012\/09\/05\/exploring-delphi-xe3-record-helpers-for-simple-types-system-sysutils-tstringhelper\/\" target=\"_blank\">covered by Rodrigo in his article<\/a> &#8211; but explore an alternative that could and should have been pursued instead.<\/p>\n<p>To me, whatever the benefits that might derive from this new capability, there are two problems: One practical and one aesthetic.  However, the solution to the aesthetic problem also leads to a solution to the practical problem, thus making the case that aesthetic problems can be indicative of more concrete problems that could\/should be addressed.  If it <strong>looks<\/strong> wrong then it might well <strong>be<\/strong> &#8220;wrong&#8221;. <\/p>\n<p>Or more simply put:  <strong>Form follows function<\/strong>.<\/p>\n<p>In this case we have a language feature (class helpers) originally introduced to meet a very narrow and specific need and which have significant constraints (and dangers) associated with them as a result.  So significant are <a href=\"https:\/\/www.deltics.co.nz\/blog\/?p=825\" target=\"_blank\">the constraints and dangers<\/a> that class helpers were always reserved (in the documentation) for that specific utilitarian purpose and developers specifically warned not to try to use them as a general purpose language feature.<\/p>\n<p>This didn&#8217;t stop people of course (some people <strong>do<\/strong> think that just because they can do something then they should).<\/p>\n<p>So the feature was extended to <strong>record<\/strong> helpers, without addressing <a href=\"https:\/\/www.deltics.co.nz\/blog\/?tag=class-helpers\" target=\"_blank\">the core constraints, problems and dangers<\/a>.<\/p>\n<p>And now we have them extended even <em>further<\/em>, with the same constraints and dangers and now &#8211; as if to confirm those underlying problems &#8211; a really, really nasty &#8220;code smell&#8221; is starting to become noticeable (if it wasn&#8217;t already &#8211; I don&#8217;t know about you, but I&#8217;ve been holding my nose since they debuted):<\/p>\n<p>That is, <em>a language feature with a contrived, inaccurate name and an awkward and misleading syntax<\/em> (which, as an aside, the syntax highlighting cannot be as helpful with because a new keyword was created which cannot be a reserved word due to it&#8217;s late entry into the syntax).<\/p>\n<p>Let us look at the declaration for a <strong>record helper<\/strong> for a string:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  type\r\n    TStringHelper = record helper for String  \/\/ &quot;helper&quot; is not reserved so is coloured as an identifier\r\n      :\r\n    end;\r\n<\/pre>\n<p>First of all, a <strong>String<\/strong> is <em>not<\/em> a record.  You might stretch a point and argue that the hidden RTTI fields of a string constitute a &#8220;record&#8221;, but the same semantic contortions cannot be applied to <strong>Integer<\/strong> or <strong>Boolean<\/strong> etc.<\/p>\n<p>The &#8220;record&#8221;ness doesn&#8217;t derive from the helper type itself either &#8211; if it did then &#8220;class helpers&#8221; would have been &#8220;record helpers&#8221; from the start.<\/p>\n<p>No, these are really just &#8220;type helpers&#8221; and since class and record types are also types, why were these not simply &#8220;type helpers&#8221; from the very start ?  This would cover <strong>all<\/strong> types &#8211; classes, records and fundamental.<\/p>\n<p>Furthermore, since when were types declared using a keyword that described their intended use (&#8216;helper&#8217;), rather than simply describing what they <strong>are<\/strong> and leaving the use to be reflected in the name given to the thing itself (rather than the type of the thing?)<\/p>\n<p>We don&#8217;t declare logical flags by declaring &#8220;flags&#8221;.  We declare boolean variables whose names indicate their use as a flag, or otherwise:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n   var\r\n     bIsUpdating: Boolean;\r\n   begin\r\n     bIsUpdating := (fUpdateCount &gt; 0);\r\n      :\r\n   end;\r\n<\/pre>\n<p>This decision to create a new keyword identifying a narrow usage for some syntactic element is especially puzzling when you consider that if you think about the language feature as what it <em>is<\/em> &#8211; rather than what it <em>does<\/em> &#8211; then you realise that everything needed to express that in a declaration was already in the reserved word list!<\/p>\n<p>Not only that, a very great deal of the character of a &#8220;helper&#8221; was already present in another, pre-existing language feature.<\/p>\n<p>Interfaces.<\/p>\n<h3>Set Time Machine for 2004&#8230; ENGAGE<\/h3>\n<p>So, let&#8217;s go back in time and see if we can&#8217;t design this language feature properly&#8230;<\/p>\n<p>Actually, it&#8217;s so easy and obvious that it beggars belief that we ended up with the mess that we have.<\/p>\n<p>Here is the alternative declaration that I suggest would have made better sense for a helper for <strong>any<\/strong> type, using the <strong>String<\/strong> helper as the example.  Notice that in this case, every word used is already an existing reserved word, except &#8211; obviously and intuitively &#8211; for the <em>identifiers<\/em> in the declaration:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  StringMethods = type interface for String\r\n    :\r\n  end;\r\n<\/pre>\n<p>First of all, the declaration states what the thing we are declaring <strong>is<\/strong>, not what it intended to be used for.<\/p>\n<p>A &#8220;type interface&#8221; describes perfectly what is occurring: we&#8217;re declaring a new [programming] interface for some type.<\/p>\n<p>Sure, it&#8217;s different from other interface or &#8220;distinct type&#8221; declarations, but at least it makes more sense than talking about &#8220;records&#8221; for things that aren&#8217;t remotely record-like.  And since this construct wasn&#8217;t previously legal or valid, we can define what ever we want it to mean now that it <strong>is<\/strong> legal and valid (just as a &#8220;class helper&#8221; required a new set of syntax rules).<\/p>\n<p>So on the one hand we get a new set of rules for something entirely new to the language, but which can be defined using existing language concepts and even keywords.<\/p>\n<p>Even better though is that the adoption of the &#8220;interface&#8221; concept for this feature automatically leads to a solution to the scoping problem that arises when you have multiple, potential interfaces for a particular type.<\/p>\n<p>This is the constraint that makes the existing class and record helper implementation so hopelessly broken (for general purpose use).<\/p>\n<p>The solution is &#8211; again &#8211; already present in the language, and follows naturally from the adoption of the &#8220;interface&#8221; concept for this feature.  It is the same solution that that already exists for <em>objects<\/em> that support multiple interfaces.<\/p>\n<p>In existing code when you have a reference to some object but you need access to that object via some supported interface, then you can ask for that using the &#8220;as&#8221; operator.    The exact same syntax could be supported where the interface being requested is a &#8220;type interface&#8221; rather than an <strong>IInterface<\/strong> (the compiler will know the difference and can emit the corresponding code accordingly):<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  (s as StringMethods).SomeMethodOfMyOwn;\r\n<\/pre>\n<p>This is better even than simply allowing &#8220;hard&#8221; type-casting.<\/p>\n<p>The <strong>as<\/strong> operator is not only consistent with the same use for COM-style interfaces, but it is also already &#8220;overloaded&#8221; as a type-checked casting operator (for class types) that is already present in the language.  All we are doing is adding a third overload &#8211; another use case &#8211; for the &#8220;as&#8221; operator.<\/p>\n<p>Instead of making a runtime call to a <strong>QueryInterface<\/strong> implementation or a runtime walk of the class hierarchy, this use case for <strong>as<\/strong> would be implemented by the <em>compiler<\/em> to ensure that the named <strong>type interface<\/strong> was available and in scope.<\/p>\n<p>There is no such similar use case for <strong>as<\/strong> in relation to &#8220;records&#8221; at all.<\/p>\n<p>I am reminded &#8211; yet again of the [Lost] Spirit of Delphi <a href=\"https:\/\/www.deltics.co.nz\/blog\/?p=484\" target=\"_blank\">I have written about in the past<\/a>, notably in relation to <a href=\"https:\/\/www.deltics.co.nz\/blog\/?p=847\" target=\"_blank\">more recent introductions to the language<\/a>.<\/p>\n<p>The ObjectPascal in Delphi used to be characterised by elegant and intuitive syntax.<\/p>\n<p>Many of the more recent language features in Delphi are &#8211; imho &#8211; clumsy and, frankly, very poorly thought out.<\/p>\n<h3>Something Borrowed<\/h3>\n<p><strong>Myth: <em>Oxygene<\/em> Cannot Compile a <em>Delphi<\/em> Class Without Significant Rewriting<\/strong><\/p>\n<p>This is not (in most cases) true.  While the <em>Oxygene<\/em> dialect of Pascal is significantly updated and overhauled in comparison with the Delphi dialect, it does however retain some language features purely and specifically for compatibility with <em>Delphi<\/em> declarations.<\/p>\n<p><strong>procedure<\/strong> and <strong>function<\/strong> for example <em>are<\/em> supported, but they are not <em>required<\/em> in Oxygene code.   Instead the single keyword <strong>method<\/strong> can be used, and whether a particular method is a procedure or a function is then determined by whether or not it is declared as having a return type or not.<\/p>\n<p>The fact that this is even possible makes it apparent that the distinction between procedures and functions is actually being made twice in any one declaration: the formal declaration of whether a return value was provided (function vs procedure) and then, in the case of a function, the corresponding <em>type<\/em> of that return value.<\/p>\n<p>When discussing this with a colleague recently I initially stated that this was an obvious redundancy that could be elegantly address by unifying the declaration in the way that <em>Oxygene<\/em> has done.  However, in the very next breath I retracted that view, as it then occurred to me the value that the <strong>procedure<\/strong>\/<strong>function<\/strong> disctinction has:<\/p>\n<p>When reading a class declaration, I can immediately and easily see that a method identified as a <strong>procedure<\/strong> has no return value that I might be concerned with.  Equally I can immediately and easily see that a <strong>function<\/strong> does have a return value that I might &#8211; and probably should &#8211; be very concerned with.  If <em>all<\/em> methods are declared simply as <strong>method<\/strong> then I have to read to the end of the declaration for each method to see whether there is any such return value.<\/p>\n<p>So on this occasion, given that I have the choice, I myself would prefer to stick to <strong>procedure<\/strong>\/<strong>function<\/strong> as a form of documentation.<\/p>\n<p>Your mileage may vary.  \ud83d\ude42<\/p>\n<h3>Something Blue<\/h3>\n<p>OK, I admit.  I couldn&#8217;t come up with something to fit this part of the saying, so at this point I&#8217;ll open the topic up to the floor.<\/p>\n<p>Feel free to nominate your favourite, or least favourite, syntactical gem in Pascal or a Pascal derived language in the comments.  \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">8<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> As the post title says, this will be a brief detour through some features of the Pascal language and a presentation of some (theoretical) alternatives that could have been introduced instead. That is, some are real but little known syntax, others are what I think might be preferable to the syntax we actually have.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4,179,180],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-jt","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1882,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1882\/","url_meta":{"origin":1207,"position":0},"title":"Not Your Grand-Daddy&#8217;s Pascal (or Java)","date":"15 Oct 2013","format":false,"excerpt":"I've mentioned some of the cool stuff in the Oxygene language in various posts and thought it would be a good idea to list them again, along with some others that I've not previously mentioned. Oxygene Everywhere First some of the core language features that are available on all supported\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":244,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/244\/","url_meta":{"origin":1207,"position":1},"title":"Generic Methods and Type Inferencing","date":"25 Aug 2008","format":false,"excerpt":"In the new Delphi forums recently, Barry Kelly responded to a question about lambda expression syntax in Tibur\u00f3n with this observation: This syntax needs type inference. Our compiler was not originally written to support type inference, but work to support type inference is orthogonal to supporting anonymous methods. ...\u00a0 you'll\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":700,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/700\/","url_meta":{"origin":1207,"position":2},"title":"The case for case[]","date":"30 Nov 2010","format":false,"excerpt":"Eric Grange (resurrector of the increasingly interesting looking DWS project) recently posted about a new idea he has had for the DWS engine, which in turn gave me an idea, or rather, prompted me to come up with what I think may be a new spin on an old one.\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1224,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1224\/","url_meta":{"origin":1207,"position":3},"title":"Sugary Goodness in &#8220;Nougat&#8221;","date":"13 Sep 2012","format":false,"excerpt":"Continuing the theme of recent - and upcoming - posts about new (and not so new) syntax in modern (and not so modern) variations on the Pascal language, I just have to comment on what I regard as yet another stunningly good job that the guys at RemObjects have done\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1624,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1624\/","url_meta":{"origin":1207,"position":4},"title":"Exploring Listeners With Oxygene","date":"16 Sep 2013","format":false,"excerpt":"Part 2 in a short series demonstrating the development of a simple camera app for Android using Oxygene. In the previous instalment we looked at the basic framework of our app. For this instalment I was going to show how to implement the camera preview or viewfinder for this instalment,\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2511,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2511\/","url_meta":{"origin":1207,"position":5},"title":"Anonymous Classes: Implementing Interfaces","date":"11 Feb 2017","format":false,"excerpt":"A few years ago (2011 to be precise) someone asked a question on StackOverflow about support for anonymous classes in Delphi. The reason for the question was that the poster was trying to use Delphi to develop for Android and on that platform the widespread use of callback interfaces makes\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1207"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=1207"}],"version-history":[{"count":16,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1207\/revisions"}],"predecessor-version":[{"id":1239,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1207\/revisions\/1239"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=1207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=1207"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=1207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}