7 ms·
LINQ is so fucking useful and well designed feature of .NET ecosystem that it is unreal when you gotta use lang which doesnt have such a thing. C# design team
by high_na_euv 2y ago
LINQ is so fucking useful and well designed feature of .NET ecosystem that it is unreal when you gotta use lang which doesnt have such a thing.
C# design team is/was unparalleled
- pjmlp 2y agoLINQ is largely based on FP stuff, also how Smalltalk collections work. It is relatively easy to find similar capabilities in most languages nowadays, unless one is stuck on Go, C and similar.
- sanex 2y agoDo you know an equivalent for Linw to EF in kotlin or Java because I have not found it.
- stanac 2y agoThose are linq expressions. They are indeed wonderful. You get an abstract tree from which you can create SQL or API commands to access the data source. I remember in the early days (.NET 3.5?) there were multiple examples of LINQ2X like Linq2Csv, Linq2Rss Linq2Drobox (I'm paraphrasing, I don't remember actual examples, but it was wild). There is also relinq library which transforms linq expressions into expressions which are easier to understand/use.
- pjmlp 2y agoRather quick search, as I am more of a myBatis person, Java: https://www.jooq.org/ https://www.jooq.org/ Kotlin: https://www.ktorm.org https://www.ktorm.org
- kumarvvr 2y agoAny pointers to such libraries in python?
- pjmlp 2y agoitertools would be the starting point, unfortunelly Python is rather limited due to the way it only supports one line lambdas.
- apwell23 2y agoNo it isn't easy to find similar capabitites in java, go, python, ruby. Maybe you do simulate some of this using meta programming in ruby but its certainly not 'easy to find'.
- pjmlp 2y agoIt certainly is, unless you are talking about SQL like syntax, which is basically syntax sugar for classical FP. And I explicitly left Go out of my list.
- apwell23 2y ago>unless you are talking about SQL like syntax yes thats what linq is? https://learn.microsoft.com/en-us/dotnet/csharp/linq/ https://learn.microsoft.com/en-us/dotnet/csharp/linq/ "Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language." With LINQ, a query is a first-class language construct, just like classes, methods, and events. doing this in java is not LINQ imo List<Integer> lowNums = filter(toList(numbers), new Predicate<Integer>() { @Override public boolean apply(Integer n) { return n < 5; } });
- high_na_euv 2y agoTo be fair, 99% of linq usage is method chaining syntax, not query syntax
- blackoil 2y agoOne difference with LINQ is its ubiquity. It works with database, in memory data structures, on disk files. You can use your skills/code across all the system.
- John23832 2y agoIt's just built on top of anything that is Iterable. If a language has first class iterator support, they could do something similar.
- naasking 2y agoMainly first-class functions I think. If you have those, you can just use fold in the core combinators.
- mythz 2y agoTakes a lot more than that, LINQ providers work by accepting a LINQ Expression Syntax tree instead of an opaque function, which allows providers to inspect and traverse the Expression's AST and translate it into the data source it's implementing. This Expression AST is constructed by the compiler, not something that can be tacked on by a library later.
- megadal 2y agoYes, but I think the point is practically every high level language can already do this pretty trivially. If it's scripted you can typically just get a string representation of the function. If it's Java, JAR inspection/dynamics have been a thing for a long time. And in other languages, they usually directly support metaprogramming (like Rust) and plugging code into the compilation logic.
- mythz 2y agoIf it were trivial you'd see LINQ-like providers implemented in "practically every high level language". Source code of the function means you have to implement the parser/lexer to convert it into a usable AST which is bad for both runtime performance and library size. Very much doubt this is available in Java, which Java ORM lets you use native Java language expression syntax to query a database?
- jiehong 2y agoI've found [0] for clojure, which maps the best IMO, but it also contains links to the same LINQ examples in other languages (java, kotlin, swift, elixir, python, ...). [0]: https://github.com/mythz/clojure-linq-examples https://github.com/mythz/clojure-linq-examples
- nightski 2y agoThe difference is many of those are dynamically typed languages. It's still useful, but a lot of the a beauty of LINQ comes from the fact that it is within a statically typed language.
- John23832 2y agoIt's surprising that Go didn't ship with it, but given that they just added iterators, it's coming. Rust has combinators, which is the same thing. Most new languages are recognizing that functional support (even if they don't consider themselves FP languages) is necessary.
- rw_panic0_0 2y agonah it's not coming, functions like maps and filters won't come to go by design, iterators are not only about FP stuff
- pjmlp 2y agoGo culture is quite clearly against this kind of niceties.
- devjab 2y agoYou can do functionality similar to LINQ with chaining as long as you don’t need to call a method with a generic different from the one defined. If you do need that, you’re going to have to do it without chaining. You can still do something similar but it’ll be a lot less elegant than how C# does it. It’s part of the design philosophy of Go though. They don’t want any magic. It’s similar to why they enforce explicit error handling instead of allowing you to chose between explicit and implicit. They want you to write everything near where it happens and not rely on things you can’t see. It’s probably the primary reason that Go is either hated or loved. I think it’s philosophy is great, a lot of people don’t. I have written a lot of C# over the years, so I’m a little atypical in that regard, I think most C# developers think Go is fairly inferior and in many regards they are correct. Just not in the ones that matter (come at me!). To elaborate a little on that, Go protects developers from themselves. C# is awesome when it’s written by people who know how it works, when it’s not you’ll get LINQ that runs in memory when it really shouldn’t and so on.
- whizzter 2y agoYes and no, the LINQ syntax being coherent between IEnumerable<> and IQueryable<> hides a lot of good magic. IEnumerable<> is regular in-memory lambdas/streams, same what you find in many places. IQueryable<> relies on the LINQ expressions, those CAN be JIT compiled for direct execution, but the fact that they are data-objects is what allows the translation to SQL and execution on the server rather than locally and can give massive gains since processing can be done where the data lives.
- whizzter 2y agoFor reference, to achieve what IQueryable does with 100% normal code in JavaScript you need something like Qustar that was posted here a month ago. Regular transform code in JS (Like IEnumerable) const ids = users.filter(user => user.age<18).map(user => user.id); IQueryable like to be transformed to the server: const ids = users.filter(user => user.age.lt(18)).map(user => user.id); In C# it'd look identical, but in JS or Java this would be achieved via proxy-object hacks (the .lt() function in the filter instead of the < operator and the .id property getter for the user map to send a flag under the hood for the mapping function). https://github.com/tilyupo/qustar https://github.com/tilyupo/qustar
- munchler 2y agoIf you like LINQ, you should really give F# a try.
- neonsunset 2y agoF# is even better. I only wish performance wasn't hit or miss around sequences/iterator expressions. Hopefully one day it will reach parity with C# through compiler improvements and/or detaching FSharp.Core from conservatively targeting NS2.0 and modernizing it.
- emn13 2y agoI never really got over the order-dependent and fairly slow compile times, but it's been like 10 years since I used it for anything even slightly complex. Is F# better in this regard now, or are there accessible patterns to help deal with that?
- munchler 2y agoOrder-dependency is a feature, not a bug, but it does take some getting used to. If you really want to avoid it, you can now declare all functions in a module to be mutually recursive, so you can put them in any order. Cyclic dependencies between files are still prohibited, for good reason. See https://fsharpforfunandprofit.com/posts/cyclic-dependencies/ https://fsharpforfunandprofit.com/posts/cyclic-dependencies/. The F# compiler is slower than the C# compiler, but it's still more than fast enough for building large applications.
- throwaway31424 2y ago[dead]
- mhh__ 2y agoMaybe you've been unlucky but LINQ didn't really seem all that interesting to me using it. It's pretty well put together but it was very hard to work out the patterns of what it was doing underneath e.g. I could not tell you now how to implement a custom IQueryable (I know where to look but couldn't tell you the rhythms of it) for some database and I am the type of person who usually does go and find that kind of thing out before using something for a "serious" project. Maybe it's just a microcosm for C# as a whole - very productive language, good design team, quite hobbled by it's weird/philistine upbringings: Bjarne said within C++ there is a simple language trying to escape, in C# you basically have a simple language buried in nouns.
- pjc50 2y ago> It's pretty well put together but it was very hard to work out the patterns of what it was doing underneath e.g. I could not tell you now how to implement a custom IQueryable There's a lot hidden in there, but basically they expect you to use EF. Writing an IQueryable is a similar amount of work to writing a SQL query planner. You get passed a tree of Expression objects. https://learn.microsoft.com/en-us/archive/blogs/mattwar/linq-building-an-iqueryable-provider-part-i https://learn.microsoft.com/en-us/archive/blogs/mattwar/linq...
- SideburnsOfDoom 2y ago> basically they expect you to use EF. Writing an IQueryable... I don't agree. I don't feel any expectation to use EF. It would not be relevant anyway to our code. LINQ is not EF and EF is not LINQ. EF uses LINQ but not vice versa. LINQ is useful without EF. The LINQ extension methods that we use constantly are on IEnumerable<T> so EF and IQueryable is of no importance to us, but LINQ is used everywhere.
- pjc50 2y ago> IQueryable is of no importance to us I was discussing IQueryable with someone else to whom it was important. In reply to > I could not tell you now how to implement a custom IQueryable (I know where to look but couldn't tell you the rhythms of it) for some database And "for some database" the default answer is "use EF" as the intermediary between LINQ queries and the database itself, rather than delving into IQueryable. LINQ-to-objects is very important and useful but I was talking about something else.
- hggigg 2y agoLINQ is a veritable footgun in any large team I find. While it's extremely powerful and really nice, it's so so so easy to blow your toes off if you don't know what you are doing. Some of my favourite screw ups I saw: * Not understanding when something is evaluated. * Not understanding the computational complexity of multiple chained operations/aggregates. * Not understanding the expectation that Single() requires exactly one of something. * Not understanding how damn hard it is to test LINQ stuff.
- high_na_euv 2y ago>Not understanding the expectation that Single() requires exactly one of something. Sorry, but idk how it is footgun of LINQ. It is like complaining about 0 or 1 based indexing >Not understanding how damn hard it is to test LINQ stuff. Any examples? Because I struggle to see such
- pjc50 2y agoHow much of that is LINQ-specific and how much is just the cost of using an ORM to build queries rather than typing them out as SQL? I've never encountered testing problems with LINQ-to-objects.
- John23832 2y agoI sort of agree. I recently had to code splunk a bug with 3 other engineers and we all got to a relatively complex LINQ and of the 4 of us, we all had 4 different interpretations when visually inspecting. > Not understanding how damn hard it is to test LINQ stuff. I disagree with this. Just run the LINQ query on a compatible iterable.
- hggigg 2y agoRegarding the testing, it's more the sheer multiplicative number of cases you have to consider on a LINQ expression.
- SideburnsOfDoom 2y ago> I recently had to code splunk a bug with 3 other engineers and we all got to a relatively complex LINQ and of the 4 of us, we all had 4 different interpretations when visually inspecting. You can write hard to read code with any framework. Yes it takes effort sometimes to make linq code clear, but you should not give up on it.
- highwaylights 2y agoI’ll get started then end up on a rant but.. This is really the thing with the entire .NET stack that’s very hard to communicate. The standard library and framework design are so well thought out relative to anything else out there. More than that, the support within VS is beyond any other dev tool that exists for any other language - it’s not even particularly close. Edit-and-continue comes to mind, which despite how many times people confuse the two is not hot reload, and is wildly more productive and useful. I remember back close to 20 years ago DHH was espousing Ruby/Rails and that the concept of types at all were a code smell, and thinking “you’re just very wrong, and clearly aren’t familiar with what else is out there”. Eventually a lot of that crowd moved to Node, then to typescript, and came around. VS Enterprise (expensive as it is) had features 15 years ago that still seem magical when I show them to JS/TS folks now. IntelliTrace is one that comes to mind - there’s nothing remotely close to it’s snapshot debugging that I’ve seen anywhere else, and I’ve really looked. The big problems with the ecosystem are that the docs are exhaustive but terribly boring, and not well explained from a learning-something-for-the-first-time perspective. They also really expect that everything you do is the Microsoft way, so if you’re trying to interface your code with something like an Avalonia UI, you’re on your own. The language is absolutely wonderful though, even when used with Rider. The productivity relative to node/typescript is better enough that it crushes my soul having to go back to wrestling tsconfig and imports after working with .NET references for even small changes. So many of the little things I used to take for granted really just work, and work well. It’s just a wonderful piece of work executed over decades, held back by poor community outreach and badly written documentation.
- high_na_euv 2y agoYour experiences are coherent with mine. Developer experience is far ahead any other technology out there. Std lib and its API design is world class, I wish cpp had as good stdlib. Tooling is strong, especially debugger
- bob1029 2y agoAgree with all of this. I think the biggest problem with popularity around these tools is that they're too good. When everything just works, you have a lot more time to focus on your problem. Once you can focus on your problem, you may quickly find out you don't actually care about it. Focusing on tools is a great way to hide from this reality.
- megadal 2y agoIt's just an API for JIT, basically metaprogramming. It's cool but you can definitely do a similar thing in pretty much every high level language. With scripting languages, it's all JIT :) The C# teams progress on this has been slow. Keep in mind the CIL bytecode has had such capabilities for at least 20 years now and only in the past like decade are we seeing more features and optimizations around LINQ and System.Reflection.Emit. Dynamics were extremely slow in C# and if you look at the CIL generated you see why. It's possible for example to use something like a Haxe anonymous types[1] to optimize Dynamics so that CallSite caching is way more performant. I am pretty sure in C# the only way to accept an anonymous type is as a dynamic value, so even though the type of the structure is well-defined at compile-time, it will still rely heavily on runtime reflection/DLR with no additional caching beyond what DLR does for any other dynamic type. Anyways, this leads to niche libraries being built for handling dynamic data like JSON performantly. Which leads to annoying things like .NET libraries/apps being incompatible (without some adapter) if they use for example, different JSON libraries under the hood. (See [2]). Problems like these (the lack of actually good JIT/dynamic code support) in my opinion significantly slow down the .NET ecosystems development, that's why it always feels like .NET is just catching up with features other popular languages have. To be fair though, much of C#'s lag is owed to Microsoft's contribution to .NET being mostly technical debt. Almost everything good that came out of .NET came from open source/non MS teams (like Mono). [1] - https://haxe.org/manual/types-anonymous-structure.html https://haxe.org/manual/types-anonymous-structure.html [2] - https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/how-to https://learn.microsoft.com/en-us/dotnet/standard/serializat...
- jeswin 2y ago> It's cool but you can definitely do a similar thing in pretty much every high level language. No. When it was release (circa 2007), very few mainstream languages embraced "Code as Data" the way C# did. In Java, there was no way to pass an expression (as an AST) to an SQL library. Which is why LINQ is so much more ergonomic than Hibernate. In C#, you could use language features you're already familiar with (such as "order.id > 100 && order.id < 200") in your queries, whereas Hibernate made you learn the framework's specific patterns (add Criteria etc etc, I don't recall now). Java just wasn't expressive enough for this. In fact, you couldn't do this even today in a language like say Python or JS. I mean, not without running it through something like babel to get an AST, and having arbitrary rules on what's code and what's data. C# had this in the spec; based on whether it was IQueryable. > Almost everything good that came out of .NET came from open source/non MS teams (like Mono). My team adopted Mono very early - like in 2005. Your statement is not true at all. C# and the Framework was a very good spec irrespective of what Open Source / Mono did, and while Mono existing might have accelerated .Net's transition into Open Source, it would have happened anyway due to the definitive swing towards Open Source in the 2000s. Linq-to-SQL, Asp.Net MVC, EF etc didn't come out of Mono.
- deleted 2y ago[deleted]