Live data from Hacker News

Simplify your code: Functional core, imperative shell

testing.googleblog.com

131–140 of 219 posts

Re: Simplify your code: Functional core, imperative shell

#131

Earlier quoted context omitted.

Command-Query Separation is the term for that. However, I find this statement odd: > having functions that do things without verifying preconditions are exploitable Why would you do this? The separation between commands and queries does not mean that executing a command must succeed. It can still fail. Put queries inside the commands (but do not return the query results, that's the job of the query itself) and branch…

I think CQRS is something different than what’s being described here. “Query” code in CQRS can still “do stuff”: call an external database, grab locks, audit trail recording etc. What’s being described here is something lower level, that you keep as much code as you can as a side-effect-free “pure functional core”. That pattern is useful both for the “command” and “query” side of a CQRS system, and is not the same th…

It's not about literally doing things (ie logging) it's about the intent.

Query and ask are synonyms and represent the same idea in this context.

Re: Simplify your code: Functional core, imperative shell

#132
post #130
post #14

Earlier quoted context omitted.

I would have written each statement on its own line: var users = db.getUsers(); var expiredUsers = getExpiredUsers(users, Date.now()); var expiryEmails = generateExpiryEmails(expiredUsers); email.bulkSend(expiryEmails); This is not only much easier to read, it's also easier to follow in a stack trace and it's easier to debug. IMO it's just flat out better unless you're code golfing. I'd also combine the first two ste…

But then you are creating references with larger then needed "reachability".

I don't see a problem with that. This code would typically be inside it's own function anyway, but regardless I think your nitpick is less important than the readability benefit.

Re: Simplify your code: Functional core, imperative shell

#133

While I largely agree with the philosophy, the example provided is not very practical. The code snippet `getExpiredUsers(db.getUsers(), Date.now())` is unlikely to occur in real-life scenarios. No one would retrieve all users and then filter them within the program. Instead, it should be `db.getExpiredUsers(Date.now())`. We should never be too extreme on anything, otherwise it would turn good into bad.

> No one would retrieve all users and then filter them within the program.

No one _should_ do that, but that's a common enough problem (that usually doesn't get found until code is running in production). I suspect with the rise of vibe coding, it's going to happen more and more.

Re: Simplify your code: Functional core, imperative shell

#134

Even large companies are still grasping at straws when it comes to good code. Meanwhile there are articles I wrote years ago which explain clearly from first principles why the correct philosophy is "Generic core, specific shell." I actually remember early in my career working for a small engineering/manufacturing prototyping firm which did its own software, there was a senior developer there who didn't speak very go…

> Meanwhile there are articles I wrote years ago which explain clearly from first principles why the correct philosophy is ...

I think this is a very common mistake. You've spent years, maybe decades, writing code and now you want to magically transfer all that experience in a few succinct articles. But no advice that you give about "the correct philosophy" is going to instantly transfer enough knowledge to make all large companies write good code, if only they followed it. Instead, I'm sure it's valuable advice, but more along the lines of a fragment within a single day of learning for a diligent developer.

A company I worked recently had a more extreme version of this mistake. It had software written in the 1980s based on a development process by Michael Jackson (no, not that one!), a software researcher that had spent his whole career trying to come up with silly processes that were meant to fix software development once and for all; he wrote whole books about it. I remember reading a recent interview with him where he mourns that developers today are interested in new programming languages but not development methodologies. (The code base I worked on was fine by the way, given that it was 40 years old, but not really because of this Jackson stuff.)

I'm reminded of the Joel on Software article [1] where he compares talented (naturally or through experience) developers as being like really talented expert chefs, and those following some methodology as being like people working at McDonald's.

[1] https://www.joelonsoftware.com/2001/01/18/big-macs-vs-the-na...

Re: Simplify your code: Functional core, imperative shell

#136

While I largely agree with the philosophy, the example provided is not very practical. The code snippet `getExpiredUsers(db.getUsers(), Date.now())` is unlikely to occur in real-life scenarios. No one would retrieve all users and then filter them within the program. Instead, it should be `db.getExpiredUsers(Date.now())`. We should never be too extreme on anything, otherwise it would turn good into bad.

With a good library you could do just that, by having the functions return only queries and then expand them to the actual values (by interacting with the DB) after applying the filtering to it?

Re: Simplify your code: Functional core, imperative shell

#137
post #136

While I largely agree with the philosophy, the example provided is not very practical. The code snippet `getExpiredUsers(db.getUsers(), Date.now())` is unlikely to occur in real-life scenarios. No one would retrieve all users and then filter them within the program. Instead, it should be `db.getExpiredUsers(Date.now())`. We should never be too extreme on anything, otherwise it would turn good into bad.

With a good library you could do just that, by having the functions return only queries and then expand them to the actual values (by interacting with the DB) after applying the filtering to it?

So would you then have to do `getActualUsers(db.getUsers())` or `query(db.getUsers())`?

Still smells like in such a case the developer avoids the complications of abstraction or OOP by making the user deal with it. That's bad API design due to putting ideology before practicality or ergonomics.

Re: Simplify your code: Functional core, imperative shell

#138
post #72

Earlier quoted context omitted.

> I have to wonder if programming should have kept pascals distinction between functions that only return one thing and procedures that go off and manipulate other things and do not give a return value. What you want is to use a language that has higher-kinded types and monads so that functions can have both effects (even multiple distinct kinds of effects) and return values, but the distinction between the two is cl…

Making a distinction between pure and effectful functions doesnt require any kind of effect system though. Having a language where "func" defines a pure function and "proc" defines a procedure that can performed arbitrary side effects (as in any imperative language really) would still be really useful, I think

nim does that. and they are called that.

Re: Simplify your code: Functional core, imperative shell

#139

Earlier quoted context omitted.

> Even large companies are still grasping at straws when it comes to good code Probably many reasons for this, but what I've seen often is that once the code base has been degraded, it's a slippery slope downhill after that. Adding functionality often requires more hacks. The alternative is to fix the mess, but that's not part of the task at hand.

> Probably many reasons for this, but what I've seen often is that once the code base has been degraded, it's a slippery slope downhill after that. Another factor, and perhaps the key factor, is that contrary to OP's extraordinary claim there is no such thing as objectively good code, or one single and true way of writing good code. The crispest definition of "good code" is that it's not obviously bad code from a spe…

> However, DDD has a strong object-oriented core, to the extent it's nearly a purist OO approach

Really?

https://fsharpforfunandprofit.com/ddd/

Re: Simplify your code: Functional core, imperative shell

#140
post #55

Earlier quoted context omitted.

I guess I just never encounter code like this in the big enterprise code bases I have had to weed through. Question. If you want to do one email for expired users and another for non expired users and another email for users that somehow have a date problem in their data.... Do you just do the const emails = three different times? In my coding world it looks a lot like doing a SELECT * ON users WHERE isExpired but in…

> Question. If you want to do one email for expired users and another for non expired users and another email for users that somehow have a date problem in their data.... > > Do you just do the const emails = > > three different times? If it's just two or three cases I might actually just copy-paste the entire thing. But let's assume we have twenty or so cases. I'll use Python notation because that's what I'm most fa…

Your post was very interesting in terms of how to translate requirements to a functional solution. You should write that book on how to do that.
Post reply on HN