<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Cleaner API Design Using Ignorable &#8220;Hints&#8221;</title>
	<atom:link href="http://www.hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/feed/" rel="self" type="application/rss+xml" />
	<link>http://hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/</link>
	<description>a disgruntled developer taking a stand in the information multiverse</description>
	<pubDate>Sat, 04 Feb 2012 09:29:14 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
		<item>
		<title>By: Hostile Fork</title>
		<link>http://hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/#comment-847</link>
		<dc:creator>Hostile Fork</dc:creator>
		<pubDate>Thu, 08 Jan 2009 21:19:34 +0000</pubDate>
		<guid isPermaLink="false">http://hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/#comment-847</guid>
		<description>Hi Jeremy, thanks for visiting the blog (and reading these old entries!)

You make a good point in matching problem-statement to problem-solution for the specific case I gave.  Since I wasn't taking advantage of any particular property of knowing the number in advance, it was a distracting choice.  So I should either use your hint or introduce the allocation number benefit (like, there's some memory block and knowing the number helps you allocate one block).  Since the latter just complicates no reason I'll go with yours!

But my main thrust wasn't any particular prescription for what kind of hints you would make.  It was merely the idea of splitting exposed APIs into instructions for which &lt;i&gt;every&lt;/i&gt; parameter has semantic meaning... and these "hints" in which ZERO parameters have meaning.

