<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx</link><description>Yes, it has happened again . This time, our fabulous C# Community Program Manager Charlie Calvert was good enough to put together a little half-hour-long video of me talking about the scenarios which justify changes to the type inference algorithm for</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1095030</link><pubDate>Fri, 17 Nov 2006 21:53:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1095030</guid><dc:creator>barrkel</dc:creator><description>&lt;p&gt;Very interesting indeed. It looks like the compiler will have to be very liberal in what it accepts while parsing expressions and statements inside lambda expressions, since it won't have the type information during the recursive descent (thinking of the SSCLI C# compiler).&lt;/p&gt;
&lt;p&gt;I wonder if there's a whole duplicate parser for this less common case of parsing lambdas, or if the parser is now as late-typed (relatively) when parsing all expressions.&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1095343</link><pubDate>Fri, 17 Nov 2006 23:14:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1095343</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;The body of an expression lambda must be an expression, period, and the body of a statement lambda must be a block of statements. &amp;nbsp;This is the same grammar that the parser uses any other time it needs to produce an expression or statement block.&lt;/p&gt;
&lt;p&gt;I don't understand what you mean by &amp;quot;late typed&amp;quot;. &amp;nbsp;The grammar of the language is entirely independent from its type system. &amp;nbsp;What is an example of a language where the _parse_ of the language changes based on type information? &amp;nbsp;I am not familiar with any such language.&lt;/p&gt;
&lt;p&gt;I think perhaps you are confusing parsing with &amp;quot;expression binding&amp;quot;, whereby we analyze the existing parse tree for type annotations. &amp;nbsp;Yes, the lambda _expression binding_ code is insanely complicated. &amp;nbsp;It defers type annotating the body of the lambda until information about what delegate type the lambda is being converted to has been determined. &amp;nbsp;Once that happens then we can bind the body and check it for type errors.&lt;/p&gt;
&lt;p&gt;Type inference complicates this matter tremendously, as we must do speculative binds to determine whether particular possible inferences will produce type errors or not. &amp;nbsp;&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1095814</link><pubDate>Sat, 18 Nov 2006 00:49:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1095814</guid><dc:creator>barrkel</dc:creator><description>&lt;p&gt;Sorry - didn't make myself clear. Problem with making off-the-cuff comments on a blog.&lt;/p&gt;
&lt;p&gt;By late typed, I meant that, when constructing the AST (during parsing), the compiler doesn't have access to the type info of the symbols represented by identifier tokens, since the argument types are inferred later. I wasn't referring to dynamic typing or anything like that.&lt;/p&gt;
&lt;p&gt;Re language where the parse of the language changes based on type info: the Delphi language does, for one, when parsing structured constants, e.g.:&lt;/p&gt;
&lt;p&gt;---8&amp;lt;---&lt;/p&gt;
&lt;p&gt;type&lt;/p&gt;
&lt;p&gt; &amp;nbsp;TRecord = record&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;x: Integer;&lt;/p&gt;
&lt;p&gt; &amp;nbsp;end;&lt;/p&gt;
&lt;p&gt;const&lt;/p&gt;
&lt;p&gt; &amp;nbsp;x = 12;&lt;/p&gt;
&lt;p&gt; &amp;nbsp;a: TRecord = (x : 42);&lt;/p&gt;
&lt;p&gt; &amp;nbsp;b: Integer = (x + 42);&lt;/p&gt;
&lt;p&gt;---&amp;gt;8---&lt;/p&gt;
&lt;p&gt;Of course, one could construct a sufficiently vague grammar so that this could be accommodated, but the parser is LL(2) and uses type information from the declared type of the constant to parse the constant expression on the right of the '='. There are other situations where similar things happen, esp. with parsing arguments to funcs/procs/methods - largely for backward compatibility reasons after language features have been added down the years.&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1095990</link><pubDate>Sat, 18 Nov 2006 01:17:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1095990</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;Interesting! &amp;nbsp;Next time I see Anders I'll ask him about that. &amp;nbsp;&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1097015</link><pubDate>Sat, 18 Nov 2006 02:34:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1097015</guid><dc:creator>Wesner Moise</dc:creator><description>&lt;p&gt;The notion of using rounds of inference seems a bit kludgy. &lt;/p&gt;
&lt;p&gt;The inferencing abilities of C# 2.0 are very weak, and C# 3.0 seems to be headed towards another complicated approach which is still not general.&lt;/p&gt;
&lt;p&gt;Have you considered a backtracking, unification-based algorithm like the Hindley-Milner type inference algorithm? This is the approach that I used which has a very simple implementation but which is also fully general.&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1179560</link><pubDate>Fri, 01 Dec 2006 00:49:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1179560</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;Wesner, I passed your concerns on to the language design team. Their reply was basically that:&lt;/p&gt;
&lt;p&gt;The problems with the hindley-milner algorithm are (a) the classic H-M algorithm handles subtyping and variance poorly, and (b) backtracking algorithms have potentially bad worst-case running times. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;We already have some contravariance, covariance and invariance in the type system and we would like to have an algorithm which handles those well. &amp;nbsp;We also have come up with an algorithm which is guaranteed to be linear in terms of number of formal parameters + number of method type arguments. &amp;nbsp;(Every round we either eliminate a formal parameter from future consideration or fix a type argument, and we'll eventually run out of one of them, at which point inference is known to either succeed or fail.)&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1235595</link><pubDate>Fri, 08 Dec 2006 02:44:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1235595</guid><dc:creator>Tomas Petricek</dc:creator><description>&lt;p&gt;Hi, thanks for the great video :-). It seems that I discovered it a bit late, but here is what comes to my mind after watching it.&lt;/p&gt;
&lt;p&gt;FIRST THING&amp;gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;It looks to me that the third - probably the most controversial step of algorithm was added because this behavior is needed in the LINQ joins (however there may be some other problems not mentioned in the video...). When I write the query &amp;quot;by hand&amp;quot; using extension methods I wouldn't mind having to write the type cast explicitly. Something like:&lt;/p&gt;
&lt;p&gt;... = Join(customers, orders, c =&amp;gt; (int?)c.ID, o =&amp;gt; (int?)o.ID, (c, o) = new { ... });&lt;/p&gt;
&lt;p&gt;In this case your inference algorithm doesn't need the third step (if I understand it correclty :-)). However I understand that this isn't acceptable syntax for writing LINQ queries. For the queries I would suggest adding something like &amp;quot;outer join&amp;quot; clause that would be translated to the previous code (= it would add the type cast to T? from T which is inferred from lambda). You could than write the follwoing:&lt;/p&gt;
&lt;p&gt;from c in customers&lt;/p&gt;
&lt;p&gt; &amp;nbsp;outer join o in orders on o.ID equals c.ID&lt;/p&gt;
&lt;p&gt; &amp;nbsp;select ..&lt;/p&gt;
&lt;p&gt;//in this case nullable types can be used&lt;/p&gt;
&lt;p&gt;from c in customers&lt;/p&gt;
&lt;p&gt; &amp;nbsp;join o in orders on o.ID equals c.ID&lt;/p&gt;
&lt;p&gt; &amp;nbsp;select ..&lt;/p&gt;
&lt;p&gt;//no nullable types allowed here&lt;/p&gt;
&lt;p&gt;This could solve the problem without adding too much complexity into the algorithm, but still allowing the most important scenario. Did you discuss solution like this? Are there any additional issues?&lt;/p&gt;
&lt;p&gt;SECOND THING&amp;gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;Thanks for adding the second algorithm step! This scenario is very important (IMHO) because it makes it possible to declare lambda/expression tree with anonymous type as local variable:&lt;/p&gt;
&lt;p&gt;var lambda = DeclareLambda(c =&amp;gt; new { c.Something });&lt;/p&gt;
&lt;p&gt;var tree = DeclareTree(c =&amp;gt; new { c.Something });&lt;/p&gt;
&lt;p&gt;// where DeclareLambda is:&lt;/p&gt;
&lt;p&gt;Func&amp;lt;A, T&amp;gt; DeclareLambda&amp;lt;A, T&amp;gt;(Func&amp;lt;A,T&amp;gt; foo) { return foo; }&lt;/p&gt;
&lt;p&gt;// DeclareTree is similar...&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1686094</link><pubDate>Fri, 16 Feb 2007 02:28:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1686094</guid><dc:creator>JohnF</dc:creator><description>&lt;p&gt;The link is broken. &amp;nbsp;Is this video still available somewhere? &amp;nbsp;&lt;/p&gt;
</description></item><item><title>Community Convergence XII</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1733433</link><pubDate>Wed, 21 Feb 2007 09:52:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1733433</guid><dc:creator>Charlie Calvert's Community Blog</dc:creator><description>&lt;p&gt;Welcome to the twelfth Community Convergence . Please go here to post comments. This edition of Community&lt;/p&gt;
</description></item><item><title>Charlie Calvert's Technical Blog Index</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1733497</link><pubDate>Wed, 21 Feb 2007 10:13:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1733497</guid><dc:creator>Charlie Calvert's Community Blog</dc:creator><description>&lt;p&gt;This is index to the various technical posts I have created for this blog. As I add to each section,&lt;/p&gt;
</description></item><item><title>February CTP Now Available</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#1776458</link><pubDate>Thu, 01 Mar 2007 03:45:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1776458</guid><dc:creator>Charlie Calvert's Community Blog</dc:creator><description>&lt;p&gt;The February CTP (aka as the March CTP) is now available for download as a regular install and as a virtual&lt;/p&gt;
</description></item><item><title>Videos</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#3409316</link><pubDate>Tue, 19 Jun 2007 21:22:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3409316</guid><dc:creator>Charlie Calvert's Community Blog</dc:creator><description>&lt;p&gt;I'm trying to pull together lists of available C# videos. I'll be working on this list over time, but&lt;/p&gt;
</description></item><item><title>re: A Face Made For Email, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#5322449</link><pubDate>Sat, 06 Oct 2007 23:47:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5322449</guid><dc:creator>markovich</dc:creator><description>&lt;p&gt;The link is broken. &amp;nbsp;Is this video still available somewhere? &amp;nbsp;&lt;/p&gt;
</description></item><item><title>Anders Hejlsberg Film Festival: The C# and other VSL Teams at the Movies</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx#8343037</link><pubDate>Sat, 29 Mar 2008 09:09:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8343037</guid><dc:creator>Charlie Calvert's Community Blog</dc:creator><description>&lt;p&gt;It's a bit rainy and snowy today in Redmond. What an excellent time to curl up by the fire and watch&lt;/p&gt;
</description></item></channel></rss>