Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> The middle road is simply a better engineering option, use a practical language that supports both paradigms.

Agreed - I would get more specific with this too. Which arrangement makes more sense:

1. A solution that has an OOP outer shell hosting an FP inner core

2. A solution that has an FP outer shell hosting an OOP inner core

I argue that 1 makes way more sense - I look at the OOP/procedural code as the foundation layer upon which the FP code can be executed. This firewalls the messy outside world from the pure maths. For me this would be entry points like BusinessLogic.ExecuteRules() after having externally prepared all of the data contexts for execution. The results of this are then processed again by the external OOP code for downstream handling (writing to database, responding to web client, etc).

The other way around feels nonsensical to me.



Mutation is infectious. It will take great care to have an OOP core and outer FP shell. The OOP core might have to become completely threadsafe and use mutexes and such, to be reliable. This might be more painful than sticking to either one paradigm.


Maybe OOP is a strong word, but it would make absolute sense to have an imperative core if you absolutely need the highest possible performance, or if the OOP/imperative core is pre-existing and you want to "regulate" access to it through the affordances of FP.


Unless you are on a greenfield project, you don't get to make these decisions like that. You start with a jumble of libraries and helper classes, or a complete app which needs its functionality amending. The right choice will alter depending on where you start if you see what I mean.

And yes, i'm an advocate for the mix and match approach.


> a complete app which needs its functionality amending

Where are you from? This reminds me of a long-since-dead grammatical construction, the "passival", in which -ing participles were used passively - the example I read about was correspondence stating "our garden is putting in order" where the modern language would require "being put".

In my English, it's still possible to say "the app needs amending" [= "needs to be amended"], or "the app's functionality needs amending" [ditto], but definitely not "the app needs its functionality amending".


Passival my arse. You need your head looking at if you think that's an unusual grammatical construction! :)

I'd say the thing you're commenting on is normal, if not altogether correct, in British English (Where are you from? I'm from the UK).

https://dictionary.cambridge.org/dictionary/english/need-hea...


You might notice that the URL you're linking identifies the expression as "need [your] head examined". On the page itself, there is a usage note saying "UK also need your head examining", of which no examples are given.

> Passival my arse.

Do you see this construction as different?

Wikipedia:

> Another construction sometimes referred to as passival involves a wider class of verbs, and was used in English until the nineteenth century. Sentences having this construction feature progressive aspect and resemble the active voice, but with meaning like the passive. Examples of this would be:

> The house is building. (modern English: The house is being built)

> The meal is eating. (modern English: The meal is being eaten)

> This passival construction was displaced during the late 18th and early 19th century by the progressive passive

( https://en.wikipedia.org/wiki/English_passive_voice#Passival )

I think it's fair to call that "long since dead".

> Where are you from? I'm from the UK

California.


Oh I'm sorry, I thought you'd find it funny. "X my arse" is another British idiom (but "Passival my arse" is novel). Yeah "need your head examining / looking at" are both quite common; as you say the online dictionary I linked gives it as a variant and you can confirm via quoted Google search strings that they're used.

E.g. headline in a major newspaper in 2019 https://www.mirror.co.uk/news/politics/you-vote-ukip-tomorro...

As for whether "need your head examining" or "needs its functionality amending" are related to the examples you're giving, it sounds like you perhaps think more deeply about grammar than I do, but I would tentatively say not. Your examples are "<noun> is <present participle>", whereas "<noun> needs its <noun> <present-participle>" seems different to me.


You could argue frameworks like Spring Integration or Apache Camel are FP outside + OO inside, but the key is that they allow side-effect channels for passing data ignoring the functional interconnections.

Without that you would need to refactor the functional part every time any OO node wants to access any new data.


C# and F#, imperative shell, functional core :)


> The other way around feels nonsensical to me.

Wonder if that's because you've learned the pattern - "functional core, imperative shell"? I feel it's not a coincidence you used the terms "shell" and "core" in your comment :).

Myself, I'm very much in favor on a theoretical basis. In practice, I've got bitten by this a couple times - keeping a purely functional core didn't play nice with the modularization and testing setup we had, using C++17 with CMake and GTest/GMock. I blame this on my inexperience, filing off sharp corners as I go along. I'd sure could use a detailed study of how to apply this pattern in modern C++, on an application scale, taking account the real tradeoffs - like how to "firewall" the core from outside mess, and allow tests to poke through that firewall, and not end up in weird linking hell, and not blow a single module into 10 tiny ones, and keep the whole thing debuggable in practice[0].

One thing I occasionally do even in the "FP inner core" is apply the idea I picked up from Clojure's "transient" data structures: there is no difference between purely-functional, immutable, referentially transparent code, and imperative code carrying mutable state, if no one on the outside can tell. Sometimes it's just easier to make a typical imperative procedural or OOP solution and isolate it in a functional interface.

--

[0] - I used to like point-free coding; especially with functional style, it makes for nice, readable, highly-expressive one-liners. But each time I had to debug such code, I ended up regretting it. Now I'm starting to favor more explicit steps with intermediary variables storing results, simply to have good targets for potential breakpoints/tracepoints, and because such code is more convenient to step through. You could say I'm only doing it because the tools I use are limited, but frankly, almost all of "readable code" principles and even the shape of modern languages are driven by limitations of the tools we use, so ¯\_(ツ)_/¯.


In at least F# you can step through point-free pipelines with a debugger!


How convenient it is, though? I can step point-free code in GDB or MSVC debugger too, but it's a painful process of stepping in and out of calls by hand.


At least in VS Code the debugger will show you the values at each step of the pipeline and move through the pipe like any other step. It is very slick!




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: