InfoQ

Interview

Recorded at:
Recorded at

Erik Meijer on LINQ

Interview with Erik Meijer by Sadek Drobi on Mar 04, 2009

Community
.NET
Topics
Programming ,
Data Access
Tags
LINQ ,
Haskell ,
QCon San Francisco 2008 ,
Functional Programming
Summary
In this interview filmed during QCon SF 2008, Erik Meijer talks about less known LINQ features, like the ability to do meta programming or the fact that LINQ works against any data collection that implements the sequence operators. Meijer also talks about the differences between functional languages and objectual ones, asynchronous computation, and the evolution of languages.

Bio
Erik Meijer is the creator of LINQ at MS, where he works together with the Microsoft Visual C# and the Microsoft Visual Basic language design teams on data integration in programming languages. Erik has participated in designing several languages: Haskell98, Mondrian, X#, Cω, C#, and Visual Basic.

About the conference
QCon is a conference that is organized by the community, for the community.The result is a high quality conference experience where a tremendous amount of attention and investment has gone into having the best content on the most important topics presented by the leaders in our community.QCon is designed with the technical depth and enterprise focus of interest to technical team leads, architects, and project managers.
I'm Sadek Drobi, I'm here at QCon San Francisco, with Erik Meijer. Erik is the father of LINQ and he is known as "the Banana guy" for his huge contribution to functional programming and research. Erik, for those who still don't know you, can you introduce yourself and tell us what you've been working on?
You worked a lot on the LINQ project and it got released a year ago. Are you satisfied with what you've done in C#, in VB, what you actually introduced in the .NET platform?
C# and VB have considerably a lot of syntax - some people say it's because of the lack of some powerful abstraction concepts - like in Haskell, type classes or type constructs. Don't you feel sometimes frustrated that each time you want to add something you have to go to the compiler guys and ask them to add more syntax, whereas in Haskell it could be easier or more powerful?
But, for example, there are some things you've been implementing, like when you've been implementing LINQ, you could just say "I need type class here". What you did instead was to introduce extension methods, for example. One difference between them is that you can actually define implementation of type classes after the design time of some type, which is not true for interfaces. Interfaces, you have to implement them inside the class whereas type classes you can extend later. It's like you have just discovered "I don't have this. What should I do?"
Also for LINQ, the team added "select from" and "where" constructs of the language - some syntax. Some people call it monadic syntax - the same syntax we use for monads. Some people try to use it in other things than list comprehensions and states. Do you see other uses of these - "select from" and "where"?
In Microsoft, are they trying to implement other monads in .NET? For example for Volta or for Continuation, whatever it is?
In functional programming languages, a function is just a value that has a type. It's the same thing like an int and string. Based on that, don't you think, for example, we can just omit or remove methods from C# and VB and replace them by properties that have a function return type because we have the function type in C#. Can't we just remove methods and use properties of function type?
Now we introduced lambdas and LINQ. Don't you think that there are some features in C# or some syntax that we have just to decide to delete actually, like using keywords and syntax that today we can implement them as functions and high order functions? Don't you think that there is a time where we should start just deleting features from the language?
C# and VB are languages that have side effects. Some people have argued that, when effects are predictable, it's OK, we still can deal with that, but when you add to these lazy evaluation and some lazy constructs like delegates, lambdas and enumerators, then you get into a problem, because effects are no more predictable. Don't you think that this is dangerous for big applications, for the enterprise and C# today?
LINQ added some functional programming concepts to .NET languages. Are there any other concepts that you'd like to introduce in mainstream languages?
What do you think of the syntax similarities and the semantics difference? For example, there is Scala today that looks a bit like Java, but it has completely different semantics - same as JavaScript. Some people try to look at it as the same syntax of some languages, yet semantically it's completely different. Developers that used to develop in language A, will go to language B and will do some assumptions that will no longer stand. What do you think of that?
Aren't you interested in implementing the same things on the JVM, that you did on the .NET? For example: LINQ and all the stuff you did in .NET. Are you interested in doing the same thing on the JVM?
I am a C# developer and sometimes, when I develop in C#, I get to some point I say "Oops, it's not inferred anymore"- for example type inference, if I could do carrying here or partial application, or whatever it is. Do you think that it's important to add these concepts to the language like better type inference, the same as it exists in F# or carrying and partial application in the mainstream language?
One of the things that you have mentioned was that a lot of languages that we have today are trapped in this quench of programming. What kinds of abstractions and syntax do you think are going to be good for allowing us to move towards more of a parallel model?
Did you give up on Haskell?
You mentioned notation being very important and of course, LINQ introduces this new syntax "select from" whatever you select and all that. What kind of things can we do to the language to facilitate the creation of things like internal DSLs or other syntax, which - like LINQ - would enable more easy expression of certain concepts, like composition of asynchronous functions, for example?
Let's make the problem a little simpler. We don't want to create new syntax because it's cognitive and overhead - everyone has to learn when they want to work up the code, but from Haskell, we certainly see that introducing monads to constrain function composition and create new computational domains for reasoning about parts of your program, reasoning about the effects that occur in those parts of the program, or reasoning about how distinct computations are composed to achieve the semantics you want. Can we introduce some more limited form into C# , which would allow us to even just say a little more about function composition, so we can create things that are similar to a using statement or an assert statement, or some kind of selection operator like we have from "select" and so on, which really just talk about what happens within the scope of a block, like an F# workflow for example?
With the inclusion of parallel extensions in .NET and trying to make concurrency a little bit easier, say through the async workflows, do you think that's enough? Where do you see similar things going? Because concurrency is hard and some of those abstractions are trying to make it easier, do you see more things like that coming?
show all  show all
More Haskell-y? by Dmitry Tsygankov Posted Mar 4, 2009 9:09 AM
Re: More Haskell-y? by Sadek Drobi Posted Mar 4, 2009 2:50 PM
Re: More Haskell-y? by Dmitry Tsygankov Posted Mar 5, 2009 1:19 AM
Reasons why nobody is ever going to care about Monads in C# by Stefan Wenig Posted Mar 5, 2009 5:38 AM
Re: Reasons why nobody is ever going to care about Monads in C# by Dmitry Tsygankov Posted Mar 12, 2009 9:16 AM
Re: Reasons why nobody is ever going to care about Monads in C# by Stefan Wenig Posted Mar 13, 2009 10:28 PM
Re: Reasons why nobody is ever going to care about Monads in C# by Dmitry Tsygankov Posted Mar 27, 2009 8:10 AM
Re: Reasons why nobody is ever going to care about Monads in C# by Ryan Riley Posted Aug 19, 2009 9:48 AM
  1. Back to top

    More Haskell-y?

    Mar 4, 2009 9:09 AM by Dmitry Tsygankov

    As a C# programmer, I admit that all those features in C# 3.0 like lambdas, extension methods and LINQ are nice. But I would definitely like C# to be more Haskell-y.
    While what Erik Meijer says about "too much of" type inference is true, C# has a long way to go in that direction. Not only does C# conditional operator fail to infer the type if no type was provided, it also fails to infer it when it was explicitly provided in the signature of the method, or in the variable declaration.
    Yes, LINQ is extensible - but due to the nature of extension methods, it's not polymorphic most of the time. Waiting for extension interfaces...
    Yes, LINQ is "almost" monads, but one cannot define an IMonad interface due to the nature of C# generics, see the comments to this blog post for details: blogs.msdn.com/wesdyer/archive/2008/01/11/the-m....
    I find C# operator overloading mechanisms no less confusing than those of Haskell, but much less powerful.
    It is questionable if the non-local return operator mentioned in the talk is worth keeping - it's a goto statement in disguise and I've seen some programs entangled to something unrecognisable by all those return-s and continue-s.
    In fact, there is a design by contract framework for Haskell, it's the QuickCheck testing library - implemented as a library, not a language extension. The tests look like "prop_test args = precondition ==> postcondition" and they are kept separately from the main code, which is a good thing.
    Having said that, I'm not sure if it's easier to write a conventional business application in Haskell than in C#. I'd like to experiment with it but don't see a reasonable opportunity.

  2. Back to top

    Re: More Haskell-y?

    Mar 4, 2009 2:50 PM by Sadek Drobi

    One thing I would like to have is type inference of lambda expressions when possible. Specifying the type of a lambda is very ugly.

  3. Back to top

    Re: More Haskell-y?

    Mar 5, 2009 1:19 AM by Dmitry Tsygankov

    Definitely. And being able to make those lambda expressions generic would be nice. I sometimes use them as local functions but then I have to move them to a separate method.
    I guess all those things - generic variables and generic parameters - correspond to rank-2 polymorphism in Haskell somehow.

  4. 1) It's all but impossible to learn Monads using C#. You'd have to learn them in an FP language and then move that knowledge to C#. That's not going to happen for a whole lot of people.
    2) There are no good explanations. Eric Meijer used to have a paper on his MS Research page that got linked quite a bit, but it's no longer there. The article from Wes Dyer that Dmitry linked to got quoted a lot, but it doesn't even try to explain why anyone should use Monads. (The null propagation? If you get to the core of it, it checks all input parameters for null-ness and then either evaluates the whole select expression - or not. The arithmetic expression itself is not elevated. Quite a lot of noise there, not very impressive. Continuations? Same problem. Now in addition to Monads, I have to go somewhere else, find out what continuations are and what they are there for, come back and try to understand Wes's implementation, and think hard about how I could use LINQ to support real-world scenarios using continuations. Unlikely.)
    3) C#'s syntax is flawed. I like a lot about the way LINQ was integrated via new C# features. But the Func<> delegates kill me, especially when their arguments are generic too. I frequently find myself using some currying-like notation on paper when trying to read stuff like Wes' article.
    4) I don't know a lot about Monads, so I could have that wrong. But I believe that while LINQ is obviously an application of Monads, it just sucks for any amplification that is _not_ IEnumerable. It might be fun to try and use it anyway, but only while you're busy playing with Monads. Who want's to see this in production code?

    I might be wrong, maybe someone comes up with a great paper that shows how to implement some parser using Monads in C# in a way that really makes sense, or something like that. But LINQ has been around for some time, Eric has written and preached his stuff, explained how LINQ is just Monads to the Lambda-the-Ultimate crowd, and nothing happened. Why should that suddenly change?<>


  5. 4) for any amplification that is _not_ IEnumerable.

    Actually, there are some problems even for IEnumerable. I stumbled into one of those today.
    In LINQ framework, there are some 22 independent implementations of IEnumerable.Min extension method, and the same for .Max, .Sum, etc.
    If I have my own number-like class with some operations of addition and negation, I don't get the two overloads of .Sum for free. Instead, I have to implement them by my own, which is a bit annoying and in my case it probably makes the whole idea pointless.
    Now, suppose I'd like to fix that, so that I have one implementation of .Sum I can always use. I could do something like this:
    public static T Sum<T>(this IEnumerable<T> sequence)
    where T : IAdditive<T>
    {
    return sequence.Aggregate((left, right) => left.Plus(right));
    }
    Is that an adequate replacement for IEnumerable<int>.Sum? No, it's not. It doesn't behave the same way for empty sequences. If I want it to behave reasonably, I'll have to fetch the zero value somehow and return it in case of an empty sequence. The problem is I cannot do that! The default(T) gives me null, which is not what I want.
    What I would like to have is something like zero(T), that is, I'd like to have a method that is polymorphic in it's return type. But I can't do that in C#! C# only allows me to have polymorphism of this kind on the first parameter of the method.
    The same thing happens with methods like long.Parse, int.Parse, decimal.Parse, etc. A colleague of mine tried to create a generic Parse method a few days ago, it all ended up with "if (typeof(T) == typeof(int))" etc.
    It's not a big deal, one can always fall back to code duplication and if-else, but those little traps are everywhere!
    Now I have no right to tell anybody that Haskell is the best language in the world for all possible tasks, but the Read and Num type classes are definitely better than what I described here.
    While what Stefan said about syntax and tutorials is definitely true, those problems are not fundamental and can be easily resolved, but a few more fundamental problems exist.</int></t></t></t>

  6. Dmitry,

    some of those problems _could_ be resolved. But this stuff has been here for quite some time now, and nobody seemed to care. Why should that suddenly change?

    Other problems are fundamental. The syntax is so hard to understand that it's actually easier to learn a bit of Haskell in order to get monads than to use your existing C# knowledge. At least that's my opinion, and I've tried it both ways. It's not just the Func<> syntax, it's also the strange SelectMany overload you need to transform if you want to use LINQ statements like Haskell's "do" and a few other details.

    On the other hand, the lack of an IAdditive interface or polymorphic return types in C#/.NET is not a weakness of IEnumerable. You could just as well complain about any other feature, but it does not stand in the way of using monads in C#.

    For the Aggregate function, you could supply a seed of "new T()", which would probably do the same as zero(T) anyway.<>

  7. For the Aggregate function, you could supply a seed of "new T()", which would probably do the same as zero(T) anyway

    Thanks for the tip, I think, that might work in my case. Although not in general - there can be only one empty constructor but a lot of possible usages for it.
    not a weakness of IEnumerable

    Agreed, but it's a part of the whole "LINQ to lists" feature.
    the strange SelectMany overload

    Yes, that one is particularly annoying.

  8. I might be wrong, maybe someone comes up with a great paper that shows how to implement some parser using Monads in C# in a way that really makes sense, or something like that.


    Luke Hoban's Monadic Parser-Combinators Using C# 3.0

    But LINQ has been around for some time, Eric has written and preached his stuff, explained how LINQ is just Monads to the Lambda-the-Ultimate crowd, and nothing happened. Why should that suddenly change?


    Functional programming is still very new to a lot of people, so you are going to see a lot more about what they are than how they are useful. That's always the case. However, I've started using continuations and am looking at the state monad for some real applications. They are terrific for parallel/async programming models. If you aren't doing async, then you probably won't see a benefit. As more move to that model, though, you'll see a lot more about applications of monads, I guarantee.

    Also, the Reactive Framework (IObservable/IObserver) is coming out and works using the continuation monad (or something very close). See more here.

