Hacker News new | past | comments | ask | show | jobs | submit login

I feel like I'm nitpicking but I couldn't let it go, and yes its already been mentioned once but I feel that argument offered by confuzatron was lacking. I'm referencing to your characterization of Linq in C# as something inextricably linked to the language, how you cant even begin to separate it from the language.

Straight off the bat the most glaring problem with that statement is that Linq is not part of C# in any way shape or form since all C# code is compiled to bytecode, it would be literally impossible for C# to have Linq and for it to not be available for the rest of the languages supported by dotNet. The funny part is the expressive form of Linq that reads like a sentence is not even fully supported by C#! Only VB.Net has fully implemented Linq expressiveness.

There are many more reasons that argument is wrong, but I feel just pointing out that one above shows how far off it is.

In my experience its almost always best to shy away from hyping your idea of better by knocking the competition, your article stands well on its own and C# has so many obvious flaws that theres no need to add to it. Stick to whats good about X, not whats crappy about alternative Y.

Again all in all an interesting read since im not familiar with Clojure, but I just had to nitpick.

Straight off the bat the most glaring problem with that statement is that Linq is not part of C# in any way shape or form since all C# code is compiled to bytecode, it would be literally impossible for C# to have Linq and for it to not be available for the rest of the languages supported by dotNet.

There's no such thing as "LINQ bytecode". LINQ is just syntactic sugar that can coexist with vanilla C# (or VB.NET, or whatever) because Microsoft decided to modify its compiler and IDE to allow it. It is fundamentally impossible for you or me to make a similar change, unless we're willing to eschew the Microsoft toolchain.

In Clojure, you do not have the same limitation. That's the only point the article was making, and it's completely correct in that respect.

see my reply to nathanmarz

Straight off the bat the most glaring problem with that statement is that Linq is not part of C#

Parts of it are. Query expression keywords[1] are defined in the C# 3.0 Language Specification (see 7.15 Query expressions)[2].

[1] http://msdn.microsoft.com/en-us/library/bb310804.aspx

[2] http://www.microsoft.com/downloads/details.aspx?FamilyID=dfb...

I'm not bashing C#. I'm just saying that you couldn't define Linq in vanilla C#. It had to be implemented as part of the compiler.

In Clojure, you can create embedded languages without modifying the compiler. That's all I'm saying.

I can appreciate and understand that you didnt mean to come of as combative, but to me it did come off that way - and others since im not the only one pointing this out.

Can you name the compiler change that enabled Linq without looking it up? Can you define Linq, what it basically is? It feels like if you could you wouldnt make such a statement since all Linq is at its core is an iteration engine. Its literally just methods you dump your collection into plus an anonymous method on top and vrooom goes the engine applying the method to each item. The pretty syntax form you usually see is not actually Linq the framework and leads to significantly more problems than it solves, its basically just for PR purposes.

Edit: This feels like it might get out of hand and spin into a good old nitpicking programmers war. Reading my post again it came out way more confrontational than I meant, and I didnt mean any insult by it. My main contention is that the Linq syntax is often confused for the Linq framework - they are not in the same state let alone ballpark. Plus the argument can be made (and i would agree to a large extent) that it wasnt the compiler that was modified to allow Linq, it was Linq that was waiting in the wings for the compiler team to implement features they had planned quite some time before. However I am also being a stickler and stubborn, I nitpicked when even from my point of view it wasnt such a large error - it was the way it disrupted the flow of a pretty good article I was getting into, thats what made it stick out for me.

I'm not the OP, but here are some compiler features missing from C# 2.0 that would have prevented a LINQ-type library: lambda expressions, implicit types, and anonymous types.

None of these required modification to the runtime, they were purely compiler features. And, as pointed out, they were features only Microsoft had the ability to implement.

Strictly speaking, none of those features were necessary to implement LINQ. Anonymous functions were already possible in C# 2.0 with the ugly delegate syntax. Type inference saves a lot of keystrokes, and anonymous types save big families of generic tuple types, but you could do without -- hell, people write functional Java.

