{"id":700,"date":"2010-11-30T19:38:01","date_gmt":"2010-11-30T07:38:01","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=700"},"modified":"2010-11-30T20:26:00","modified_gmt":"2010-11-30T08:26:00","slug":"the-case-for-case","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/700\/","title":{"rendered":"The case for case[]"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>Eric Grange (resurrector of the increasingly interesting looking DWS project) recently posted about <a href=\"http:\/\/delphitools.info\/2010\/11\/29\/iif-anonymous-expression-parameters\/\">a new idea he has had for the DWS engine<\/a>, 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.<br \/>\n<!--more--><br \/>\nI briefly posted my idea to the comments on his post, and for more details of his suggestion please visit his pages.  Here I shall spend more time outlining my idea, inspired by, but not necessarily directly connected to his.<\/p>\n<p>The old problem at the heart of the idea, is the lack of &#8220;iif()&#8221; or so called &#8220;ternary operator&#8221; in Delphi.<\/p>\n<p>We do have <strong>IfThen()<\/strong> in limited forms in various places in the RTL:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n   s := IfThen(SomeCondition, stringA, stringB);\r\n<\/pre>\n<p>Which provides a neat (i.e. condensed) alternative to:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  if SomeCondition then\r\n    s := stringA\r\n  else\r\n    s := stringB;\r\n<\/pre>\n<p>Except it doesn&#8217;t quite do that, as anyone who has encountered this function will testify.<\/p>\n<p>Problems from the fact that <strong>IfThen()<\/strong> is just a function, like every other function in Delphi, and to pass expressions as parameters to that function, those parameter expression must be first evaluated.  A simple way to demonstrate the problem is to (try to) use <strong>IfThen()<\/strong> to retrieve a property of an object or yield a default if the object is not assigned:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n   s := IfThen(Assigned(obj), obj.Name, '(no object assigned)');\r\n<\/pre>\n<p>Because the parameters to the <strong>IfThen()<\/strong> function must be evaluated before <strong>IfThen()<\/strong> can itself be called, the <strong>obj.Name<\/strong> reference will cause an access violation if <strong>obj<\/strong> is not assigned, precisely what we were trying to avoid!<\/p>\n<p><a href=\"http:\/\/delphitools.info\/2010\/11\/29\/iif-anonymous-expression-parameters\/\">Eric&#8217;s idea was to support a way of declaring parameters<\/a> that indicate that if those parameters represent an expression, that the expression itself in effect be passed and only evaluated within the function if required.<\/p>\n<p>I can see how this is easily possible in a scripting engine such as DWS, and I can even see how it might be achieved with anonymous methods in Delphi, except that I really wouldn&#8217;t want to see that any more than I would be happy to see a generalised <strong>IfThen()<\/strong> contrived using generics, which would look something like:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n   TTernary&lt;T&gt; = class\r\n      class function IfThen(aCondition: Boolean; aTrueResult, aFalseResult: T): T;\r\n   end;\r\n\r\n   \/\/ In usage:\r\n   s := TTernary&lt;String&gt;.IfThen( condition, stringA, stringB );\r\n<\/pre>\n<p>Some might call me &#8220;old fashioned&#8221; for not welcoming such new syntax.<\/p>\n<p>I don&#8217;t think it has anything to do with being &#8220;old fashioned&#8221;, unless it is old fashioned to find such syntax ugly, cumbersome and just plain hard to read (not hard to understand, but physically hard read &#8211; it being full of syntax and punctuation, far more than should be required).<\/p>\n<p>Not to mention the flat out ridiculous need to place the function in an extraneous class, just to gain access to generics support.<\/p>\n<p>But I digress.<\/p>\n<p>My idea came from thinking about what the code that the operator itself represents (and possibly even generates).  To recap:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n   s := IfThen(SomeCondition, stringA, stringB);\r\n<\/pre>\n<p>Is equivalent to:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  if SomeCondition then\r\n    s := stringA\r\n  else\r\n    s := stringB;\r\n<\/pre>\n<p>Which in turn is equivalent to:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  case SomeCondition of\r\n    TRUE  : s := stringA\r\n    FALSE : s := stringB;\r\n  end;\r\n<\/pre>\n<p>Now it seems quite clear and obvious to me that this form of the code quickly identifies how much of the code is not just boilerplate, but merely syntactic scaffolding, and could be replaced by&#8230; (drum roll please&#8230;)<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  s := case[SomeCondition, stringA, stringB];\r\n<\/pre>\n<p>Or some variation on this.  I suggest re-using the keyword &#8220;case&#8221; &#8211; perfectly valid since it is being used in exactly the same way as it&#8217;s current use, merely employing a slightly different syntax.<\/p>\n<p>Similarly, using <strong>[]<\/strong> (rather than <strong>()<\/strong>) ensures that the new syntax itself is not confusable with that syntax for case that is already supported and also differentiates this syntax from a function call which it might otherwise appear to resemble.<\/p>\n<p>TA-DA!<\/p>\n<p>I don&#8217;t know about you, but I would love to see this added to the language, and when I get my hands on DWS (and some time) I hope to explore adding it to at least that scripting version of Pascal.<\/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\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> 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.<\/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":[125,292,13,127,126],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-bi","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":2624,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2624\/","url_meta":{"origin":700,"position":0},"title":"Expressive If and Case &#8230;","date":"25 Apr 2017","format":false,"excerpt":"A quick post on a small but hugely useful little language feature in Oxygene... if expressions. Many people will be familiar with the so-called ternary operator. Delphi developers will also be aware that there is no direct equivalent in Delphi. In 'C' and other languages we can write a statement\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2223,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2223\/","url_meta":{"origin":700,"position":1},"title":"When You Say Nothing At All&#8230;","date":"10 Mar 2014","format":false,"excerpt":"This is another one of those posts that has a bit of a double meaning in the same title. First, there is the matter of a useful hint\/warning that I think could be emitted by a Pascal compiler. The other is what I have been up to in recent months\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1930,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1930\/","url_meta":{"origin":700,"position":2},"title":"VCL Threading &#8211; Indeterminate Lifetimes","date":"18 Oct 2013","format":false,"excerpt":"Sometimes when you launch a thread you don't know when it will complete whatever processing it is tasked with. Sometimes you do. Sometimes it may never complete and will require that you expressly terminate it. Usually any given thread will have a lifecycle that is at least consistently one or\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":391,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/391\/","url_meta":{"origin":700,"position":3},"title":"Free Yourself","date":"27 Sep 2008","format":false,"excerpt":"Barry Kelly recently posted an example of \"smart\" pointers (specifically the auto-pointer variant of a smart pointer) using generics in Delphi 2009.\u00a0 It was an interesting use of generics but the end result was something that has - in part at least - been possible for some time in Delphi\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":412,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/412\/","url_meta":{"origin":700,"position":4},"title":"Proposal for Automated Variables","date":"01 Oct 2008","format":false,"excerpt":"Or: \"Environmentally Friendly Coding - Recycle Your Keywords\" Yesterday I logged a Quality Central report proposing the addition of support for \"automatic variables\" 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\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":719,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/719\/","url_meta":{"origin":700,"position":5},"title":"Google+ Feature Suggestion: Rings\/Spheres\/Super-Circles","date":"14 Jul 2011","format":false,"excerpt":"A tenuous link to Delphi I accept, but a Google+ suggestion occurred to me, arising from my Delphi-oriented use of it. A potential problem I am seeing already on Google+ is where I get a notification that \"So-And-So\" has added me to their circles. In some cases I don't know\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\/700"}],"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=700"}],"version-history":[{"count":5,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/700\/revisions"}],"predecessor-version":[{"id":705,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/700\/revisions\/705"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=700"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=700"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=700"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}