frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

Open in hackernews

LINQ and Learning to Be Declarative

https://www.nickstambaugh.dev/posts/LINQ-and-being-declarative
32•sieep•1w ago

Comments

bob1029•1w ago
> 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 or cause trouble (your business logic). Worrying about making the underlying infrastructure functional is where I start to zone out.

Does F# care if a DLL it references was coded in a functional style?

louthy•1h ago
> 100% purity down the entire vertical is a very strong anti-pattern.

It really isn't. The benefit of pure all the way down is that later you can replace bits with something more performant if necessary. But starting out with the idea that some bits should never be pure just means none of it is. The beauty of pure functional programming is that its very compositional nature means that you can replace a component without having a detrimental effect to everything its composed with: as long as you maintain referential transparency for that component.

What we gain from imposing the pure functional constraints on ourselves is genuine composition. If we compose two pure functions into a new function, that resulting function will also be pure. This is the pure functional programming super power that leads to fewer bugs, easier refactoring, easier optimisation, faster feature addition, improved code clarity, parallelisation for free, and reduced cognitive load. Opting out for arbitrary reasons at certain stages of the vertical threatens all of that.

mrkeen•37m ago
All of this!

"Pure functional" isn't a style choice. The judges won't hold up big placards with 10 on them because you executed your business logic in style.

It's a contract that your code will give the same output given the same input. The contract goes both ways: your ability to supply a caller with functional code is made easier by your callees supplying you with functional code.

Someone decides that that's draconian and says "what's the worse that can happen?" and starts mutating in a library dependency. Well now your backtracking parser may or may not be able to backtrack. Your transactional code may or may not be able to be rolled back. Your multi-threaded code may or may not be free of races. `true || f()` no longer means the same thing as `true`. You might need to start scaffolding all your unit tests with @Before and @After to setup and teardown state, and give up running them in parallel.

Maybe you really, really, really need to fire the missiles at the bottom of the call chain. Fine, just mark that method as 'red' so I get a compiler error when I try to serve up 'blue' code to my callers.

As long as you're showing off the syntax (matter of taste) on blog posts you might as well get some mileage out of the semantics (guarantees).

pjc50•28m ago
The problem is this tends to collide hard with things which are both stateful and mandatory ubiquitous, like logging.

"Functional core, imperative shell" is a great tradeoff position though.

>> Does F# care if a DLL it references was coded in a functional style

Deeper problem: it can't know. It can only assume. I'd have to check how the loader works but it may be the case that "first call to a function in an external DLL" is not stateless (and can error!) because it triggers the linker.

jayd16•20m ago
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).

xnorswap•1w ago
If you're going to write code snippets, please make sure they compile!

The final example has signature List<Product> but tries to return IOrderedEnumerable<Product>.

I recognise that this is very much a taster rather than even a full introduction, so the author didn't want to explain IOrderedEnumerable<T>, but please when writing blogs, run through your code examples and make sure they compile.

This means that your audience can follow along.

( It just needs a .ToList() on the end. )

sieep•1w ago
Thanks for the heads up, must've slipped my mind. Edit: fixed
NetMageSCW•1h ago
Isn’t that also true for the second to last example with the query syntax code?
abstractspoon•6d ago
Fwiw in the final iteration I would still place each clause on a seperate line aligned by their leading '.' because I find it much easier to scan.
sieep•6d ago
Agreed. That's how I would write it in a professional codebase. I added it to show the transformation from separate functions -> LINQ one-liner. Cheers!
Etheryte•1h ago
Having things on one line is not an upside. Just think of all the Bash one-liners that are write once edit never. Doubly so in what's essentially a tutorial.
wslh•2h ago
I think the future of programming will be mostly declarative and parametric since most professional software is redundant.
cjonas•1h ago
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<Product> GetExclusiveProducts(List<Product> source) => (from p in source where p.ProductTitle == "iPhone" orderby p.TypeOfPhone select p).ToList();

z500•1h ago
You can format it on one line if you want. Please don't do that, though. Personally I prefer the method syntax with one method per line, it reads more linear than the query syntax.
cjonas•27m ago
Agree and disagree. I prefer the second approach, but I wouldn't format either as a single line.
magicalhippo•1h ago
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 code that's easily debuggable and which runtime characteristics is predictable is much better than one dense line that's difficult to untangle, or a few that's hard to predict what will do etc.

anonymars•26m ago
Not to mention it's much easier to put a breakpoint on one of those specific lines
the_other•3m ago
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.
louthy•1h ago
I'm the author of language-ext [1] a pure functional framework for C# and have been pushing the declarative programming thing in C# for over decade. C# is a great language for declarative programming and LINQ is awesome. You need to constrain yourself (and your team) so you don't fall into bad habits, but it can really pay dividends in terms of code stability/maintainability.