Educational Content

Brian Marick on 4 Challenges and 5 Guiding Values of Agile Software Development

Brian Marick takes us through a quick tour of the most important values and challenges to adopting Agile successfully (they aren't the typical challenges and values we hear in the community).

Are You a Software Architect?

The line between development and architecture is tricky. Does it exist at all? Is an ivory tower actually needed? There's a balance in the middle, but how do you move from developer to architect?

Agile – A Way of Life and Pragmatic Use of Authority

The word 'authority' sometimes produces an allergic response in hard-line agilists. Freedom and authority – both are bad if misused and both are good if used in right spirit for a noble cause.

Getting Started with Grails, Second Edition

"Getting Started with Grails" brings you up to speed on this modern web framework. Companies as varied as LinkedIn, Wired, and Taco Bell are all using Grails. Are you ready to get started as well?

Using ITIL V3 as a Foundation for SOA Governance

Those familiar with only ITIL V2 often scoff at the thought that ITIL could serve as a governance framework for SOA. With ITIL V3, the focus of the framework shifted towards service-orientation.

Adrian Colyer on AspectJ, tc Server and dm Server

SpringSource CTO Adrian Colyer discusses AspectJ, SpringSource's dm Server and tc Server products, OSGi and Scrum.

Adam Wiggins on Heroku

Heroku's Adam Wiggins talks about Rails, Background Jobs, Add-Ons, Ruby, and how Heroku manages to work around Ruby's inefficiencies using Erlang and other languages.

SOA as an Architectural Pattern: Best Practices in Software Architecture

For Grady Booch the foundation of a good architecture is patterns, SOA being just one of many patterns. In this Second Life presentation, Booch attempts to bring more clarity on what architecture is.