<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Consuming Fluent Interfaces</title>
	<atom:link href="http://blog.matthewdoig.com/?feed=rss2&#038;p=174" rel="self" type="application/rss+xml" />
	<link>http://blog.matthewdoig.com/?p=174</link>
	<description>Matthew Doig's Weblog</description>
	<lastBuildDate>Tue, 08 Sep 2009 23:36:14 -0500</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Jonathan Aneja</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2630</link>
		<dc:creator>Jonathan Aneja</dc:creator>
		<pubDate>Tue, 08 Sep 2009 23:36:14 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2630</guid>
		<description>Hey Luke,

VB10 will have an &quot;implicit line continuation&quot; feature where the goal is that in the 98% case you won&#039;t need to type the underscore anymore.

The case you mention though is one of those situations where it gets trickier for us to remove it, due to the ambiguity of With blocks.

Dim rect = RectangleFluent.Create() 
    .SetColor(Color.AliceBlue) 
    .SetHeight(16) 
    .SetLength(16)

If that code is inside a With block then we could parse it as one statement or 4 statements.  We could make a rule to prefer one approach over the other, but that would just get confusing and messy.

Instead what we&#039;ve done is allow the underscore to be implicit *after* the dot:

Dim rect = RectangleFluent.Create().
    SetColor(Color.AliceBlue). 
    SetHeight(16). 
    SetLength(16)

Definitely not perfect, but we felt this was a reasonable compromise.

Hope that helps,

Jonathan Aneja
Program Manager, VB Compiler</description>
		<content:encoded><![CDATA[<p>Hey Luke,</p>
<p>VB10 will have an &#8220;implicit line continuation&#8221; feature where the goal is that in the 98% case you won&#8217;t need to type the underscore anymore.</p>
<p>The case you mention though is one of those situations where it gets trickier for us to remove it, due to the ambiguity of With blocks.</p>
<p>Dim rect = RectangleFluent.Create()<br />
    .SetColor(Color.AliceBlue)<br />
    .SetHeight(16)<br />
    .SetLength(16)</p>
<p>If that code is inside a With block then we could parse it as one statement or 4 statements.  We could make a rule to prefer one approach over the other, but that would just get confusing and messy.</p>
<p>Instead what we&#8217;ve done is allow the underscore to be implicit *after* the dot:</p>
<p>Dim rect = RectangleFluent.Create().<br />
    SetColor(Color.AliceBlue).<br />
    SetHeight(16).<br />
    SetLength(16)</p>
<p>Definitely not perfect, but we felt this was a reasonable compromise.</p>
<p>Hope that helps,</p>
<p>Jonathan Aneja<br />
Program Manager, VB Compiler</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Horsfield</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2599</link>
		<dc:creator>Steve Horsfield</dc:creator>
		<pubDate>Sat, 05 Sep 2009 17:29:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2599</guid>
		<description>You can find the suggestion on Microsoft Connect here: &lt;a href=&quot;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=488312&quot; title=&quot;Microsoft Connect Suggestion&quot; rel=&quot;nofollow&quot;&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=488312&lt;/a&gt;.</description>
		<content:encoded><![CDATA[<p>You can find the suggestion on Microsoft Connect here: <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=488312" title="Microsoft Connect Suggestion" rel="nofollow">https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=488312</a>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Horsfield</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2598</link>
		<dc:creator>Steve Horsfield</dc:creator>
		<pubDate>Sat, 05 Sep 2009 17:17:02 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2598</guid>
		<description>Hi Matt,

Yes, there is no reason why I clever F# compiler could not have an extension operator to do just that.  I&#039;ve recently discovered that :: is treated as a special case by the compiler as it is actually a discriminated union constructor that expects a tuple but is allowed to act as an infix operated that is curried, so there is a precedent for such special cases.

I&#039;ll suggest it to the product team.</description>
		<content:encoded><![CDATA[<p>Hi Matt,</p>
<p>Yes, there is no reason why I clever F# compiler could not have an extension operator to do just that.  I&#8217;ve recently discovered that :: is treated as a special case by the compiler as it is actually a discriminated union constructor that expects a tuple but is allowed to act as an infix operated that is curried, so there is a precedent for such special cases.</p>
<p>I&#8217;ll suggest it to the product team.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mattdoig</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2596</link>
		<dc:creator>mattdoig</dc:creator>
		<pubDate>Sat, 05 Sep 2009 16:04:27 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2596</guid>
		<description>Luke

I will have to look at why identions are not working in the comments, but i still get an unexpected symbol in binding when i try.

let rect = 
    RectangleFluent.Create()
    .SetColor(Color.AliceBlue)
    .SetHeight(16)
    .SetLength(16)  </description>
		<content:encoded><![CDATA[<p>Luke</p>
<p>I will have to look at why identions are not working in the comments, but i still get an unexpected symbol in binding when i try.</p>
<p>let rect =<br />
    RectangleFluent.Create()<br />
    .SetColor(Color.AliceBlue)<br />
    .SetHeight(16)<br />
    .SetLength(16)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mattdoig</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2595</link>
		<dc:creator>mattdoig</dc:creator>
		<pubDate>Sat, 05 Sep 2009 16:02:56 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2595</guid>
		<description>Mauricio

Thanks for the link</description>
		<content:encoded><![CDATA[<p>Mauricio</p>
<p>Thanks for the link</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mattdoig</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2594</link>
		<dc:creator>mattdoig</dc:creator>
		<pubDate>Sat, 05 Sep 2009 16:02:27 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2594</guid>
		<description>Steve

I agree that pipelining methods is a more functional solution to fluency. Every method call in .net takes this as the first parameter.  I wonder if the f# compiler could exploit this to allow for pipeling without the need for extension methods?</description>
		<content:encoded><![CDATA[<p>Steve</p>
<p>I agree that pipelining methods is a more functional solution to fluency. Every method call in .net takes this as the first parameter.  I wonder if the f# compiler could exploit this to allow for pipeling without the need for extension methods?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Luke</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2585</link>
		<dc:creator>Luke</dc:creator>
		<pubDate>Fri, 04 Sep 2009 17:58:45 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2585</guid>
		<description>Matthew - 

For the F# code in the last example, you could use:

let rect = 
    RectangleFluent.Create()
      .SetColor(Color.AliceBlue)
      .SetHeight(16)
      .SetLength(16)</description>
		<content:encoded><![CDATA[<p>Matthew &#8211; </p>
<p>For the F# code in the last example, you could use:</p>
<p>let rect =<br />
    RectangleFluent.Create()<br />
      .SetColor(Color.AliceBlue)<br />
      .SetHeight(16)<br />
      .SetLength(16)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mauricio Scheffer</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2580</link>
		<dc:creator>Mauricio Scheffer</dc:creator>
		<pubDate>Fri, 04 Sep 2009 13:23:00 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2580</guid>
		<description>Fluent interfaces in F# is a whole different game and most C#/VB fluent interfaces break (lose their fluency) on F#.

&lt;a href=&quot;http://bugsquash.blogspot.com/2009/04/using-windsor-in-f.html&quot; rel=&quot;nofollow&quot;&gt;I&#039;ve written a blog post about it&lt;/a&gt; a couple of months ago.</description>
		<content:encoded><![CDATA[<p>Fluent interfaces in F# is a whole different game and most C#/VB fluent interfaces break (lose their fluency) on F#.</p>
<p><a href="http://bugsquash.blogspot.com/2009/04/using-windsor-in-f.html" rel="nofollow">I&#8217;ve written a blog post about it</a> a couple of months ago.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Horsfield</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2579</link>
		<dc:creator>Steve Horsfield</dc:creator>
		<pubDate>Fri, 04 Sep 2009 10:16:41 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2579</guid>
		<description>Looks like the indentations were lost.  You will need to indent the type and module definitions to allow the code to compile.</description>
		<content:encoded><![CDATA[<p>Looks like the indentations were lost.  You will need to indent the type and module definitions to allow the code to compile.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Horsfield</title>
		<link>http://blog.matthewdoig.com/?p=174&#038;cpage=1#comment-2577</link>
		<dc:creator>Steve Horsfield</dc:creator>
		<pubDate>Fri, 04 Sep 2009 10:08:20 +0000</pubDate>
		<guid isPermaLink="false">http://blog.matthewdoig.com/?p=174#comment-2577</guid>
		<description>Hi Matthew,

I think the reason that fluent APIs look ugly in F# is that they do not follow the functional paradigm.  For example, you cannot easily compose functions using them.  My solution has been to create static extension methods that wrap the API (fluent or not) and return the object.  I will be demonstrating this approach with WPF on my blog soon (the code is done for that part, but not the supporting material).

I have not found a way round the &#039;.&#039; problem, it does seem an oversight.  Here&#039;s an example using an extension method and a type T:

&lt;code&gt;
type T() =
  member s.get() = () ; s

module Extension =
  type T with
    static member Get (s:T) = s.get()
&lt;/code&gt;

Then you can write:

&lt;code&gt;
   (T()) 
&#124;&gt; T.Get
&#124;&gt; T.Get
&lt;/code&gt;

And also (T.Get &gt;&gt; T.Get) is a valid function.

However, it is a pain to write all those extension methods.

The middle ground is to write short &quot;let&quot; statements:

&lt;code&gt;
let x1 = new T()
let x2 = x1.get()
let x3 = x2.get()
x3
&lt;/code&gt;

That is a bit extra code but it has a consistent structure, is strongly typed for the debugger at each step and is nicely formatted.  Of course, you can batch statements too:

&lt;code&gt;
let x1 = new T()
let x2 = x1.get().get().get().get()
let x3 = x2.get().get().get()
x3
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Hi Matthew,</p>
<p>I think the reason that fluent APIs look ugly in F# is that they do not follow the functional paradigm.  For example, you cannot easily compose functions using them.  My solution has been to create static extension methods that wrap the API (fluent or not) and return the object.  I will be demonstrating this approach with WPF on my blog soon (the code is done for that part, but not the supporting material).</p>
<p>I have not found a way round the &#8216;.&#8217; problem, it does seem an oversight.  Here&#8217;s an example using an extension method and a type T:</p>
<p><code><br />
type T() =<br />
  member s.get() = () ; s</p>
<p>module Extension =<br />
  type T with<br />
    static member Get (s:T) = s.get()<br />
</code></p>
<p>Then you can write:</p>
<p><code><br />
   (T())<br />
|&gt; T.Get<br />
|&gt; T.Get<br />
</code></p>
<p>And also (T.Get &gt;&gt; T.Get) is a valid function.</p>
<p>However, it is a pain to write all those extension methods.</p>
<p>The middle ground is to write short &#8220;let&#8221; statements:</p>
<p><code><br />
let x1 = new T()<br />
let x2 = x1.get()<br />
let x3 = x2.get()<br />
x3<br />
</code></p>
<p>That is a bit extra code but it has a consistent structure, is strongly typed for the debugger at each step and is nicely formatted.  Of course, you can batch statements too:</p>
<p><code><br />
let x1 = new T()<br />
let x2 = x1.get().get().get().get()<br />
let x3 = x2.get().get().get()<br />
x3<br />
</code></p>
]]></content:encoded>
	</item>
</channel>
</rss>