I have a couple of samples that I think might surprise you if you think C# must look like Java...

* A game of pontoon [2] - I create a Game monad which is an alias for a monad-transformer stack of StateT > OptionT > IO. This shows how terse you can get, where the code almost turns into a narrative.

* Newsletter sender [3] (which I use for my blog) [4] - This generalises over any monad as long as the trait requirements are met. This is about as declarative as you can get in C#. It's certainly pushing the language, but is still elegant (in my eyes anyway).

[1] https://github.com/louthy/language-ext

[2] https://github.com/louthy/language-ext/blob/main/Samples/Car...

[3] https://github.com/louthy/language-ext/blob/main/Samples/New...

[4] https://paullouth.com

yCombLinks•1h ago
I think the final version is far worse than the second version. This is simpler in what way ?
shortrounddev2•1h ago
I like to return IEnumerable instead of List<>:

    IEnumerable<Product> GetExclusiveProducts(List<Product> 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 can use an extension method to add it to linq I think

mlhpdx•36m ago
Given the use case I’d consider IGrouping<PhoneType,Product>. My point being LINQ is a wide subject and most code I see barely touches the surface.
nlawalker•22m ago
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.
pjc50•20m ago
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

jayd16•7m ago
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.

jasonthorsness•1h ago
I love LINQ (the object method syntax not the keyword syntax) and used it extensively in a production application in ~2015-2017. It is easier in many cases to write and read than manual loops.

In performance-critical code at the time it had to be avoided due to allocations and poor performance compared to loop-based implementations.

However, the new versions of .NET have been reducing this penalty [1], to the point where it might make sense to try LINQ first if it's more concise/clear then only rewrite after profiling!

[1] https://devblogs.microsoft.com/dotnet/performance-improvemen...

HackerThemAll•1h ago
"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.

steego•11m ago
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?

vivalahn•49m ago
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.
steego•29m ago
Why?

Writing your own LINQ provider is a very niche activity done by people who want to translate or “transpile” C# expression trees into something else.

It is fundamentally a difficult endeavor because you’re trying to construct a mapping between two languages AND you’re trying to do it in a way that produces efficient target code/query AND you’re trying to do that in a way that has reasonable runtime efficiency.

Granted, on top of that, I’m sure LINQ provider SDKs probably add their own complexity, but this isn’t an activity that C# developers typically encourage.

stanac•17m ago
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.
Kwpolska•44m ago
The example with lambdas should be written on multiple lines, too. At the same time, you can leverage the => syntax to avoid braces and end up with five lines:

    List<Product> GetExclusiveProducts(List<Product> source)
      => source
        .Where(p => p.ProductTitle == "iPhone")
        .OrderBy(p => p.TypeOfPhone)
        .ToList();
(You could join the first two lines, but I think that’s ugly for multi-line expressions.)

Also, less lines is not a good argument for SQL-style syntax vs method-call syntax. The good argument is that the SQL-style syntax is limited to only a few basic operations, when there are many more useful methods available.

Another reason is that this does not compile:

    List<Product> GetExclusiveProducts(List<Product> source)
    {
      return from p in source
             where p.ProductTitle == "iPhone"
             orderby p.TypeOfPhone
             select p;
    }
This method returns IOrderedEnumerable<Product>, not a list. To fix it, you would need to either change the return type, or go outside of the SQL-style syntax and call the ToList method:

    return (from ... select p).ToList();
recursive•24m ago
There are some things that are harder to write in extension methods too. Such as `let` declarations. Or multiple from clauses referencing iterating variables from multiple levels. I use both.
mau•35m ago
> 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.

pjc50•23m ago
List comprehension is pretty good, but I prefer LINQ method-style because it's executed left-to-right, whereas I keep having to look up the order of Python.
zihotki•9m ago
> with a one-liner for the actual logic

Looking at that 'one-liner' I get strong perl vibes, or is it chills?..

Tor browser removing various Firefox AI features

https://blog.torproject.org/new-alpha-release-tor-browser-150a4/
182•HelloUsername•1h ago•117 comments

Hyperflask – Full stack Flask and Htmx framework

https://hyperflask.dev/
118•emixam•3h ago•27 comments

Video game union workers rally against $55B private acquisition of EA

https://www.eurogamer.net/ea-union-workers-rally-against-55bn-saudi-backed-private-acquisition-wi...
75•ksec•1h ago•30 comments

Lace: A New Kind of Cellular Automata Where Links Matter

https://www.novaspivack.com/science/introducing-lace-a-new-kind-of-cellular-automata
36•airesearcher•2h ago•16 comments

Upcoming Rust language features for kernel development

https://lwn.net/Articles/1039073/
230•pykello•10h ago•135 comments

A stateful browser agent using self-healing DOM maps

https://100x.bot/a/a-stateful-browser-agent-using-self-healing-dom-maps
63•shardullavekar•4h ago•39 comments

Launch HN: Inkeep (YC W23) – Open Source Agent Builder

https://github.com/inkeep/agents
33•engomez•3h ago•32 comments

LINQ and Learning to Be Declarative

https://www.nickstambaugh.dev/posts/LINQ-and-being-declarative
32•sieep•1w ago•36 comments

Ld_preload, the Invisible Key Theft

https://bomfather.dev/blog/ld-preload-the-invisible-key-theft/
11•nathan_naveen•54m ago•10 comments

VOC injection into a house reveals large surface reservoir sizes

https://www.pnas.org/doi/10.1073/pnas.2503399122
45•PaulHoule•4d ago•27 comments

Liquibase continues to advertise itself as "open source" despite license switch

https://github.com/liquibase/liquibase/issues/7374
284•LaSombra•8h ago•237 comments

Why more SaaS companies are hiring chief trust officers

https://www.itbrew.com/stories/2025/10/14/why-more-saas-companies-are-hiring-chief-trust-officers
9•PwnEmAll•54m ago•5 comments

Electricity can heal wounds three times as fast (2023)

https://www.chalmers.se/en/current/news/mc2-how-electricity-can-heal-wounds-three-times-as-fast/
15•mgh2•3h ago•8 comments

JustSketchMe – Digital Posing Tool

https://justsketch.me
155•surprisetalk•6d ago•26 comments

Jiga (YC W21) Is Hiring Full Stacks

https://www.workatastartup.com/jobs/44310
1•grmmph•4h ago

Why I Chose Elixir Phoenix over Rails, Laravel, and Next.js

https://akarshc.com/post/phoenix-for-my-project.html
107•akarshc•2h ago•91 comments

How America got hooked on ultraprocessed foods

https://www.nytimes.com/interactive/2025/10/16/well/eat/ultraprocessed-food-junk-history.html
45•mykowebhn•1h ago•38 comments

Improving the Trustworthiness of JavaScript on the Web

https://blog.cloudflare.com/improving-the-trustworthiness-of-javascript-on-the-web/
7•doomrobo•1h ago•2 comments

New coding models and integrations

https://ollama.com/blog/coding-models
167•meetpateltech•10h ago•53 comments

Trusting builds with Bazel remote execution

https://jmmv.dev/2025/09/bazel-remote-execution.html
3•jmmv•3d ago•4 comments

TurboTax’s 20-year fight to stop Americans from filing taxes for free (2019)

https://www.propublica.org/article/inside-turbotax-20-year-fight-to-stop-americans-from-filing-th...
570•lelandfe•10h ago•305 comments

Flies keep landing on North Sea oil rigs

https://theconversation.com/thousands-of-flies-keep-landing-on-north-sea-oil-rigs-then-taking-off...
179•speckx•6d ago•96 comments

The people rescuing forgotten knowledge trapped on old floppy disks

https://www.bbc.com/future/article/20251009-rescuing-knowledge-trapped-on-old-floppy-disks
76•jnord•5d ago•27 comments

Credential Stuffing

https://ciamweekly.substack.com/p/credential-stuffing
35•mooreds•2d ago•23 comments

Silver Snoopy Award

https://www.nasa.gov/space-flight-awareness/silver-snoopy-award/
84•LorenDB•4d ago•18 comments

Sharp Bilinear Filters: Big Clean Pixels for Pixel Art

https://bumbershootsoft.wordpress.com/2025/10/11/sharp-bilinear-filters-big-clean-pixels-for-pixe...
24•todsacerdoti•4d ago•5 comments

The Hidden Math of Ocean Waves Crashes Into View

https://www.quantamagazine.org/the-hidden-math-of-ocean-waves-crashes-into-view-20251015/
51•pykello•9h ago•1 comments

Apple M5 chip

https://www.apple.com/newsroom/2025/10/apple-unleashes-m5-the-next-big-leap-in-ai-performance-for...
1198•mihau•1d ago•1291 comments

Working with the Amiga's RAM and Rad Disks

https://www.datagubbe.se/ramdisk/
11•ibobev•1h ago•2 comments

Free applicatives, the handle pattern, and remote systems

https://exploring-better-ways.bellroy.com/free-applicatives-the-handle-pattern-and-remote-systems...
83•_jackdk_•12h ago•24 comments