{"id":412,"date":"2008-10-01T17:34:49","date_gmt":"2008-10-01T05:34:49","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=412"},"modified":"2008-10-01T17:34:49","modified_gmt":"2008-10-01T05:34:49","slug":"proposal-for-automated-variables","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/412\/","title":{"rendered":"Proposal for Automated Variables"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">4<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p><em><strong>Or: <\/strong>&#8220;Environmentally Friendly Coding &#8211; Recycle Your Keywords<\/em>&#8221;<\/p>\n<p>Yesterday I logged a Quality Central report proposing the addition of support for &#8220;automatic variables&#8221; to the Delphi language.\u00a0 Not only is it an <span style=\"text-decoration: underline;\">excellent<\/span> idea (in my humble and utterly objective opinion :)), but there is already a keyword in the language that could be co-opted for this purpose, a keyword that has been at something of a loose-end since it was deprecated (rendered obsolete even) a long, long time ago&#8230;<\/p>\n<p><!--more--><\/p>\n<p>The language keyword in question is <strong>automated<\/strong>.\u00a0 This was introduced in Delphi 2.0 as part of the initial implementation to support COM automation and, if memory serves, deprecated in the very next release when &#8220;proper&#8221; (albeit COM) interfaces were added to the language.<\/p>\n<p>The functionality that <strong>AutoFree()<\/strong> provides is similar to the concept of an <a href=\"http:\/\/en.wikipedia.org\/wiki\/Auto_ptr\" target=\"_blank\">auto pointer<\/a> &#8211; a specific variant of the general concept of a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Smart_pointer\" target=\"_blank\">smart pointer<\/a>.\u00a0 &#8220;auto&#8221;&#8230; &#8220;automatic&#8221;&#8230; &#8220;automated&#8221;&#8230; the similarity in the terms, and the relevance of the semantics, is striking.\u00a0 To me at least.<\/p>\n<p>The proposal in Quality Central drew inspiration directly from exchanges in the comments on my post on an <strong>AutoFree()<\/strong> implementation and a realisation that the required behaviour is very similar to that already implemented for interface references &#8211; it would not be entirely alien to the Delphi language.<\/p>\n<p>Indeed I believe it would be quite easily understood and welcomed by most, if not all, developers.<\/p>\n<h2>The Proposal<\/h2>\n<p>The <strong>automated<\/strong> keyword should be supported as a decoration on variable declarations.\u00a0 That is local variables, member variables and unit variables:<\/p>\n<pre class=\"delphi\">interface\r\n\r\n  type\r\n    TFoo = class\r\n    private\r\n      fBar: TBar automated;\r\n    end;\r\n\r\nimplementation\r\n\r\n  var\r\n    _Bar: TBar automated;\r\n\r\n  function FooFn;\r\n  var\r\n    bar: TBar automated;\r\n  begin\r\n    :\r\n  end;<\/pre>\n<p>The rules for the keyword and the effect of it shall be as follows:<\/p>\n<p style=\"padding-left: 30px;\">&#8211; The <strong>automated<\/strong> keyword shall be valid only for pointer and object reference type variables. <strong>(*)<\/strong><\/p>\n<p style=\"padding-left: 30px;\">&#8211; When marked as <strong>automated<\/strong> the compiler shall emit code to initialize a variable to <strong>NIL<\/strong>. <em>This already occurs for local variables of certain types, most notably interface references, as well as all member variables <\/em><em>(albeit indirectly in that case)<\/em><em>, and currently has to be specified directly, if required, for unit variables.<\/em><\/p>\n<p style=\"padding-left: 30px;\">&#8211; When marked as <strong>automated<\/strong> the compiler shall emit code to finalize a variable in a manner appropriate to it&#8217;s type.\u00a0 For object references this shall be a call to <strong>Free<\/strong>; for pointers a call to <strong>FreeMem()<\/strong>.\u00a0 <em>This is directly equivalent to the code already emitted by the compiler to finalize interface references by calling <strong>Release()<\/strong>.<\/em><\/p>\n<p style=\"padding-left: 30px;\">&#8211; <strong>automated<\/strong> would <span style=\"text-decoration: underline;\">not<\/span> be combinable with <strong>absolute<\/strong>.<\/p>\n<p><em><strong>(*)<\/strong> &#8211; it could also be supported on record types with the proviso that the record type in question supports a parameterless <strong>constructor<\/strong> (to be called to initialize the record) and a lone <strong>destructor<\/strong> (called to finalize the record).\u00a0 But to keep things simple lets stick to object references and pointers, for now at least.<br \/>\n<\/em><\/p>\n<p>The effect on code of the use of this keyword would be to facilitate:<\/p>\n<p style=\"padding-left: 30px;\">1. resource protection for temporary objects held in local variables without the need for <strong>try..finally<\/strong> blocks.<\/p>\n<p style=\"padding-left: 30px;\">2. reliable clean up of dependent objects in object hierarchies without the need for objects to implement a <strong>destructor<\/strong> (solely) to free those dependent objects.\u00a0 Destructors may still be necessary for other purposes of course.<\/p>\n<p style=\"padding-left: 30px;\">3. reliable clean up of unit (a.k.a &#8220;global&#8221;) objects without the need for a unit <strong>finalization<\/strong>.\u00a0 Again, finalization may still be required for other purposes.<\/p>\n<p>Note however that it would not prevent these existing techniques from functioning, if required or preferred.<\/p>\n<p>There is only one possible danger that I foresee, which is that a developer might mark a variable as automated but then dispose of the referenced object\/memory explicitly without re-initializing the variable.\u00a0 e.g.:<\/p>\n<pre class=\"delphi\">  procedure SomeFn;\r\n  var\r\n    bar: TBar automated;\r\n  begin\r\n    bar := TBar.Create;\r\n    bar.Free;\r\n  end;<\/pre>\n<p>In this case, when <strong>SomeFn<\/strong> exits, the finalization of <strong>bar<\/strong> will likely result in an error since <strong>bar<\/strong> has been left holding a reference to an object that has already been <strong>Free<\/strong>&#8216;d.<\/p>\n<p>Note that the initialization of <strong>bar<\/strong> as NIL (as a consequence of being <strong>automated<\/strong>) specifically avoids any problem if bar is only assigned a reference conditionally in the code.<\/p>\n<p>Note also that explicitly disposing an automated variable is not in and of itself problematic, as long as the variable is also then explicitly re-set to <strong>NIL<\/strong>.\u00a0 In the above example, if bar had been <strong>NIL<\/strong>&#8216;d once freed, or <strong>FreeAndNIL()<\/strong> had been used, then there would not be any problem with the automated behaviour of <strong>bar<\/strong>.<\/p>\n<p>The code below illustrates safe explicit disposal and potentially conditional assignment of an automated reference:<\/p>\n<pre class=\"delphi\">  procedure SomeFn;\r\n  var\r\n    bar: TBar automated;\r\n  begin\r\n    bar := TBar.Create;\r\n\r\n    \/\/ do some work with \"bar\"\r\n\r\n    FreeAndNIL(bar);\r\n\r\n    if SomeCondition then\r\n    begin\r\n      bar := TBar.Create;\r\n      \/\/ do more work with a new \"bar\"\r\n    end;\r\n  end;<\/pre>\n<p>This code is perfectly safe, will not result in a runtime error and will not leak a <strong>TBar<\/strong>.<\/p>\n<p>The potential dangers and pitfalls of an automated variable behaviour implemented as described are actually no different to the potential dangers and pitfalls associated with the manual techniques that it could replace.<\/p>\n<p>I should also mention that I cannot see that the proposal described here would necessarily interfere with, or be interfered with by, the existing, deprecated usage of the <strong>automated<\/strong> keyword.<\/p>\n<p>A final observation is that this implementation &#8220;feels very Pascal&#8217;ly&#8221; to me.\u00a0 In a <span style=\"text-decoration: underline;\">good<\/span> way.<\/p>\n<h2>Call To Action<\/h2>\n<p>The <a href=\"http:\/\/qc.codegear.com\/wc\/qcmain.aspx?d=67324\" target=\"_blank\">Quality Central report # is 67324<\/a>.<\/p>\n<p>If you feel the idea has merit please vote for it.<\/p>\n<p>If you feel it needs refining, comment on it (in QC, rather than here).<\/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\">4<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Or: &#8220;Environmentally Friendly Coding &#8211; Recycle Your Keywords&#8221; Yesterday I logged a Quality Central report proposing the addition of support for &#8220;automatic variables&#8221; to the Delphi language.\u00a0 Not only is it an excellent idea (in my humble and utterly objective opinion :)), but there is already a keyword in the language that could be co-opted [&hellip;]<\/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],"tags":[292,68],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-6E","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":586,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/586\/","url_meta":{"origin":412,"position":0},"title":"Absolute (for) Beginners","date":"15 Oct 2009","format":false,"excerpt":"I casually suggested the use of the \"absolute\" keyword in response to a question on the NZ DUG mailing list today. \u00a0I thought nothing of it but someone mentioned that it had been years since he'd seen anyone use it, so I thought maybe it was worth bringing to wider\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1207,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1207\/","url_meta":{"origin":412,"position":1},"title":"Adventures in Syntax: Something Old, Something New etc&#8230;","date":"20 Sep 2012","format":false,"excerpt":"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\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":412,"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":338,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/338\/","url_meta":{"origin":412,"position":3},"title":"Delphi 2009 &#8211; A Heads-Up for Low-Level Coders","date":"13 Sep 2008","format":false,"excerpt":"Prompted by a conversation with some colleagues where-in we collectively speculated about the implementation details of a generic class and what impact - if any - this might have on performance vs a \"traditional\" polymorphic equivalent, I threw together a quick performance test case in my Smoketest framework, and as\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2337,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2337\/","url_meta":{"origin":412,"position":4},"title":"A Silent Danger&#8230;","date":"07 Jun 2015","format":false,"excerpt":"A brief post on a long standing omission in type checking in Pascal and the limitations of Range Checking as applied to the problem. Consider this contrived example of a simple function: This very simple function accepts an explicitly 32-bit Integer parameter and simply returns TRUE if the value passed\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1300,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1300\/","url_meta":{"origin":412,"position":5},"title":"What&#8217;s in a Name(space) ?","date":"28 Nov 2012","format":false,"excerpt":"The ever evolving DWScript project continues to advance the Pascal language at an impressive pace. Just today it was announced that this scripting version of Pascal now has \"namespace\" support. When I first read the details of the implementation, my initial reaction was that it \"felt a bit backwards\". The\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/412"}],"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=412"}],"version-history":[{"count":5,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/412\/revisions"}],"predecessor-version":[{"id":417,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/412\/revisions\/417"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=412"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=412"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=412"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}