<?xml version="1.0" encoding="utf-8"?><!-- generator="wordpress/1.5.1.3" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: F# compiler considered too linear</title>
	<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/</link>
	<description>General musings and programming stuff</description>
	<pubDate>Mon, 08 Sep 2008 14:10:07 +0000</pubDate>
	<generator>http://wordpress.org/?v=1.5.1.3</generator>

	<item>
		<title>by: Jon Harrop</title>
		<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166814</link>
		<pubDate>Thu, 22 May 2008 12:28:43 +0000</pubDate>
		<guid>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166814</guid>
					<description>&amp;#34;What does the F# user gain from the ordering requirement?&amp;#34;

Good question. The answer is reliability. The linearity that has been observed here allows this family of languages to enforce a well-defined order of evaluation on the entire program and that is absolutely essential for value-based (rather than class based) languages like F#. The ad-hoc evaluation order that Oliver is advocating is even completely prohibited in many languages from the ML family. The F# compiler will actually let you do this but it emits a warning because this is a dangerous practice.

In fact, if Oliver's last code snippet did compile it would be an infinite loop, with the constructors invoking each other indefinitely. I suspect the desired functionality was to construct two mutually-dependent objects simultaneously but that requires the manipulation of partially constructed objects. If either construction sequence contains side-effects (as is the case here because constructing ClassA invokes DoSomethingInB that prints to the console) then the evaluation order of these statements is undefined and the program becomes non-deterministic.

Having said that, my proposed idiomatic-OCaml solution does not work in F# as Oliver noted. The reason is that OCaml has structurally-typed objects so it can infer classes whereas F# requires class types to be explicitly declared beforehand (just like a header file).

Finally, regarding the Solution Explorer in Visual Studio for F#, I agree completely that the current implementation is dreadful. The F# team are completely rewriting the VS mode and, hopefully, the new version will make it into the CTP this summer. My personal opinion is that the VS mode is by far the weakest point of the current F# distro.</description>
		<content:encoded><![CDATA[	<p>&quot;What does the F# user gain from the ordering requirement?&quot;</p>
	<p>Good question. The answer is reliability. The linearity that has been observed here allows this family of languages to enforce a well-defined order of evaluation on the entire program and that is absolutely essential for value-based (rather than class based) languages like F#. The ad-hoc evaluation order that Oliver is advocating is even completely prohibited in many languages from the ML family. The F# compiler will actually let you do this but it emits a warning because this is a dangerous practice.</p>
	<p>In fact, if Oliver&#8217;s last code snippet did compile it would be an infinite loop, with the constructors invoking each other indefinitely. I suspect the desired functionality was to construct two mutually-dependent objects simultaneously but that requires the manipulation of partially constructed objects. If either construction sequence contains side-effects (as is the case here because constructing ClassA invokes DoSomethingInB that prints to the console) then the evaluation order of these statements is undefined and the program becomes non-deterministic.</p>
	<p>Having said that, my proposed idiomatic-OCaml solution does not work in F# as Oliver noted. The reason is that OCaml has structurally-typed objects so it can infer classes whereas F# requires class types to be explicitly declared beforehand (just like a header file).</p>
	<p>Finally, regarding the Solution Explorer in Visual Studio for F#, I agree completely that the current implementation is dreadful. The F# team are completely rewriting the VS mode and, hopefully, the new version will make it into the CTP this summer. My personal opinion is that the VS mode is by far the weakest point of the current F# distro.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Oliver Sturm</title>
		<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166210</link>
		<pubDate>Wed, 21 May 2008 18:32:35 +0000</pubDate>
		<guid>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166210</guid>
					<description>Michael - thanks for making my point ;-) Though I'm still having a hard time understanding how Generics will even solve my problem. But I'm sure I need to spend more time on it.</description>
		<content:encoded><![CDATA[	<p>Michael - thanks for making my point <img src='http://www.sturmnet.org/blog/wp-images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Though I&#8217;m still having a hard time understanding how Generics will even solve my problem. But I&#8217;m sure I need to spend more time on it.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Michael</title>
		<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166204</link>
		<pubDate>Wed, 21 May 2008 18:02:52 +0000</pubDate>
		<guid>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166204</guid>
					<description>Regarding Chance's suggestion to take another look at generics to help with the large hierarchy:

I agree that the human can work around it.  However, I would question why I want a feature in the language that requires a human to rewrite an otherwise correct type hierarchy when introducing a cycle in the type dependency.  This makes it much more difficult to predict the cost of making a change--the cost could vary by more than an order of magnitude depending on whether the change introduces a cycle or not.

What does the F# user gain from the ordering requirement?</description>
		<content:encoded><![CDATA[	<p>Regarding Chance&#8217;s suggestion to take another look at generics to help with the large hierarchy:</p>
	<p>I agree that the human can work around it.  However, I would question why I want a feature in the language that requires a human to rewrite an otherwise correct type hierarchy when introducing a cycle in the type dependency.  This makes it much more difficult to predict the cost of making a change&#8211;the cost could vary by more than an order of magnitude depending on whether the change introduces a cycle or not.</p>
	<p>What does the F# user gain from the ordering requirement?
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Oliver Sturm</title>
		<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166075</link>
		<pubDate>Wed, 21 May 2008 10:32:39 +0000</pubDate>
		<guid>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166075</guid>
					<description>Hi Jon,

Thanks for your comment. I have to admit though that I don't have the first clue how your suggestion is supposed to work in reality... I wrote this little piece of code to model what you said:

&lt;pre&gt;
type ClassA&amp;#60;'b when 'b : (new : unit -&amp;#62; 'b)&amp;#62;() = 
    let foo = new 'b()
    let test() = 
        foo.DoSomethingInB()
    
type ClassB&amp;#60;'a when 'a : (new : unit -&amp;#62; 'a)&amp;#62;() = 
    let foo = new 'a()
    member x.DoSomethingInB() = printfn &amp;#34;Doing something&amp;#34;

let classA = new ClassA&amp;#60;ClassB&amp;#62;();
&lt;/pre&gt;    

Now, there are two major problems with it:

&lt;ol&gt;
&lt;li&gt;The final line doesn't compile, because ClassB on its own isn't accepted - after all it's ClassB&amp;#60;'a&amp;#62;. So this results in an endless ClassA&amp;#60;ClassB&amp;#60;ClassA&amp;#60;ClassB&amp;#60;.... chain, which I have no idea how to resolve.
&lt;/li&gt;&lt;li&gt;The line foo.DoSomethingInB() doesn't compile, because it makes assumptions about 'b that the compiler can't check. I would have to use a type annotation to make the compiler understand which type(s) I'm expecting, and that in turn would reintroduce the dependency I'm trying to get rid of. I don't see how there's a way around this if I'm ever going to do anything meaningful with the classes I depend on.
&lt;/li&gt;&lt;/ol&gt;

Theoretically, your idea is interesting. While we don't support these generic class structures in our library right now, it would be possible to extend without introducing a dependency to F# into our code. But I just don't see how this should work, since especially (2) above seems to be a general problem with the approach. If you know what the solution is, perhaps you could remodel my little sample above so that it works?

Thanks
Oliver</description>
		<content:encoded><![CDATA[	<p>Hi Jon,</p>
	<p>Thanks for your comment. I have to admit though that I don&#8217;t have the first clue how your suggestion is supposed to work in reality&#8230; I wrote this little piece of code to model what you said:</p>
	<pre>
type ClassA&lt;'b when 'b : (new : unit -&gt; 'b)&gt;() =
    let foo = new 'b()
    let test() =
        foo.DoSomethingInB()
	
type ClassB&lt;'a when 'a : (new : unit -&gt; 'a)&gt;() =
    let foo = new 'a()
    member x.DoSomethingInB() = printfn &quot;Doing something&quot;
	
let classA = new ClassA&lt;ClassB&gt;();
</pre>
	<p>Now, there are two major problems with it:</p>
	<ol>
	<li>The final line doesn&#8217;t compile, because ClassB on its own isn&#8217;t accepted - after all it&#8217;s ClassB&lt;&#8217;a&gt;. So this results in an endless ClassA&lt;ClassB&lt;ClassA&lt;ClassB&lt;&#8230;. chain, which I have no idea how to resolve.
</li>
	<li>The line foo.DoSomethingInB() doesn&#8217;t compile, because it makes assumptions about &#8216;b that the compiler can&#8217;t check. I would have to use a type annotation to make the compiler understand which type(s) I&#8217;m expecting, and that in turn would reintroduce the dependency I&#8217;m trying to get rid of. I don&#8217;t see how there&#8217;s a way around this if I&#8217;m ever going to do anything meaningful with the classes I depend on.
</li>
</ol>
	<p>Theoretically, your idea is interesting. While we don&#8217;t support these generic class structures in our library right now, it would be possible to extend without introducing a dependency to F# into our code. But I just don&#8217;t see how this should work, since especially (2) above seems to be a general problem with the approach. If you know what the solution is, perhaps you could remodel my little sample above so that it works?</p>
	<p>Thanks<br />
Oliver
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Oliver Sturm</title>
		<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166074</link>
		<pubDate>Wed, 21 May 2008 10:15:09 +0000</pubDate>
		<guid>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-166074</guid>
					<description>Hi Chance,

You are right - renaming the files actually does change the order in the project! Unbelievable, that's ridiculous. You know, if the order was entirely unimportant, then this wouldn't matter. But seeing how the order is in fact extremely important for all the reasons I've listed above, this is a major issue.

Oliver</description>
		<content:encoded><![CDATA[	<p>Hi Chance,</p>
	<p>You are right - renaming the files actually does change the order in the project! Unbelievable, that&#8217;s ridiculous. You know, if the order was entirely unimportant, then this wouldn&#8217;t matter. But seeing how the order is in fact extremely important for all the reasons I&#8217;ve listed above, this is a major issue.</p>
	<p>Oliver
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Jon Harrop</title>
		<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-165806</link>
		<pubDate>Wed, 21 May 2008 01:42:58 +0000</pubDate>
		<guid>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-165806</guid>
					<description>Your problem with large sets of mutually-recursive classes can be overcome by parameterizing the classes over their dependencies. You have probably not considered this before because it is too tedious and error-prone in C#.

Consider the mutually recursive type definition:

type stuff = Stuff of things
and things = Things of stuff

Rewrite it like this:

type 'a stuff = Stuff of 'a

type 'a things = Things of 'a

This idiomatic functional approach is sometimes called &amp;#34;untying the recursive knot&amp;#34; and it allows you to split any definitions (type or value) across any boundaries you like (e.g. source files or even DLLs).</description>
		<content:encoded><![CDATA[	<p>Your problem with large sets of mutually-recursive classes can be overcome by parameterizing the classes over their dependencies. You have probably not considered this before because it is too tedious and error-prone in C#.</p>
	<p>Consider the mutually recursive type definition:</p>
	<p>type stuff = Stuff of things<br />
and things = Things of stuff</p>
	<p>Rewrite it like this:</p>
	<p>type &#8216;a stuff = Stuff of &#8216;a</p>
	<p>type &#8216;a things = Things of &#8216;a</p>
	<p>This idiomatic functional approach is sometimes called &quot;untying the recursive knot&quot; and it allows you to split any definitions (type or value) across any boundaries you like (e.g. source files or even DLLs).
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Chance Coble</title>
		<link>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-165758</link>
		<pubDate>Wed, 21 May 2008 00:20:30 +0000</pubDate>
		<guid>http://www.sturmnet.org/blog/archives/2008/05/20/f-compiler-considered-too-linear/#comment-165758</guid>
					<description>In order to change the ordering of files in a Visual Studio project all you have to do is rename the file in the solution explorer. That will drop it to the last position in the project (have only tested this in 2005).  It should still be supported directly, and I am sure it will be.  But for the time being that is a decent work around.

As to the interrelated class problem, I am surprised to read that it is such an issue.  We have been using F# for over a year now at my company and have only run into what you describe in a few GUI related instances.  I would recommend taking another look at generics to help you with the large hierarchy.  In a language like F#, polymorphism like .NET's generics often proves superior to runtime polymorphism with class hierarchies.</description>
		<content:encoded><![CDATA[	<p>In order to change the ordering of files in a Visual Studio project all you have to do is rename the file in the solution explorer. That will drop it to the last position in the project (have only tested this in 2005).  It should still be supported directly, and I am sure it will be.  But for the time being that is a decent work around.</p>
	<p>As to the interrelated class problem, I am surprised to read that it is such an issue.  We have been using F# for over a year now at my company and have only run into what you describe in a few GUI related instances.  I would recommend taking another look at generics to help you with the large hierarchy.  In a language like F#, polymorphism like .NET&#8217;s generics often proves superior to runtime polymorphism with class hierarchies.
</p>
]]></content:encoded>
				</item>
</channel>
</rss>
