<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TURBU Tech</title>
	<atom:link href="http://tech.turbu-rpg.com/feed" rel="self" type="application/rss+xml" />
	<link>http://tech.turbu-rpg.com</link>
	<description>Mason Wheeler&#039;s thoughts on Delphi programming in general, and particularly on the technical aspects of developing the TURBU engine and editor.</description>
	<lastBuildDate>Sun, 19 May 2013 01:41:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>How to simplify memory management the right way</title>
		<link>http://tech.turbu-rpg.com/505/how-to-simplify-memory-management-the-right-way</link>
		<comments>http://tech.turbu-rpg.com/505/how-to-simplify-memory-management-the-right-way#comments</comments>
		<pubDate>Sun, 19 May 2013 01:40:32 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Memory Management]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=505</guid>
		<description><![CDATA[As I pointed out yesterday, with FastMM available, memory management is so much of a solved problem that it&#8217;s a non-problem.  So dropping a performance-killing pseudo-GC &#8220;solution&#8221; on us is patronizing and insulting in the extreme, not to mention a massive waste of effort that could have been spent actually improving the language and/or standard [...]]]></description>
				<content:encoded><![CDATA[<p>As I pointed out yesterday, with FastMM available, memory management is so much of a solved problem that it&#8217;s a non-problem.  So dropping a performance-killing pseudo-GC &#8220;solution&#8221; on us is patronizing and insulting in the extreme, not to mention a massive waste of effort that could have been spent actually improving the language and/or standard libraries.  But I did notice one very interesting thing from its implementation: the introduction of the [Weak] attribute, and a few other related attributes, are something fundamentally new in the Delphi language.<span id="more-505"></span></p>
<p>Attributes were introduced to Delphi as part of the extended RTTI package in D2010.  They&#8217;re essentially little tags you can put on a class (or various other places) that provide metadata about it, which can be retrieved via the RTTI system.  But [Weak] is something more: it&#8217;s an attribute that has a specific meaning <em>to the compiler itself</em>.  It&#8217;s not just a metadata attribute, but a <em>semantic</em> attribute.  And that concept of semantic attributes, if employed in a slightly different way, could be used to make Delphi code a lot prettier without having to slow everything down, break tons of existing code, and tick off the vast majority of Delphi developers who <strong>do not want garbage collection in the language<em>.</em></strong></p>
<p>Consider the following code:</p>
<pre>procedure myProc;
var
   myObj: TMyObject;
begin
   myObj := TMyObject.Create;
   try
      myObj.DoWhatever;
   finally
      myObj.free;
   end;
end;</pre>
<p>You&#8217;re probably familiar with this pattern.  You&#8217;ve probably written code like this a million times.  It&#8217;s The Right Way to write it: you clean up after yourself once you&#8217;re done.</p>
<p>It&#8217;s also kind of bulky.  The body of the procedure is six lines long. One for setup, one for doing what we actually care about, and <strong>four</strong> for cleanup.  The ARC version would be a lot shorter:</p>
<pre>procedure myProc;
var
   myObj: TMyObject;
begin
   myObj := TMyObject.Create;
   myObj.DoWhatever;
end;</pre>
<p>But while that may look like less code, there&#8217;s actually a lot more going on.  That <strong>try</strong> block is still there; it&#8217;s just been added implicitly by the compiler.  And instead of calling Free directly, there&#8217;s a ref count release call (which slows down everything because it has to use an atomic decrement) before the destructor.  And the stupid part is, <em>none of it is necessary.</em>  Even the most trivial static analysis could show that this reference to myObj is never going to be passed to anything else, so there&#8217;s no need to keep a count of it, at all.  A smart compiler should be able to automatically insert a direct call to Free without having to keep a reference count here.</p>
<p>The problem is, the only static analysis that can really do any good is &#8220;the most trivial static analysis,&#8221; which can only be useful in the most trivial of cases.  For example, if the TMyObject constructor passed Self to some routine somewhere, it may or may not have held a reference to it in an object, and then all bets are off.  Have you heard of the Halting Problem, how it&#8217;s impossible to come up with a general-case analysis routine that will determine if a given program will halt or not?  Well, it gets worse.  There&#8217;s <a href="https://67a8df06-a-97b1dc77-s-sites.googlegroups.com/a/jeffreykegler.com/domain-start/Home/perl-and-undecidability/perl-and-undecidability-files/TPR2.pdf?attachauth=ANoY7cp1eulkEkAx495m4RoZ-c2uw5X9Y9k_ajgwnae-DeT8r-s1N2UetXF0n82SzvCOrghaO7PlI7lB7wywggjJTkhJnIz5yAuCzHzYHgXlFC1WphhjsUNsUto5W7BCnuVg2zurfSVQZsYO_tFJbsJirKo4Ihr5MP-GbJ-S9u4As5H5gSZjXWoDHZ61CBCpCl4TxokwLZ3E7eGCz6hABPpuidJOYPjwDf-29ocHSPkWnhVOlSmXbA84hA_kjx1R4Il7ZlJs_n0uR36c5-Z5QRscUG0SJTzP9LnOBLGh3MI1P45QRDr9Pg8%3D&amp;attredirects=1">this thing called Rice&#8217;s theorem</a> which states that it is impossible to come up with any general-purpose analysis routine that can answer <em>any useful, non-trivial question about computer programs.</em>  Which means that there&#8217;s no way to write a static analyzer that can detect which variables can be freed safely in a situation like this.</p>
<p>Rice&#8217;s theorem says that it&#8217;s impossible to create a smart compiler that can take care of something like that, for the same basic reasons that it&#8217;s impossible to solve the Halting Problem.  Simply put, you can&#8217;t automate &#8220;smart,&#8221; which is why attempts to do so invariably end up with stupid solutions that require dumbing things way down.  (See: every implementation of garbage collection ever devised, including ARC.)</p>
<p>This is where semantic attributes come in.  With a bit of compiler support, it would be simple to accomplish the same thing, like this:</p>
<pre>procedure myProc;
var
   [Local] myObj: TMyObject;
begin
   myObj := TMyObject.Create;
   myObj.DoWhatever;
end;</pre>
<p>The semantics here should be intuitively obvious.  A [Local] attribute would declare to the compiler that this variable is scoped to the current declaration.  Instead of trying to automate &#8220;smart&#8221;, which is impossible, we keep the smart decisions where they belong&#8211;with the intelligent person behind the keyboard&#8211;and instead get the compiler to automate something computers are very good at automating: mindless drudgery.  The [Local] attribute would transform the procedure above into this:</p>
<pre>procedure myProc;
var
   myObj: TMyObject;
begin
   myObj := nil;
   try
      myObj := TMyObject.Create;
      myObj.DoWhatever;
   finally
      myObj.free;
   end;
end;</pre>
<p>(If static analysis could prove that myObj can never be accessed before it gets assigned (as is the case here) it could even optimize out the initialization.)</p>
<p>There would be two other use cases for the [Local] attribute.  Putting it inside a field list for a class or record would mean that when the class or record gets cleaned up, the object in question should be destroyed.  (And I&#8217;ve got more to say about object and record cleanup a bit later on.  There&#8217;s something that could be done to improve those greatly)  And for functions, it would be a little bit different.</p>
<p>You&#8217;ve used factory functions before, right?  You call a function that produces a new object, instead of using an existing one that you pass in.  Well, [Local] would be useful for them, for safety:</p>
<pre>function MyFactory(value, value2: integer): [Local] TMyObject;
begin
   result := FactoryRegistryClass[integer].Create;
   result.Foo(value2);
end;</pre>
<p>The problem with a function like this is, what happens if the call to Foo can raise an exception?  You don&#8217;t want a try/finally block here, because if everything goes right you&#8217;re supposed to return the value, but you do have to wrap it in a &#8220;try/except free; raise; end;&#8221; block to get it right.  Marking the result as [Local] would have the compiler take care of that for you.</p>
<p>Tagging something that&#8217;s not an object or a typed pointer with [Local] should result in a compiler warning.</p>
<p>This scheme would result in much cleaner code, it would keep the responsibility for making the smart decisions where it belongs&#8211;with the programmer, not the language designer&#8211;it doesn&#8217;t introduce any overhead beyond that which exists for correct code, and it doesn&#8217;t break any already-existing code.  Unlike ARC, where there&#8217;s really no upside, with this system there&#8217;s no downside.</p>
<p>&#8230;except for one thing.  Moving object fields to an object&#8217;s or record&#8217;s automatic destruction list would mean moving them to FinalizeRecord, and for the life of me, I cannot understand why FinalizeRecord exists at all.</p>
<p>For those of you who&#8217;ve never ended up in there while debugging with Use Debug DCUs turned on, or who just plain don&#8217;t know what it is, FinalizeRecord (and its partner in crime, FinalizeArray) is a routine that uses RTTI to automatically clean up managed managed-type variables (strings, interfaces, variants) that are owned by something else.  When you destroy an object that contains a string, you don&#8217;t have to clean up the string in the destructor, because FinalizeRecord takes care of it for you.  The compiler creates a table that says where all of the managed references are and what types they are, and FinalizeRecord and FinalizeArray go over this table, and for each item in it they look up the correct cleanup routine and call it with a pointer to the right location in memory.  It&#8217;s been around since the beginning of Delphi, and it&#8217;s been a big mistake since the beginning.  It&#8217;s absolutely the wrong way to clean up this sort of situation.</p>
<p>I can sort of imagine how it came about.  They&#8217;d just invented the Delphi RTTI system to take care of form streaming, which was quite the impressive accomplishment, and remains one today.  (Remember that Java came out at the same time as Delphi, and <em>still</em> doesn&#8217;t have a decent form designer!)  And someone on another part of the team said, &#8220;well, look at this.  We&#8217;ve got managed types, that the compiler cleans up when they go out of scope without the programmer needing to write any code for it, and that works fine inside of procedures&#8230; but how are we going to handle it for objects that contain managed types as fields?&#8221;</p>
<p>And then someone, tragically, said &#8220;well, look at this cool RTTI thing we invented!  We can write up one cleanup routine that inspects the object&#8217;s structure and cleans up managed types that way.&#8221;  And so that&#8217;s what they did.</p>
<p>The only problem with that theory is that it requires the original Delphi team to have been smart enough to create Delphi, and yet stupid enough to make a mistake like this.  It requires that Anders Hejlsberg, who created Delphi, who famously stated &#8220;static when possible, dynamic when necessary,&#8221; to have <em>gotten his own principle completely wrong</em> in this case.  (But, since FinalizeRecord has been in Delphi since the beginning, any explanation of why it happened must necessarily involve this in some way.  It really does baffle me.)</p>
<p>The thing is, RTTI is <strong>Run-Time</strong> type information.  It&#8217;s for looking things up that <em>are not and cannot be</em> known at compile time, such as (de)serializing a form file.  But this is not such a situation.  Remember that the compiler has to build the finalization table in the first place.  This means that it already knows exactly what has to be finalized, and seeing as how Delphi is not a dynamically-typed language, that knowledge it has isn&#8217;t going to become invalid at any point after compilation.  So why doesn&#8217;t it simply do what compilers do best, and <em>generate code</em> to do the finalization?</p>
<p>Even though they&#8217;re written in hand-optimized assembly, FinalizeRecord and FinalizeArray are painfully slow.  They&#8217;ll frequently turn up in profiling reports if you&#8217;re working with code that churns through a lot of objects or records.  And adding objects to them will just make things slower.  (Which the ARC system has done, BTW.  It just keeps inflicting layer upon layer of extra slowness upon us!)  What I&#8217;d like to see is those routines deleted from System.pas, and the VMT slot that points to the finalization table replaced with a pointer to an automatically-generated cleanup routine.  No more unnecessary RTTI to take care of a task that could easily be covered under &#8220;static when possible&#8221;.</p>
<p>And before anyone objects, saying that debugging would suffer under all of the new auto-generated code&#8230; have you ever tried to debug into FinalizeArray?  It&#8217;s a huge mess of ASM.  What you would see in the debugger if you tried to trace into this would be a much smaller and more straightforward mess of ASM, so if anything, debugging would be improved!</p>
<p>If Embarcadero would do these two things&#8211;throw out ARC in favor of a [Local] attribute (don&#8217;t worry about compatibility if it&#8217;s only for one version, guys; Delphi developers are very forgiving and we&#8217;d let you take a mulligan on an obvious mistake; it wouldn&#8217;t be the first time we&#8217;ve done it) and throw out FinalizeArray and FinalizeRecord in favor of faster, compiler-generated static code, we&#8217;d see some huge improvements in both readability and performance for the Delphi language.  That would give us a NextGen I could actually rant about <em>positively</em>!</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/505/how-to-simplify-memory-management-the-right-way/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>NextGen: Delphi&#8217;s &#8220;Visual Fred&#8221; moment?</title>
		<link>http://tech.turbu-rpg.com/499/nextgen-delphis-visual-fred-moment</link>
		<comments>http://tech.turbu-rpg.com/499/nextgen-delphis-visual-fred-moment#comments</comments>
		<pubDate>Fri, 17 May 2013 21:58:48 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Memory Management]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=499</guid>
		<description><![CDATA[There&#8217;s been a lot of talk recently about immutable strings in the iOS compiler, which, as Marco pointed out, is not actually implemented (yet) but is just something that&#8217;s under consideration.  And it appears that he&#8217;s uncomfortable with the removal of AnsiStrings.  That&#8217;s a good thing, IMO.  I think they should be put back, particularly [...]]]></description>
				<content:encoded><![CDATA[<p>There&#8217;s been a lot of talk recently about immutable strings in the iOS compiler, which, <a href="http://blog.marcocantu.com/blog/strings_immutability_cow_ansistrings.html?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+marcocantublog+%28marcocantu.blog%29">as Marco pointed out,</a> is not actually implemented (yet) but is just something that&#8217;s under consideration.  And it appears that he&#8217;s uncomfortable with the removal of AnsiStrings.  That&#8217;s a good thing, IMO.  I think they should be put back, particularly for UTF-8 strings.<span id="more-499"></span></p>
<p>I have to disagree with one of the points he made, before I get into the main focus of my post.  He said that &#8220;Optimizing for English language is not a primary goal, as Delphi is used a lot around the world.&#8221;  That&#8217;s a mistake in modern coding, because even if your application&#8217;s user interface isn&#8217;t in English, it&#8217;s very likely that it will rely on one or more of the following features:</p>
<ul>
<li>HTML/HTTP, either for display purposes or for communicating with websites and web services</li>
<li>XML</li>
<li>SQL</li>
<li>Some scripting language</li>
</ul>
<p>Each of these features make heavy use of English keywords, and numbers and symbols in the ASCII range.  Optimizing for them with a native UTF-8 string type will help most programs no matter what language the users speak or read.</p>
<p>But that&#8217;s not really what I wanted to talk about.  There are more serious problems in the NextGen compiler.  Does anyone remember <a href="http://catb.org/jargon/html/V/Visual-Fred.html">Visual Fred</a>?  When Microsoft came out with Visual Basic.NET, it was incompatible with classic VB code in many ways, which made it essentially impossible to port existing VB projects forward.  There are good arguments out there to support the claim that VB.NET is a better, more powerful language than classic VB, but that doesn&#8217;t change the fact that it&#8217;s a very different, incompatible language, and that calling it by the same name as classic VB is deceptive.  So people decided they should call it by a different name, and the term &#8220;Visual Fred&#8221; was coined.</p>
<p>I&#8217;m worried that Delphi is heading in the same direction.  Let&#8217;s have a look at a couple of the other things that were added in the Nextgen compiler.  (These are things that <em>actually were added</em>, not just things that are being discussed as possibilities.)  They&#8217;re huge messes, and for some reason, people don&#8217;t seem to be talking about them.</p>
<p><strong>STRING INDEXING CONFUSION: </strong>Nextgen strings are 0-based, rather than 1-based.  Now, that would be bad enough if that was all.  (Note: I&#8217;m not claiming that 1-based strings are inherently better.  There are good arguments for both styles.  But changing the way it works when you have literally billions of existing lines of code that use the old system is just insane.)  But it&#8217;s worse than that.  &#8220;To make the transition easier,&#8221; string indexing is controlled by a compiler directive.  Now strings might be zero-based or they might be one-based, depending on what the compiler directive is set to where the routine that uses the string is compiled.  Now we don&#8217;t have a language with 0-based strings, and we don&#8217;t have a language with 1-based strings; <em>we have both in the same codebase</em>!</p>
<p>There&#8217;s an old joke in programming circles: &#8220;There are only two difficult problems in computer science: cache invalidation, naming things, and off-by-one errors.&#8221;  Expect to see off-by-one errors skyrocket under the new string indexing regime.</p>
<p><strong>AUTOMATED REFERENCE COUNTING:</strong> Under the new compiler, TObject is now a managed type, like String or IInterface.  Very much like IInterface, in fact: Every TObject now has a reference count (it&#8217;s been moved off of TInterfacedObject) and special add/release methods, and the compiler has a special-case hack in it where calling TObject.Free sets the object reference to <strong>nil</strong> instead.</p>
<p>Remember the additional memory pressure created a few releases back, when TMonitor was introduced and every TObject got an extra 4 bytes of overhead whether it needed it or not?  Well, here we go again.  Even more bizarre is the fact that it was added to the iOS compiler.  Adding that overhead to the 64-bit compiler might not be such a bad thing.  But when your target platform is a mobile device with very limited memory?  You&#8217;ve gotta be kidding me!</p>
<p>But it gets worse.  Again following the IInterface model, every reference to a TObject, as a variable, a parameter, a member of an object or record, or an array element will incur compiler-managed AddRef/Release calls.  Again, on devices with limited hardware resources.  And since mobile devices are going multicore now, that means that we get all the additional overhead of synchronization on an atomic value change FOR EVERY SINGLE ONE.</p>
<p>&#8230;well, almost.  You can get around that for parameters by marking them <strong>const, </strong>like with strings and interfaces.  This makes sense with strings, but a lot less sense with objects.  It&#8217;s not uncommon to pass a string somewhere and then change the local copy in some way, but you just don&#8217;t do that with objects.  At least I don&#8217;t.  When was the last time that you wrote a routine that takes an object as input, then assigns something new to the parameter variable, without the parameter being specifically marked as <strong>var</strong>?  So what this means is that in order to avoid crippling overhead on your function calls, you have to go back and spam up a huge percentage of them with <strong>const</strong> declarations.</p>
<p>But it gets worse still.  There&#8217;s a second problem with reference counting: cycles.  If A holds a reference to B, and B holds a reference to A, neither one of them will fall to 0 and nothing will get cleaned up.  <a href="http://docwiki.embarcadero.com/RADStudio/XE4/en/Automatic_Reference_Counting_in_Delphi_Mobile_Compilers#Weak_References">To deal with this problem, you can mark variables and object members with a [Weak] attribute, which marks it as a weak reference.</a>  That&#8217;s great, right?  No cycles, no reference counting overhead&#8230; right? Not quite.  Look closely at the bottom of the documentation, and you&#8217;ll see:</p>
<blockquote><p><b>Note:</b> When an instance has its memory released, all active <b>[weak]</b> references are set to <b>nil</b>. Just as a <b>strong</b> (normal) reference, a <b>[weak]</b> variable can only be <b>nil</b> or reference a valid instance. This is the main reason why a <b>weak</b> reference should be assigned to a <b>strong</b> reference before being tested for <b>nil</b> and dereferenced. Assigning to a strong reference does not allow the instance to be released prematurely.</p></blockquote>
<p>So all of those weak references have to get tracked, and then cleaned up when you&#8217;re done with them.  That&#8217;s actually far more expensive than the atomic updates, and is likely to be a massive performance killer if you use weak references.  And where do you think that all gets stored?  If you said &#8220;on the object itself, with even more overhead per instance, like the new reference count,&#8221; you&#8217;d be&#8230; wrong, actually.  It&#8217;s not *quite* as bad as that.  But all that bookkeeping has to go somewhere, so instead, there&#8217;s a new global multimap structure declared deep in the bowels of system.pas that manages weak references.  Look up TInstHashMap for the gory details.  It&#8217;s not pretty, and because it&#8217;s a global, access has to be protected by a TMonitor.  Yay for additional atomic synchronization and memory management overhead!</p>
<p>And did you notice how it says that with both a strong or a weak reference, an object variable can only be <strong>nil</strong> or reference a valid object?  OK, everyone who&#8217;s ever called something like myStringList.AddObject(myString, TObject(myIntegerValue)); please raise your hand.  Yeah, lots of hands going up out there.  It&#8217;s a pretty common idiom in Delphi code.  Well congratulations, your code no longer works!  You see, this isn&#8217;t really about reference counting.  If it was, no one would care about cleaning up those weak references.  No, what it&#8217;s really about is <strong>memory safety.</strong>  Delphi programmers have soundly rejected the concept of putting garbage collection in the language for years, consistently, every time the question comes up.  But now someone at Embarcadero is trying to sneak it in through the back door.</p>
<p>And this isn&#8217;t just me ranting.  Look at that same documentation page.  Just below the section on weak references, we see that there&#8217;s a new <b>[Unsafe]</b> attribute for special-case references that really need to not be reference-counted for some reason.</p>
<blockquote><p>It should be only used outside the <a title="lib en:System" href="http://docwiki.embarcadero.com/Libraries/XE4/en/System">System</a> unit in very rare situations. It is considered dangerous and its use is not recommended as no code associated with reference counting is generated.</p></blockquote>
<p>In other words, &#8220;we realize that &#8220;unsafe&#8221; code is absolutely necessary to actually create a working programming language, as evidenced by the fact that <em>we have to employ it in the System unit in order to make basic functionality work</em>, but it&#8217;s only for <em>us </em>to use; you really should stick to high-level code only.&#8221;</p>
<p>What a bunch of patronizing crap!  If we wanted guaranteed memory safety and enforced garbage collection, we would be using <del>Prism</del> Oxygene.  Not being burdened with all that baggage is one of Delphi&#8217;s strongest selling points, and someone at Embarcadero doesn&#8217;t get that, and thinks it should all just be thrown out the window.  Well, they&#8217;re wrong.  We already have a .NET Delphi implementation, and one for Java, in Oxygene.  There&#8217;s no good reason not to keep native Delphi native and close to the metal.</p>
<p>And it keeps getting worse!  You see, there&#8217;s no <strong>[Weak]</strong> generic constraint, which means it&#8217;s impossible to create a TObjectList&lt;[Weak]T&gt;.  And you know where generic lists are popping up?  Everywhere!  Since you only want to assign object references to strongly typed values so that ARC can work, that means the old TList is out.  So let&#8217;s look at one specific scenario: GUI design.</p>
<p>In previous versions of Delphi, TComponent had a member declared as FComponents: TList.  It held the component&#8217;s child components.  Now that&#8217;s a generic list, containing strong references to the child components.  What that means (among other things) is that you can no longer delete a UI element by calling Free on it.  (Free is &#8220;magic&#8221; now, remember?  All it does is set your reference to <strong>nil</strong>.  But with the object&#8217;s owner holding a strong reference to it, that won&#8217;t bring the count down to 0.)</p>
<p>Whatever shall we do?  Never fear! It&#8217;s <em>even more incompatible changes</em> to the rescue!  There&#8217;s <a href="http://docwiki.embarcadero.com/Libraries/XE4/en/System.TObject.DisposeOf">a new method on TObject, called DisposeOf</a>, that forces the destructor to execute immediately in exactly the same way that Free used to do.  So instead of using what we already have that we know works, someone decided to change the semantics of Free, and then <em>introduce something else that does exactly what Free is supposed to do</em>, except that you still have to wait for the garbage collector to actually clean up the object.  And they called it Dispose.  <a href="http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx">Hmm&#8230; where have I heard that before?</a></p>
<p>The entire ARC model is one big mess from beginning to end.  It will make Delphi code slow&#8211;it will essentially make it impossible to write fast Delphi code, in fact&#8211;and it will break tons of existing, working code.  I literally see zero benefit to any of this.  Managed code advocates&#8217; FUD notwithstanding, <a href="http://tech.turbu-rpg.com/106/delphi-memory-management-made-simple">manual memory management is not a difficult issue.</a>  Heck, <a href="http://programmers.stackexchange.com/a/129555/935">in Delphi it&#8217;s a solved problem with FastMM and FullDebugMode.</a>  Even if someone were to make the (somewhat dubious) claim that this &#8220;modernizing&#8221; of the language will attract new developers, the saying &#8220;a bird in the hand beats two in the bush&#8221; exists for a reason.</p>
<p>There&#8217;s one very interesting thing that was introduced among all of this ARC crap, that could be used to produce real improvements in memory management and help people write cleaner code going forward, <em>without breaking any existing code,</em> had the compiler team followed a slightly different path.  But this article is too long already, so I&#8217;ll explain how to do this sort of stuff right tomorrow.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/499/nextgen-delphis-visual-fred-moment/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>More dwsLinq improvements: query sources and JSON</title>
		<link>http://tech.turbu-rpg.com/497/more-dwslinq-improvements-query-sources-and-json</link>
		<comments>http://tech.turbu-rpg.com/497/more-dwslinq-improvements-query-sources-and-json#comments</comments>
		<pubDate>Thu, 16 May 2013 22:36:01 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=497</guid>
		<description><![CDATA[When I started writing dwsLinq, I never intended it to just be an integrated SQL query builder.  I did that first because it was both useful and easy to implement, but that was never the end goal. Over the last few days I&#8217;ve taken a big step towards the real goal: developing a general-purpose data [...]]]></description>
				<content:encoded><![CDATA[<p>When I started writing dwsLinq, I never intended it to just be an integrated SQL query builder.  I did that first because it was both useful and easy to implement, but that was never the end goal.</p>
<p>Over the last few days I&#8217;ve taken a big step towards the real goal: developing a general-purpose data querying system.  I factored out all of the SQL-specific stuff into its own unit and created an interface called IQueryBuilder that responds to the various query operators to build an expression tree that can be evaluated by DWS.  You create a recognizer and register it with dwsLinq, that checks the value of your FROM expression and returns an IQueryBuilder if it can create an expression for it.  And once I had that working, I created a second unit with a new implementation of IQueryBuilder, for querying JSON data.<span id="more-497"></span></p>
<p>I checked it in recently, and it supports all of the query operators except JOIN (which raises a compiler error, since I couldn&#8217;t figure out how to do in any meaningful way without language support for anonymous methods) and DISTINCT (which is a no-op that raises a compiler warning).  It takes a JSONVariant value (supplied by the JSON Connector language extension) as input and produces a new one as output.  The INTO operator expects a JSONVariant as input and can output any type.  (There&#8217;s no special to distinguish array types from single elements, like with the SQL version, because this is a lot more complicated to pull off without an enforced schema.  I might change that later on.)</p>
<p>The JSON query system is still very rough, and very much a work in progress.  It&#8217;s a lot harder to get things right than SQL, because SQL relations have a schema and JSON does not.  (It&#8217;s essentially the same as the difference between ensuring type safety in a static language or a dynamic one.  Getting it right in the dynamic language is a lot more work!)</p>
<p>The query system expects that the input value will consist of an array of objects (much like a SQL result set) and should work more or less as expected under those conditions.  I&#8217;ve tried to put in cases for the various query operators to handle them, but it still needs work, and I&#8217;ll keep working on it.</p>
<p>But what this means is that anyone could write an IQueryBuilder implementation and their own query expression objects, to be able to run LINQ expressions against arbitrary data.  This is starting to become a really interesting project&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/497/more-dwslinq-improvements-query-sources-and-json/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>dwsLinq update: INTO</title>
		<link>http://tech.turbu-rpg.com/494/dwslinq-update-into</link>
		<comments>http://tech.turbu-rpg.com/494/dwslinq-update-into#comments</comments>
		<pubDate>Wed, 15 May 2013 16:34:05 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=494</guid>
		<description><![CDATA[I just checked in an update to dwsLinq that covers a big step in its progress: the INTO clause. This is not quite the same thing as INTO in C#&#8217;s version of LINQ.  INTO there basically acts as a naming operator, taking a query expression and giving it a name so that you can use [...]]]></description>
				<content:encoded><![CDATA[<p>I just checked in an update to dwsLinq that covers a big step in its progress: the INTO clause.</p>
<p>This is not quite the same thing as INTO in C#&#8217;s version of LINQ.  INTO there basically acts as a naming operator, taking a query expression and giving it a name so that you can use it as a sub-expression in further query work.</p>
<p>I did something different with this.  INTO in dwsLinq takes a function pointer as its argument.  The function has to have a single parameter of type Dataset, and return some value, and the INTO clause changes the output of the entire query expression.<span id="more-494"></span></p>
<p>If the INTO function returns an array type, it will be called once, and whatever it returns becomes the query result.  Otherwise, it gets called once for each result in the dataset, and the individual results get collected into an array of whatever type the INTO function returns, which becomes the query result.  The idea is that this can be used to quickly load data into script objects or records.  You provide the basic query, and a function that transforms a dataset row into an object, and let dwsLinq take care of the plumbing.</p>
<p>Having to write a function pointer expression into the query is a bit awkward, but it&#8217;s a limitation of the language at the moment.  Once DWS is able to deal with anonymous methods, I&#8217;ll expand the capabilities of INTO.</p>
<p>Here&#8217;s the test that I wrote, that demonstrates the syntax for both forms of INTO.  Both styles shown here give the same result:</p>
<pre>uses System.Data;

function processor(ds: Dataset): integer;
begin
   result := ds.FieldByName('VALUE_1').AsInteger;
end;

function processor2(ds: Dataset): array of integer;
begin
   var value := ds.FieldByName('VALUE_1');
   while ds.step do
      result.add(value.AsInteger);
end;

var db := DataBase.Create('SQLite', ['.\Linq\linqtest.s3db']);

var values := from DB.TBL1
              order by ID
              select VALUE_1
              into @processor;
for var value in values do
   printLn(value);

PrintLn('');

var values2 := from DB.TBL1
               order by ID
               select VALUE_1
               into @processor2;
for var value2 in values2 do
   printLn(value2);</pre>
<p>Yes, the @ is necessary for the DWS parser to recognize it as a function pointer.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/494/dwslinq-update-into/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Work in progress: dwsLinq extension for DWS</title>
		<link>http://tech.turbu-rpg.com/489/work-in-progress-dwslinq-extension-for-dws</link>
		<comments>http://tech.turbu-rpg.com/489/work-in-progress-dwslinq-extension-for-dws#comments</comments>
		<pubDate>Sat, 11 May 2013 20:00:13 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=489</guid>
		<description><![CDATA[I&#8217;ve always enjoyed the concept behind LINQ: write SQL-esque queries directly in your code, with the compiler able to provide syntactical and type checks, and automatically generate the correct code to do what you wanted. Unfortunately, there&#8217;s nothing like that available for Delphi.  There could be, if the team would shift their focus to augmenting [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve always enjoyed the concept behind LINQ: write SQL-esque queries directly in your code, with the compiler able to provide syntactical and type checks, and automatically generate the correct code to do what you wanted.</p>
<p>Unfortunately, there&#8217;s nothing like that available for Delphi.  There could be, if the team would shift their focus to augmenting the language with actual useful features borrowed from managed languages, such as a proper extension method implementation, rather that burdening it with useless, counterproductive crap like pseudo-garbage collection and new String models.  But for the time being, we&#8217;re out of luck.</p>
<p>It could be done in DWS, but LINQ is a really complex system that makes heavy use of lambdas (aka anonymous methods,) which Eric Grange hasn&#8217;t gotten around to supporting yet outside of the JavaScript cross-compilation.  Apparently it&#8217;ll take a complete re-architecting of the execution model to make anonymous methods available.</p>
<p>But a while ago, an idea struck me.  <em>In .NET, </em><em>LINQ uses anonymous methods to support expression class evaluation at runtime.  But DWS is already an interpreted scripting system that operates on an expression tree!</em>  And since DWS has a language extension mechanism in place, I decided to poke around and see what was possible.<span id="more-489"></span></p>
<p>I came up with a simple proof of concept that could read very simplistic queries and generate SQL from them, then execute it using DWS&#8217;s database module and return a dataset.  It required modifying both the compiler and the language extension system.  So I sent it to Eric for feedback, just as an idea.  I was expecting some constructive criticism, either explaining why it was a bad idea, or some things that would make it work better.  I certainly never expected him to actually take it and put it in the DWS repository.</p>
<p>Guess what he did with my code?</p>
<p>So now I&#8217;ve been added as a contributor to the DWS project, so I can maintain this.  I&#8217;ve been updating it since then, and now it will cover all of the basic syntax features (FROM, JOIN, WHERE, GROUP BY, ORDER BY, and SELECT).  It&#8217;s still just a SQL generator, and not a full-blown LINQ implementation, which will take time, but if you&#8217;re working with DWS and database code, it already has a few advantages over the normal SQL model.</p>
<p>You can integrate parameters directly into your query, rather than having to put them someplace else.  For example, consider this:</p>
<pre>myDataset := myDatabase.Query(#'
 select VALUE1, dbFunction(VALUE2, :param1)
 from TABLE_1
 where ID = :param2', [arg, userID]);</pre>
<p>Having to move the params apart from the values you&#8217;re giving them makes it harder to read, especially on large queries, you can have DRY problems with it.  What happens if you rearrange the query, you change the order of the params?  What if you add or delete a param?  You need to find the right place in your param array to insert/delete the new value.</p>
<p>This can be expressed in LINQ syntax more simply, without the problems noted above:</p>
<pre>myDataset :=
 from myDatabase.TABLE_1
 where ID = userID
 select VALUE1, dbFunction(VALUE2, arg);</pre>
<p>The dwsLinq parser can call back into the DWS parser to read Pascal expressions, and when building your query, it will automatically replace anything that came from a Pascal expression with a parameter, so you get the right SQL query.</p>
<p>This is still very much a work in progress, but if anyone would like to try it out, it&#8217;s in the repository now.  Any bug reports would be welcome.  Just keep in mind that this isn&#8217;t expected to be stable, or to work well, yet.  It&#8217;s still mostly something I&#8217;m playing around with.  But so far, it&#8217;s kinda cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/489/work-in-progress-dwslinq-extension-for-dws/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Wanted: live leak detection for FastMM</title>
		<link>http://tech.turbu-rpg.com/486/wanted-live-leak-detection-for-fastmm</link>
		<comments>http://tech.turbu-rpg.com/486/wanted-live-leak-detection-for-fastmm#comments</comments>
		<pubDate>Thu, 28 Mar 2013 21:48:19 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Memory Management]]></category>
		<category><![CDATA[Wish List]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=486</guid>
		<description><![CDATA[One of the awesome things about FastMM is FullDebugMode.  Its features pretty much make memory leaks trivial to track down&#8230; usually.  But if you&#8217;ve got the classic problem of code creating objects and placing them in a container somewhere and then abandoning them, you can have a huge memory leak in your program without it [...]]]></description>
				<content:encoded><![CDATA[<p>One of the awesome things about FastMM is FullDebugMode.  Its features pretty much make memory leaks trivial to track down&#8230; usually.  But if you&#8217;ve got the classic problem of code creating objects and placing them in a container somewhere and then abandoning them, you can have a huge memory leak in your program without it ever being detected, just as long as the container gets properly cleaned up before the program shuts down.</p>
<p>Seems to me that it should be possible to detect this with a bit of instrumenting, though.  Here&#8217;s the basic idea.<span id="more-486"></span></p>
<p>When FastMM starts, it gets a brand new heap with nothing allocated in it yet, and it sets up its bookkeeping.</p>
<p>When FastMM shuts down, it checks to see if anything is still allocated in that heap.  If so, it reports it.</p>
<p>If you want to detect &#8220;live leaks,&#8221; just apply that principle recursively: Run some routine called &#8220;LiveLeakCheckBegin&#8221; which allocates a new heap and some new bookkeeping for it.  From this point on, all new allocations should go into this new heap.</p>
<p>At some later point, run &#8220;LiveLeakCheckEnd&#8221;.  When this is run, FastMM would go through and generate a leak report based on everything still allocated *in the new heap*.</p>
<p>Obviously, this would only be for debugging purposes, and should not be used in a release build.  Maybe it could be added to the FullDebugMode DLL as a new feature?</p>
<p>Pierre, if you&#8217;re reading this, how difficult would it be to implement something like this in FastMM?</p>
<p>Anyone else, do you have any ideas on how to implement it without having to modify FastMM?</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/486/wanted-live-leak-detection-for-fastmm/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The US Supreme Court just ruled that publishers have no right to differential pricing</title>
		<link>http://tech.turbu-rpg.com/480/the-us-supreme-court-just-ruled-that-publishers-have-no-right-to-differential-pricing</link>
		<comments>http://tech.turbu-rpg.com/480/the-us-supreme-court-just-ruled-that-publishers-have-no-right-to-differential-pricing#comments</comments>
		<pubDate>Wed, 20 Mar 2013 05:45:33 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[politics]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=480</guid>
		<description><![CDATA[If you&#8217;ve been paying attention to copyright and the myriad ways it gets abused by publishing interests, you&#8217;ve probably heard of the Kirtsaeng case.  For those just tuning in, here&#8217;s quick recap: John Wiley &#38; Sons is a publishing company, involved in one of the most despicable fields within the publishing industry: the publication of [...]]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;ve been paying attention to copyright and the myriad ways it gets abused by publishing interests, you&#8217;ve probably heard of the <a href="http://en.wikipedia.org/wiki/Kirtsaeng_v._John_Wiley_%26_Sons,_Inc.">Kirtsaeng case.</a>  For those just tuning in, here&#8217;s quick recap:</p>
<p>John Wiley &amp; Sons is a publishing company, involved in one of the most despicable fields within the publishing industry: the publication of academic textbooks.  Anyone who&#8217;s ever been to college and had to pay the exorbitant rates they charge every semester, just because they can, will need no explanation as to why these guys are scum.</p>
<p>The interesting thing is, while they charge whatever they can, &#8220;whatever they can&#8221; means different things in different contexts.  Some parts of the world are wealthier than others, and in some countries there&#8217;s just less blood available to be squeezed from that particular stone, and so they have to set the prices lower so as not to be unaffordable.</p>
<p>Anyone with a basic knowledge of economics, when presented with these facts, should recognize that an opportunity for <a href="http://en.wikipedia.org/wiki/Arbitrage">arbitrage</a> exists here: buying goods in a low-priced market and reselling them at a profit, where the prices are high.  And that&#8217;s exactly what this Thai guy called Supap Kirtsaeng did.<span id="more-480"></span></p>
<p>He would purchase textbooks in poor nations at a low cost, then resell them to American students at a decent markup which still managed to significantly undercut Wiley&#8217;s prices.  It&#8217;s a win-win situation. Students get a more affordable education, Kirtsaeng gets some money in his pocket, and the parasites lose out on some opportunities for ill-gotten gain.  Everyone&#8217;s happy.</p>
<p>&#8230;except, of course, the parasites.  Wiley said &#8220;hey, we&#8217;re losing money on this!&#8221; and sued.</p>
<p>Kirtsaeng&#8217;s defense was that, under the <a href="http://en.wikipedia.org/wiki/First-sale_doctrine">First Sale Doctrine</a> in US copyright law, once he&#8217;s legally purchased something, he has the right to do whatever he wants to with it, including resell it, and the publisher has no right to interfere.  (Publishing interests hate the First Sale Doctrine.  In digital media, they&#8217;ve managed to do a good job circumventing it by getting the DMCA passed, so that they can just stick DRM on something and then even if you have rights to something you purchased, you can&#8217;t legally exercise them.  But Kirtsaeng was dealing with books.)</p>
<p>Wiley responded with the somewhat ridiculous claim that, because the books were printed and purchased overseas, they were not covered by the First Sale Doctrine, which is a provision of US law and therefore does not apply to foreign purchases.  (And yet somehow they wanted US copyright law to apply to these purchases in every sense in which it benefited <em>them</em>! Otherwise, they would have had no case in the first place.)</p>
<p>Well, to make a long story short, different courts ruled different ways, and it kept getting appealed, until the Supreme Court agreed to hear the case.  The justices asked some pretty pointed questions about how the exclusion of First Sale rights from copyrighted items created overseas might apply to other areas of life.  Would it be illegal to sell your car, for example, if it runs copyrighted computer code that was written outside of the USA?</p>
<p>Well, they finally reached a verdict earlier today, in which they upheld Kirtsaeng&#8217;s First Sale rights and officially ruled that the First Sale Doctrine is not bound by geography.  But the part that really caught my attention was the way their ruling explicitly went back and touched on the basic underlying issue: arbitrage.</p>
<blockquote><p>Wiley and the dissent claim that a nongeographical interpretation will make it difficult, perhaps impossible, for publishers (and other copyright holders) to divide foreign and domestic markets. We concede that is so. A publisher may find it more difficult to charge different prices for the same book in different geographic markets. But we do not see how these facts help Wiley, for we can find no basic principle of copyright law that suggests that publishers are especially entitled to such rights.</p>
<p>[....] the Constitution’s language nowhere suggests that its limited exclusive right should include a right to divide markets or a concomitant right to charge different purchasers different prices for the same book, say to increase or to maximize gain. Neither, to our knowledge, did any Founder make any such suggestion.We have found no precedent suggesting a legal preference for interpretations of copyright statutes that would provide for market divisions.</p>
<p>To the contrary, Congress enacted a copyright law that (through the “first sale” doctrine) limits copyright holders’ ability to divide domestic markets. And that limitation is consistent with antitrust laws that ordinarily forbid market divisions.</p></blockquote>
<p>In other words, the Supreme Court just officially proclaimed, as part of a larger ruling, that <strong>publishers have no inherent right to charge different prices for the same product in different markets</strong>.</p>
<p>If anyone wonders why I&#8217;ve spent so many words writing up a brief recap of a copyright decision on what&#8217;s supposed to be a Delphi blog, look at that last paragraph.  Things are about to get very interesting for Delphi customers overseas&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/480/the-us-supreme-court-just-ruled-that-publishers-have-no-right-to-differential-pricing/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>The next RTTI bottleneck</title>
		<link>http://tech.turbu-rpg.com/473/the-next-rtti-bottleneck</link>
		<comments>http://tech.turbu-rpg.com/473/the-next-rtti-bottleneck#comments</comments>
		<pubDate>Fri, 01 Mar 2013 06:01:26 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Dark Corners]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=473</guid>
		<description><![CDATA[A few years back, when I posted an analysis of how TValue is very slow, it prompted a lot of response from the community.  Various people ran their own benchmarks, and started working on building or optimizing their own meta-value types.  Some people are even still working on that today.  But one of the most [...]]]></description>
				<content:encoded><![CDATA[<p>A few years back, when I posted an analysis of how <a href="http://tech.turbu-rpg.com/100/tvalue-is-very-slow">TValue is very slow</a>, it prompted a lot of response from the community.  Various people ran their own benchmarks, and started working on building or optimizing their own meta-value types.  Some people are even <a href="http://www.cromis.net/blog/2013/02/tanyvalue-an-attempt-to-make-the-best-variable-data-container/">still working on that today</a>.  But one of the most interesting things was Robert Love&#8217;s response.  He looked at the TValue code and found a way that it could be optimized for the common case to speed things up.<span id="more-473"></span></p>
<p>I built on his foundation and sent a suggested patch to the Delphi team.  They made their own tweaks, and newer versions of Delphi have had a much faster TValue because of that.  But one of the most interesting things I heard while I was working on that improvement came from Barry Kelly. He said that he wasn&#8217;t sure how much those speedups would actually help, because the bulk of your CPU time in RTTI work was going to be spent in invocation (using the RTTI system to call methods) and not in moving data in and out of TValue variables.</p>
<p>And he was right.  If you wanna really break your brain sometime, trace into a call to TRttiMethod.Invoke and take a look at what all is taking place under the hood.  That&#8217;s a huge amount of work going on, and the interesting thing is how much of it will be exactly the same every time you invoke the same method, assuming you have a valid parameter list.</p>
<p>To do it quickly, you have to recompute as little of that setup code as possible every time.  The fastest way would be to write your own invocation routines, something like this:</p>
<pre><div class="codesnip-container" ><div class="delphi codesnip" style="font-family:monospace;"><span class="kw1">function</span> InvokeFuncA<span class="br0">&#40;</span><span class="kw1">var</span> params<span class="sy1">:</span> TArray&lt;TValue&gt;<span class="sy1">;</span> <span class="kw1">const</span> <span class="kw2">self</span><span class="sy1">:</span> TValue<span class="br0">&#41;</span><span class="sy1">:</span> TValue<span class="sy1">;</span><br />
<span class="kw1">begin</span><br />
&nbsp; &nbsp;result <span class="sy1">:</span><span class="sy3">=</span> <span class="br0">&#40;</span><span class="kw2">self</span><span class="sy1">.</span><span class="me1">AsObject</span> <span class="kw1">as</span> TMyClass<span class="br0">&#41;</span><span class="sy1">.</span><span class="me1">FuncA</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="sy1">.</span><span class="me1">AsInteger</span><span class="br0">&#41;</span><span class="sy1">;</span><br />
<span class="kw1">end</span><span class="sy1">;</span></div></div></pre>
<p>Of course, that&#8217;s a static invocation routine which only works for one method, which is the exact opposite of what TRttiMethod.Invoke does: provides you with a generic invocation routine that works for any method.  But it&#8217;s fast.</p>
<p>So&#8230; what if we could find a way to get TRttiMethod to create something like that for us, at runtime?  Instead of doing a bunch of work every time you call it to figure out what goes into memory where in order to convert your list of TValues into a native parameter list for a method, maybe it could <em>work out how to perform that mapping</em>, and express it in machine code.</p>
<p>It&#8217;s not as strange as it sounds. TMethodImplementation already does a certain amount of machine code generation at runtime to make some of the fancier RTTI tricks possible.  And with RTTI becoming used in more places in Delphi (it&#8217;s all over the place in Live Bindings, for example,) the last thing anyone wants is for it to be slow.</p>
<p>So, I&#8217;d like to challenge the community to step up to the plate again.  Is there anyone out there who knows enough about low-level code to build what would essentially be a JIT compiler that takes a TRttiMethod as input and outputs a shim for fast invocation?  I&#8217;ll be poking at things from one angle, but I&#8217;d like to invite anyone else who&#8217;s interested to help out. Let&#8217;s see how fast we can get RTTI invocation.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/473/the-next-rtti-bottleneck/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Heading to Australia</title>
		<link>http://tech.turbu-rpg.com/470/heading-to-australia</link>
		<comments>http://tech.turbu-rpg.com/470/heading-to-australia#comments</comments>
		<pubDate>Tue, 19 Feb 2013 05:49:53 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=470</guid>
		<description><![CDATA[A while back, the Australian Delphi Users&#8217; Group put out a call for papers for a conference they were planning to hold in March of 2013.  I sent in a submission and it ended up getting accepted, so in about a month I&#8217;m going to be going to Australia! About a year ago, I was [...]]]></description>
				<content:encoded><![CDATA[<p>A while back, the Australian Delphi Users&#8217; Group put out a call for papers for a conference they were planning to hold in March of 2013.  I sent in a submission and it ended up getting accepted, <a href="http://www.adug.org.au/meetings/Symposia/2013/default.html">so in about a month</a> I&#8217;m going to be going to Australia! <img src='http://tech.turbu-rpg.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><span id="more-470"></span>About a year ago, I was browsing around and I found an ad for a Web-based game that looked like a lot of fun.  Turns out it really wasn&#8217;t.  It was kind of simplistic and insipid, in fact, but it had a bunch of players who were paying real money for in-game bonuses.</p>
<p>I&#8217;d been working on a bunch of HTTP-based services for work, and I looked at this game and thought, &#8220;I could do this, and I could do it better.&#8221;  So I got in touch with a few friends of mine who have some design skills, and we set up a team.  Things are not quite ready to announce anything officially yet, but we&#8217;re making a lot of progress and are getting pretty close to launching a public beta.</p>
<p>In the middle of all this, the ADUG call for papers came out, so I submitted an idea for presenting about how to build an interactive website on a pure Pascal stack.  This is based on what I&#8217;ve learned from my work on the game, using a Delphi web server, with <a href="http://code.google.com/p/dwscript/">DWS</a> for the server-side scripting and building advanced front-end effects in <a href="http://op4js.optimalesystemer.no/">Smart</a>.</p>
<p>For those of you who are in the area and can make it, I hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/470/heading-to-australia/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Does Apple owe Jim McKeeth money?</title>
		<link>http://tech.turbu-rpg.com/467/does-apple-owe-jim-mckeeth-money</link>
		<comments>http://tech.turbu-rpg.com/467/does-apple-owe-jim-mckeeth-money#comments</comments>
		<pubDate>Mon, 04 Feb 2013 18:52:10 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[irony]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=467</guid>
		<description><![CDATA[Jim McKeeth, the RemObjects evangelist who runs delphi.org, was a coworker of mine before he left for RO.  Another coworker just pointed me to a couple articles that mention his name. Slide to unlock is not Apple&#8217;s patent Smartphone Wars: Micron’s Slide-to-Unlock Patent Apparently the patent office essentially just ruled that the infamous &#8220;slide to [...]]]></description>
				<content:encoded><![CDATA[<p>Jim McKeeth, the RemObjects evangelist who runs <a href="http://www.delphi.org">delphi.org</a>, was a coworker of mine before he left for RO.  Another coworker just pointed me to a couple articles that mention his name.</p>
<p><a href="http://www.decryptedtech.com/news/slide-to-unlock-is-not-apples-patent.html">Slide to unlock is not Apple&#8217;s patent</a></p>
<p><a href="http://www.patentlyo.com/patent/2013/01/smartphone-wars-microns-slide-to-unlock-patent.html">Smartphone Wars: Micron’s Slide-to-Unlock Patent</a></p>
<p>Apparently the patent office essentially just ruled that the infamous &#8220;slide to unlock&#8221; patent that Apple has been beating Samsung and other companies that make Android devices over the head with is actually invalid, because another company, Micron PC, invented it several years before Apple did.  And the name associated with Micron&#8217;s patent is Jim McKeeth.</p>
<p>Of course, when something like this happens, you wonder if it&#8217;s the same guy or not.  Sometimes people have the same name, you know.  But I did some checking, and it appears that <a href="http://www.mckeeth.org/2005/05/congratulations-to-russ-on-graduating/">he did used to work at Micron.</a></p>
<p>So, does Apple owe Jim McKeeth money for this bogus &#8220;innovation&#8221; that they&#8217;ve been extorting money from all sorts of smartphone companies over?  It would be deliciously ironic if they did.</p>
<p>Jim, if you&#8217;re reading this, would you mind leaving a comment on the subject?</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/467/does-apple-owe-jim-mckeeth-money/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
