Live data from Hacker News

LINQ and Learning to Be Declarative

nickstambaugh.dev

31–40 of 60 posts

Re: LINQ and Learning to Be Declarative

#31

I like to return IEnumerable instead of List : IEnumerable GetExclusiveProducts(List source) => source .Where(p => p.ProductTitle == "iPhone") .OrderBy(p => p.TypeOfPhone); That way the user can decide if they want a List or Array or Set or whatever, and you can also add additional queries to this Also better to pass IEnumerable to the function instead of List, for the same reasons Also I forget the syntax but you ca…

The only problem with IEnumerable's open-endedness is that it's so open-ended. It makes no implicit guarantees about order, finiteness, side effects, speed/efficiency, idempotency etc. It's easy to assume those things until you accidentally find a situation where one or more are not in your favor.

Re: LINQ and Learning to Be Declarative

#32

I like to return IEnumerable instead of List : IEnumerable GetExclusiveProducts(List source) => source .Where(p => p.ProductTitle == "iPhone") .OrderBy(p => p.TypeOfPhone); That way the user can decide if they want a List or Array or Set or whatever, and you can also add additional queries to this Also better to pass IEnumerable to the function instead of List, for the same reasons Also I forget the syntax but you ca…

This is generally better yes, especially if it's going to end up inside another LINQ operation - you can avoid materializing the list.

Cases where it isn't:

- risk of multiple execution (there is a CA warning for this)

- when returning data protected by a mutex, you should always materialize a copy of the returned list/array rather than return an enumerable

Re: LINQ and Learning to Be Declarative

#33
post #2

> Functional programming isn’t an afterthought in C#, it’s effective and you should learn it if you haven’t already. I think C# is the best functional programming language because you always have access to a procedural code safety valve if the situation calls for it. 100% purity down the entire vertical is a very strong anti-pattern. You want to focus on putting the functional code where it is most likely to be wrong…

There are a lot of patterns you get when you can be 100% certain of something. For certain functional languages, you could actually safely assume immutable patterns and such.

I really love C# but I will also say that 100% purity is a super power that C# will never have (can't have 'em all).

Re: LINQ and Learning to Be Declarative

#34

I’m going to reserve a thread on this post for folks who want to share horror stories trying to implement their own LINQ providers.

Not a horror story. I like how marten worked with postgres and wanted something similar for sqlite, so I made a library that stores data as json, and translates linq to sql using json query functions. It wasn't very fast, but it was fun experience. For next attempt (once I have more time) I will probably include source generators to precompile queries and skip if not all, then most translation at runtime.

Re: LINQ and Learning to Be Declarative

#35

"But what if I told you we could make it simpler" ... and then the author proceeds to presenting clunky, unreadable fluent syntax That was a good joke for the afternoon.

Are you saying that you’re unable to read a fluent syntax that’s been supported by most mainstream programming languages for the past 10 years?

Or are you suggesting that the majority of programmers struggle to read and understand fluent method chaining?

I don’t have a dog in this fight because this blog post is very novice oriented. I’m just genuinely confused why you think it’s unreadable or “clunky”. What is it about the fluent example that you find clunky?

Re: LINQ and Learning to Be Declarative

#37

I like to return IEnumerable instead of List : IEnumerable GetExclusiveProducts(List source) => source .Where(p => p.ProductTitle == "iPhone") .OrderBy(p => p.TypeOfPhone); That way the user can decide if they want a List or Array or Set or whatever, and you can also add additional queries to this Also better to pass IEnumerable to the function instead of List, for the same reasons Also I forget the syntax but you ca…

It really depends. IEnumerable could have a lambda that leaks the world and makes a web call on every iteration for all the caller knows. You know iterating a List will be fairly banal.

So from an API perspective, I think returning IEnumerables can end up being too cute. The caller has to deal with this unknown thing.

In general you should be clear about what you return and loose about what you accept. If your whole API is returning IEnumerables and some are expensive to iterate and others are not its actually less clear what I'm getting. And this isn't to say List is always the answer either.

Re: LINQ and Learning to Be Declarative

#38
post #8

The second SQL-like version is far more readable. There is just less "syntax noise" and it's far more "declarative" by definition. The author stating that the lambda is "better" because it's less lines is also silly. It's been a while since I've written C#, but pretty sure the SQL-like version can be formatted to a single line as well: List GetExclusiveProducts(List source) => (from p in source where p.ProductTitle =…

Never understood why a lot of programmers are so obsessed with reducing lines of code at the expense of all else. What's important to me is that I can understand the intent of the code, that I can reason about how that code will be executed at runtime, and that I can easily debug the code if needed. Of course, there's no need to go full enterprise Java. Never go full enterprise Java. But having ten lines of clear cod…

Years ago on the Ruby Rogues podcast, someone mentioned they aim to do just one operation per line. I’ve aimed to do that with ny TS/JS ever since. My files are longer but they’re usually easier to read.

Re: LINQ and Learning to Be Declarative

#40
post #24

> Your coworkers and QA will thank you for learning LINQ and ditching the imperative methods that plague your Python brain. This is a very unfortunate joke: Python has list (and generator) comprehension expression for a long time (2.3?) which are similar to LINQ. At some point in the history many languages stole useful expressions from other paradigms. Let’s joke on BASIC, it always works.

> This is a very unfortunate joke: Python has list (and generator) comprehension expression for a long time (2.3?) which are similar to LINQ.

I love Python, its my main daily driver, both at work and by preference for most of my personal coding, but Python comprehensions and genexps are much more limited than LINQ language level query syntax (Scala’s visually-similar construct is more like LINQ in capabilities) and Python—purely because of core and stdlib convention which also drive convention for the ecosystem, not actual structural features—lacks anything like the method syntax as a common API (unlike, say, Ruby).

EDIT: Thinking about it a little bit, though, it should be possible in theory to implement LINQ in Python without language level changes (including providing something close to but not quite as clean as the language level query syntax[0]) as a library via creative use of inspect.getsource and ast.parse, both for providing the query syntax and for building the underlying expression tree functionality around which providers are built (support for future python versions would require implementing translation layers for the ASTs and rejecting unsupported new constructs). Conceptually, this is similar to how a lot of embedded DSLs in Python for numeric JIT, compiling GPU kernels, etc., from (subsets of) normal Python coded are done.

[0] existing comprehension/genexp syntax looks similar, but relies on simple iteration, not pushing code execution out to a provider which may be doing something very different behind the scenes, like mapping "if..." clauses into SQL WHERE clauses for a database query.

Post reply on HN