https://docs.microsoft.com/en-us/dotnet/api/system.linq.enum...
Maybe if you're using the query form, but if you're using the method form, I'd argue that they work together very nicely.
For me, at least, I've found embracing Lambda expressions to be very helpful in a number of cases, between Linq, or writing my own code for doing things like rendering tables (long story there).
Granted, I learned C# right after LINQ was released, but I'd still argue that LINQ is well worth having around.
Think I'd still prefer ActiveRecord really but after you get used to EF (Core) it's still a good tool.
I think the fact this is not an objectively good or bad thing has led to a lot of the tension we see in other aspects of programming.
I think a connected issue is tooling: if you presume a certain floor on tooling, more 'advanced' things like multiple composed domain languages become much more feasible since the tooling can remove the need for memorization and help guide construction without fear of errors. But if you presume all tooling beyond text editing should be regarded as non-essential at best and superfluous at worst, it greatly constrains the set of things in programming one can consider sane or not. I do wish we had more projects experimenting + getting traction with "high tooling, high abstractions, high domain mixing" so we could get more literacy around these methods, but I think the vast majority of programmers today have abandoned these kinds of ideas as good or worthy of further development. On pure interia alone, I long ago capitulated to the idea we will be stuck in text editors and having heated debates over typographical syntax for programming languages for the foreseeable future.
People working on things like LINQ and more advanced domain mixing like MPL or (where I once worked) Intentional Software run up against lots of resistance from people I think probably due to some fundamental differences in assumptions, but I'm not really sure what the deepest differences are.
Stuff.new().each do |item|
puts item
endIn idiomatic ruby, we drop this parenthesis, so the code will look like Stuff.new.each ...
Because Enumerable provides so much functionality, I almost never need to implement methods like those. So what I really care about a lot more are the ergonomics of using each, map, select, reject, all?, any?, etc, which I use very frequently.
The real magic is when you start doing things like:
some_enum.collect(&:+)
This simple line will do everything from sum numbers to concatenate strings, etc.
(Enumerable#lazy gives you an object where collect/map is, and other merhods are, lazy rather than eager.)
> I feel like it takes the role that generators have in Python
Ruby has generators, though in either Ruby or Python map/collect (the lazy versions, in Ruby) can be used for some of their uses, since it basically produces a generator from an input collection or generator and a mapping function.
It’s not, though. (If it was, we could write about its equivalence with Python’s [from functools in py3, core in Py2] reduce function, though, saying much the same thing as about the actual equivalence with map upthread, except reduce/inject is less often a substitute for generators than map/collect.)
#map is an alias for #collect. [0]
#reduce has the alias #inject. [1]
[0] https://ruby-doc.org/core-3.0.2/Enumerable.html#method-i-col...
[1] https://ruby-doc.org/core-3.0.2/Enumerable.html#method-i-inj...
I haven't been a professional Rubyist in some years but my habit here was to use inject.
One thing that is cool about the .to_proc shorthand though is, for example, you have a method
def square_it(x); x * 2; end;
people tend to write an enumeration that uses it like
items.map {|i| square_it i }
but you can actually write it like this
items.map(&method(:square_it))
So not only can you write shorthands to methods on the object itself, you can write shorthands to other methods and "automagically" pass the item as its argument. Nifty stuff.