<?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>Yet Another Language Geek : Scheme</title><link>http://blogs.msdn.com/wesdyer/archive/tags/Scheme/default.aspx</link><description>Tags: Scheme</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Thus Quoth the Humble Programmer</title><link>http://blogs.msdn.com/wesdyer/archive/2006/12/22/thus-quoth-the-humble-programmer.aspx</link><pubDate>Sat, 23 Dec 2006 02:20:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1349791</guid><dc:creator>wesdyer</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1349791.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1349791</wfw:commentRss><description>&lt;p&gt;I love Scheme!&amp;nbsp; It is such a beautiful language.&amp;nbsp; I was first introduced to it during college.&amp;nbsp; At that time, I thought it was an interesting language but I didn't see the power of the language until later.&amp;nbsp; That moment came when I experienced reading &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book.html"&gt;The Structure and Interpretation of Computer Programs&lt;/a&gt;.&amp;nbsp; It was a great joy to read the text and work through the exercises.&amp;nbsp; But the most fulfilling part was thinking about what it all meant.&amp;nbsp; I definitely encourage anyone who wants to expand their mind to read this wonderful text.&lt;/p&gt; &lt;p&gt;&lt;a onclick="return amz_js_PopWin('http://www.amazon.com/gp/product/images/0262011530/ref=dp_image_0/002-7913622-5508035?ie=UTF8&amp;amp;n=283155&amp;amp;s=books','AmazonHelp','width=700,height=600,resizable=1,scrollbars=1,toolbar=0,status=1');" href="http://www.amazon.com/gp/product/images/0262011530/ref=dp_image_0/002-7913622-5508035?ie=UTF8&amp;amp;n=283155&amp;amp;s=books" target="AmazonHelp"&gt;&lt;img id="prodImage" height="240" alt="Structure and Interpretation of Computer Programs - 2nd Edition (MIT Electrical Engineering and Computer Science)" src="http://ec1.images-amazon.com/images/P/0262011530.01._AA240_SCLZZZZZZZ_.jpg" width="240" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Quoting in Scheme&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Scheme&amp;nbsp;(or any other LISP dialect)&amp;nbsp;allows programmers&amp;nbsp;to&amp;nbsp;define variables, define lambdas, and evaluate expressions (I know that I am greatly simplifying here).&amp;nbsp; But one feature that is particularly interesting is the ability to quote.&amp;nbsp; Quoting an expression causes the expression not be evaluated but instead to return the structure of the expression.&amp;nbsp; For example (line numbers added for discussion purposes):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;1:&amp;nbsp;&amp;nbsp;&amp;nbsp; (define f1 (lambda (x y) (+ x y)))&lt;br&gt;2:&amp;nbsp;&amp;nbsp;&amp;nbsp; f1&lt;br&gt;3:&amp;nbsp;&amp;nbsp;&amp;nbsp; (define e (quote (lambda (x y) (+ x y))))&lt;br&gt;4:&amp;nbsp;&amp;nbsp;&amp;nbsp; e&lt;br&gt;5:&amp;nbsp;&amp;nbsp;&amp;nbsp; (define f2 (eval e))&lt;br&gt;6:&amp;nbsp;&amp;nbsp;&amp;nbsp; (f1 3 4)&lt;br&gt;7:&amp;nbsp;&amp;nbsp;&amp;nbsp; (f2 3 4)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This program produces the following results. &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;#&amp;lt;procedure:f1&amp;gt;&lt;br&gt;(lambda (x y) (+ x y))&lt;br&gt;7&lt;br&gt;7&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Line number 1 defines a variable f1 to be the result of evaluating a lambda expression, thus f1 is a function.&amp;nbsp; Line 2 evaluates f1 which simply returns the function.&amp;nbsp; Line 3 defines e to be the result of evaluating the quote of the same lambda expression that appeared in line 1.&amp;nbsp; But now e is &lt;em&gt;not &lt;/em&gt;a function but rather a structure describing the lambda.&amp;nbsp; Line 4 evaluates e, which displays the structure it references.&amp;nbsp; Line 5 defines a variable f2 to be the result of apply eval to e.&amp;nbsp; Eval runs the Scheme interpreter on its arguments.&amp;nbsp; Recall, that e is a structure describing a lambda.&amp;nbsp; So applying eval to e we get a lambda and so f2 is now a function described by this lambda.&amp;nbsp; Finally, on lines 6 and 7 we apply f1 and f2 respectively to arguments 3 and 4.&amp;nbsp; Since they are both functions that correspond to the same lambda structure we expect to get the same results and indeed we do. &lt;p&gt;&lt;strong&gt;Quoting in C#&lt;/strong&gt; &lt;p&gt;With C# 3.0 we can do essentially the same thing (again line numbers added for discussion purposes). &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;1:&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;int, int, int&amp;gt; f1 = (x, y) =&amp;gt; x + y;&lt;br&gt;2:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(f1);&lt;br&gt;3:&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression&amp;lt;Func&amp;lt;int, int, int&amp;gt;&amp;gt; e = (x, y) =&amp;gt; x + y;&lt;br&gt;4:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(e);&lt;br&gt;5:&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;int, int, int&amp;gt; f2 = e.Compile();&lt;br&gt;6:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(f1(3, 4));&lt;br&gt;7:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(f2(3, 4));&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This program displays the following: &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;System.Linq.Func`3[System.Int32,System.Int32,System.Int32]&lt;br&gt;(x, y) =&amp;gt; (x + y)&lt;br&gt;7&lt;br&gt;7&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Notice how remarkably similar both the programs and that outputs are.&amp;nbsp; Again, on line 1 we define a delegate to be the result of evaluating a lambda expression.&amp;nbsp; On line 2, we display this delegate.&amp;nbsp; On line 3, we assign e the result of evaluating a lambda expression.&amp;nbsp; Notice that in C# both assignments (lines&amp;nbsp;1 and 3)&amp;nbsp;look the same except for the type of the variable to which the lambda is assigned.&amp;nbsp; Lambdas can be converted either to delegates or to expression trees depending on the usage.&amp;nbsp; Delegates can be invoked while expression trees preserve the structure of the lambda.&amp;nbsp; On line 4, we display the expression tree for e which corresponds to the structure of the lambda.&amp;nbsp; On line 5, we do the equivalent of the eval in Scheme by compiling the expression tree structure to a delegate.&amp;nbsp; We can now invoke f2 like we can invoke f1.&amp;nbsp; On lines 6 and 7, we invoke these two delegates and display their results. &lt;p&gt;&lt;strong&gt;So What?&lt;/strong&gt; &lt;p&gt;While this is all very remarkable, it may seem a bit esoteric.&amp;nbsp; Why take the trouble to have a variable with a value that corresponds to the structure of a lambda and then convert that to an invocable form?&amp;nbsp; Why not just always create the delegate immediately?&amp;nbsp; The reason is with the expression tree form of the lambda, we can reason about the structure and then take action on it.&amp;nbsp; Consider queries.&amp;nbsp; When a query is translated it creates a number of lambdas, but one of the key questions is: Are those lambdas then converted to delegates or expression trees?&amp;nbsp; For example: &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = from x in foo&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;where x &amp;gt; 1&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select x + 1;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This is &lt;a href="http://blogs.msdn.com/wesdyer/archive/2006/12/21/comprehending-comprehensions.aspx"&gt;translated&lt;/a&gt; to: &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = foo.Where(x =&amp;gt; x &amp;gt; 1)&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Select(x =&amp;gt; x + 1);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/wesdyer/archive/2006/12/21/comprehending-comprehensions.aspx"&gt;We have already discussed&lt;/a&gt; that which "Where" and "Select" methods are called depends upon what the type of foo is and which extension methods are in scope.&amp;nbsp; If the "Where" and "Select" methods take a delegate then the lambdas will be converted to delegates; however, if they take an expression tree then the lambdas are converted to expression trees instead.&amp;nbsp; So a LINQ provider (or someone who has implemented the query pattern methods like "Where" and "Select") can choose whether they would like the lambdas in delegate or expression tree form.&amp;nbsp; Now lets look at a few providers and see what they do.&amp;nbsp; LINQ to objects (or the in-memory query operators that apply to IEnumerable&amp;lt;T&amp;gt;) take delegates.&amp;nbsp; This is because they will invoke the delegates to do things like evaluate predicates or projections.&amp;nbsp; However, LINQ to SQL&amp;nbsp;on the other hand takes expression trees.&amp;nbsp; It does not "invoke" the lambdas but instead reasons over the structure of the lambdas and then translates the expression trees to equivalent SQL code given a schema for a database.&amp;nbsp; This is the beauty of the LINQ pattern. &lt;p&gt;Adding the ability to quote lambdas enables all sorts of possiblities.&amp;nbsp; You might easily imagine other uses for expression trees: remoting evaluation of expressions, query planning, executing them on a GPU, .... &lt;p&gt;What can you think of doing?&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1349791" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Queries/default.aspx">Queries</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Scheme/default.aspx">Scheme</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Lambdas/default.aspx">Lambdas</category></item></channel></rss>