It encourages clients to write their code in a natural way--and gives the API implementers a chance to be more free in inventing interesting hints based on the specific use cases that clients are encountering.  Especially since the program should still work if the implementation were changed to a no-op!  Not only will the hinting not break backwards binary compatibility when clients run against old API implementations (assuming the hints aren't statically linked), but a hint that turns out to be useless can be dropped.

I've always wished it were possible to give these kinds of hints to hardware.  Recently I was looking at LLVM and saw they had an instruction for "prefetch" where you can give hints about the locality of your data access:

http://llvm.org/docs/LangRef.html

That looks like a pretty cool project overall, perhaps worth delving into...</description>
		<content:encoded><![CDATA[<p>Hi Jeremy, thanks for visiting the blog (and reading these old entries!)</p>
<p>You make a good point in matching problem-statement to problem-solution for the specific case I gave.  Since I wasn&#8217;t taking advantage of any particular property of knowing the number in advance, it was a distracting choice.  So I should either use your hint or introduce the allocation number benefit (like, there&#8217;s some memory block and knowing the number helps you allocate one block).  Since the latter just complicates no reason I&#8217;ll go with yours!</p>
<p>But my main thrust wasn&#8217;t any particular prescription for what kind of hints you would make.  It was merely the idea of splitting exposed APIs into instructions for which <i>every</i> parameter has semantic meaning&#8230; and these &#8220;hints&#8221; in which ZERO parameters have meaning.</p>
<p>It encourages clients to write their code in a natural way&#8211;and gives the API implementers a chance to be more free in inventing interesting hints based on the specific use cases that clients are encountering.  Especially since the program should still work if the implementation were changed to a no-op!  Not only will the hinting not break backwards binary compatibility when clients run against old API implementations (assuming the hints aren&#8217;t statically linked), but a hint that turns out to be useless can be dropped.</p>
<p>I&#8217;ve always wished it were possible to give these kinds of hints to hardware.  Recently I was looking at LLVM and saw they had an instruction for &#8220;prefetch&#8221; where you can give hints about the locality of your data access:</p>
<p><a href="http://llvm.org/docs/LangRef.html" rel="nofollow" target="_blank" class="liexternal">http://llvm.org/docs/LangRef.html</a></p>
<p>That looks like a pretty cool project overall, perhaps worth delving into&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jeremy Friesner</title>
		<link>http://hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/#comment-844</link>
		<dc:creator>Jeremy Friesner</dc:creator>
		<pubDate>Fri, 02 Jan 2009 20:11:32 +0000</pubDate>
		<guid isPermaLink="false">http://hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/#comment-844</guid>
		<description>Oops, that should be:

[code]
void EndMakingWidgetsBatch()
{
   if (-–widgets_batch_count == 0) 
      RestartProcesses();
}
[/code]</description>
		<content:encoded><![CDATA[<p>Oops, that should be:</p>
<p>[code]<br />
void EndMakingWidgetsBatch()<br />
{<br />
   if (-–widgets_batch_count == 0)<br />
      RestartProcesses();<br />
}<br />
[/code]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jeremy Friesner</title>
		<link>http://hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/#comment-842</link>
		<dc:creator>Jeremy Friesner</dc:creator>
		<pubDate>Fri, 02 Jan 2009 20:08:56 +0000</pubDate>
		<guid isPermaLink="false">http://hostilefork.com/2005/08/12/cleaner-apis-using-ignorable-hints/#comment-842</guid>
		<description>Hi Brian,

I do something similar, but perhaps a little bit better.  My version of the API would look like this:

[code]
[...]

public:
   void BeginMakingWidgetsBatch() 
   {
      widgets_batch_count++;
   }

   Widget * MakeAWidget()
   {
      if (ProcessesRunning())
         StopProcessesSoItsSafeToMakeWidgets();

      Widget * w = new Widget();

      if (widgets_batch_count == 0)
         RestartProcesses();

      return w;
   }

   void EndMakingWidgetsBatch()
   {
      if (--widgets_batch_count == 0)
         RestartProcesses();
   }
[/code]

I think this is better, because it doesn't force the caller to try and predict in advance how many widgets he is planning to make.  If he wants "better performance mode", he simply does this:

[code]
   BeginMakingWidgetsBatch();
   // however many calls to MakeAWidget() he cares to do, go here
   EndMakingWidgetsBatch();
[/code]

... and it handles nested calls correctly as well.  The processes are always restored at the last call to EndMakingWidgetsBatch().  And of course the non-batch version does the right thing as well.

The only hazard here would be the possibility that the user will call BeginMakingWidgetsBatch() and forget to call a matching EndMakingWidgetsBatch(), in which case your processes would never get restarted.  So if you wanted to be extra safe/fancy, you could preclude that possibility by putting those calls into the constructor and destructor of an object that the user puts on the stack, instead:

[code]
    WidgetFactoryBatchObject batchMe(&#38;theWidgetFactory);
    // any number of calls to MakeWidget() can go here
[/code]

(Making the code exception-safe is left as an exercise to the reader ;^) )

-Jeremy</description>
		<content:encoded><![CDATA[<p>Hi Brian,</p>
<p>I do something similar, but perhaps a little bit better.  My version of the API would look like this:</p>
<p>[code]<br />
[&#8230;]</p>
<p>public:<br />
   void BeginMakingWidgetsBatch()<br />
   {<br />
      widgets_batch_count++;<br />
   }</p>
<p>   Widget * MakeAWidget()<br />
   {<br />
      if (ProcessesRunning())<br />
         StopProcessesSoItsSafeToMakeWidgets();</p>
<p>      Widget * w = new Widget();</p>
<p>      if (widgets_batch_count == 0)<br />
         RestartProcesses();</p>
<p>      return w;<br />
   }</p>
<p>   void EndMakingWidgetsBatch()<br />
   {<br />
      if (&#8211;widgets_batch_count == 0)<br />
         RestartProcesses();<br />
   }<br />
[/code]</p>
<p>I think this is better, because it doesn&#8217;t force the caller to try and predict in advance how many widgets he is planning to make.  If he wants &#8220;better performance mode&#8221;, he simply does this:</p>
<p>[code]<br />
   BeginMakingWidgetsBatch();<br />
   // however many calls to MakeAWidget() he cares to do, go here<br />
   EndMakingWidgetsBatch();<br />
[/code]</p>
<p>&#8230; and it handles nested calls correctly as well.  The processes are always restored at the last call to EndMakingWidgetsBatch().  And of course the non-batch version does the right thing as well.</p>
<p>The only hazard here would be the possibility that the user will call BeginMakingWidgetsBatch() and forget to call a matching EndMakingWidgetsBatch(), in which case your processes would never get restarted.  So if you wanted to be extra safe/fancy, you could preclude that possibility by putting those calls into the constructor and destructor of an object that the user puts on the stack, instead:</p>
<p>[code]<br />
    WidgetFactoryBatchObject batchMe(&amp;theWidgetFactory);<br />
    // any number of calls to MakeWidget() can go here<br />
[/code]</p>
<p>(Making the code exception-safe is left as an exercise to the reader ;^) )</p>
<p>-Jeremy</p>
]]></content:encoded>
	</item>
</channel>
</rss>