(A better comparison would be to look at LINQ-to-SQL specifically; that would not be possible in any sense without the expression tree libraries and compiler support introduced in C# 3.0, since there was no way to "quote" a C# expression and look into it. That's much closer to the mark here.)

However, I agree with you in spirit. A big enough quantitative difference becomes a qualitative one; nobody would actually want to use LINQ+C#2. And likewise, few people want to write small-scale DSLs in C#.

Well, your argument is tiptoeing down a very narrow path based on the definition of "necessary". Here's what Eric Lippert has to say about which features were necessary for LINQ: http://blogs.msdn.com/b/ericlippert/archive/2009/10/05/why-n...

Yes, you're right. Expression trees are especially interesting from an integrated DSL perspective, since you can do ridiculous things like turn lambda expressions into a syntax for hashes and so on. I omitted them because I believe that really did require a runtime modification to support.

But I would argue that since DSLs are all about affordances, it's not sufficient to say that similar functionality would be "possible". If the new approach doesn't represent significant semantic compression (which your hypothetical LINQ+C#2 would not), no one will use it. By that measure, the syntactic sugar added to C# 3.0 was absolutely a necessary precondition for LINQ.

LinqBridge allows support for Linq to run on .NET 2.0. The description of how it works might provide some insight:


That requires the .NET 3.0 compiler to work, which was my point: LINQ is largely a compile-time feature.

No, the features that were used to build LINQ were added to C#. LINQ was then built using them, and those same features are available to you to build anything similar.

I'm obviously just referring to the syntax added to C# to support Linq.

I'm not even criticizing Linq/C#, I'm just using it as a point of comparison to help the reader understand Clojure concepts. How that comes across as combative I don't understand.

Im afraid we will have to agree to disagree, I think weve both stated our cases to the extent they can be clearly stated. I wanted to edit my previous post to take out the combativeness but responses had been put up and it would like a cop out if i did that. I banged it out without double-checking it for overall tone, but again I do appreciate the article and overall found it a good read.

I think what Nathan is referring to is the SQL-like syntax for LINQ, which really couldn't be implemented in C#, as C# doesn't have any syntax extension features.

However, expression-based LINQ is implemented in C#. That's possible because of several language features added to C# 3.0, notably expression trees (code as data) and anonymous functions (lambda). Those features make C# expressive enough to do things like LINQ in C#, though in a somewhat clumsier way than Clojure does it.

For example, if you write cities.Where(s => s.StartsWith("L")), that "s => " is a lambda expression, but because the Where method takes an expression tree, the expression is turned into a data structure rather than executable code. This is similar (not identical!) to Clojure recognizing that you're calling a macro rather than a function and letting you see code as data.

Thats why it felt like a cheap detour to me. To me it read like Linq is completely unchangeable and you're stuck with what MS/C# language dictates it is, but almost every single component of it can be swapped out with your own implementation and overloads that in practice you can do much of what is implied as unachievable. Its been so long ive lost some of my grasp on it, but from what I recall you can swap out even the core methods that the C# sentence type syntax ends up being converted to, now is that not really close to what was highlighted in the article as impossible? With expression trees added on top to build out queries with decision trees during runtime you can make it work against whatever kind of datastore youre interacting with. In the end I felt its not nearly as immovable as portrayed in the article, and at the time i felt like the article was past its prime since it had been an hour with few comments - though im kinda wishing I kept my mouth shut now that theres been an invasion of comments.

To start splitting hairs about exact definition of what was written in the article seems to miss the point to me, the general flow and feel was dismissive of its ability. Is it clumsier? From what I can tell so far yes its clumsier, but its not powerless and immovable which is how it came off. Maybe im just sensitive though, or maybe im insensitive in how i portrayed my argument, but I really did just meant my original comment as constructive criticism.

Applications are open for YC Winter 2020

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact