Alexander Granin

Author
+ Follow
since Aug 30, 2021
Merit badge: grant badges
Biography
Software architect, international speaker, books author
Author of Functional Design and Architecture, Pragmatic Type-Level Design
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Alexander Granin

Richard Rodriguez wrote:Hi Alexander,

I know that there are some difficulties that comes along learning monads, but I also know that they are useful and powerful. But is it required when building FP applications?
Do you need them for complex applications, and skip them for non-complex ones?

Thanks,
Richard



Hi Richard,

Thank you for the question!

Strictly speaking, you don't need monads in your FP applications, but you need a sequential IO. It's only Haskell who implements the sequential IO on top of the monads mechanism, and it's a very FPish solution. Other FP languages just let you doing sequential imperative calls.

What about non-IO monads, I'm sure that people implement this monadic behavior in different scenarios all the time, they are just unaware of this fact. What is ROP in F# if not a kind of Either monad? I'm sure Scott Wlaschin knows this, he just avoids calling it a monad.
Congrats to the winners!

Thank you for this opportunity!

And thank you folks for nice questions!

Stepankha Yuliannia wrote:Hi Alex,

Would you then agree that FP is closer to this real-world scenarios and therefore more native for DS?

Many thanks & have a good one



Hi Stepankha,

I don't have enough experience and knowledge to comment on CAP and distributes systems. This is a very specific topic that I'm not familiar with.

FP is definitely closer to data processing. Essentially, FP is about data processing, and in theory, making data transformation pipelines (even distributed ones) should be simpler in FP languages.

However, there is something unfair that Python has taken this field while not being so convenient to writing such applications.

Sebastian Makowiecki wrote:Hi there,

When it comes to functional programming paradigm does the language choice matter much in your opinion?

Briefly, in 'couple' sentences or just naming a few in a list, what are  the main benefits of functional paradigm over the others?

Many thanks, lately I have been thinking about all the available paradigm  choices, so far struggling to make sense of it and would appreciate your expert input.



Hi Sebastian,

Yep, the choice of a language is an architectural decision and it definitely affects everything that comes after. Let me try to make a short overview of FP languages as how I see this, but my overview won't be exhaustive by any means.

1. Clojure. Very simple FP language, very pleasant to use (#2 of the most loved languages in SO Survey). Fast development cycle, JVM, lovely tools. You'll have to write tests for making your apps reliable. I would avoid writing big programs in Clojure though.
2. Scala. Enterprise-level FP/OOP language. Also JVM. A lot of approaches, solutions, design patterns, architectures. Great for data transformation pipelines. Somewhat a difficult language requires a lot of knowledge. An acceptable mix of FP and OOP.
3. Haskell. Great for financial apps and backends. For blockchains as well. Excellent for concurrent apps. Great for building reliable apps with a minimum of bugs. Small community - this risk is higher than with other languages. Learning can be somewhat challenging. But Haskell is what we call "real FP" today. Most of the mainstream languages borrow ideas from it, and I'd recommend learning Haskell to learn FP in its purest.
4. F#. .NET, MS stack. Well-established, quite ready for production, enough powerful and nicely documented. Not that difficult to learn.

There are other FP languages, for example, JavaScript, but I'm not sure if I need to characterise them.

What about the paradigm itself, let me copy-paste my answer from another thread:

FP:

- Compilers, research, math
- Multithreaded and concurrent applications (if we want a better story with concurrency bugs)
- Data transformations and pipelines (for example, spam filters)
- Very complicated domains. (FP simplifies domain modeling very much)
- Stateless services
- Correctness (statically typed FP works extremely well for such domains as payments, bank software, blockchains etc)

OOP:
- All the traditional uses of OOP
- GUI (for now, FP doesn't work here that well)
- Business software (at least until we find a good way for FP)
- OOP can even work for soft-realtime apps. I wouldn't try FP there.

Hope this helps!

Mohammed Sardar. wrote:Hi Alex,



How does functional design impact the microservices architecture of an application when the functional aspect of any service changes? Can microservices adopt complete functional programming?

Glad to hear from you.


Thanks,




Hi Mohammed Sardar,

Thank you for your question.

FP is compatible with microservices. You can have your microservice apps completely written in an FP language, and I would do so with Haskell rather than in any different language. There are certain advantages of this choice, but they are not about the high-level solution because microservices are microservices no matter what paradigm is used. But you might be happy to enjoy nice FP features when writing your app: concurrency, bugs elimination, a reduced complexity. Especially if your microservice is "stateless". (I take this word into quotes because "stateless" doesn't necessarily mean the absence of any state. People may say "stateless" even when there is a DB to interact with.)

Junilu Lacar wrote:

Alexander Granin wrote:

Stepankha Yuliannia wrote:I'm just going to add that performance is a big thing/reason to use FP (supports parallel programming). OOP does not support parallel programming.

Yes, agree. I'd only say that the term "performance" is quite overloaded, and we might be talking about different things here


Just wanted to get some clarification on this "OOP does not support parallel programming" statement.

Admittedly, I haven't written any Java programs that use them but Java does have features that support parallel programming. Are you both disagreeing with that assertion or is there some nuance in what you said that I'm just missing? Isn't support for parallel programming "a function" (excuse the pun) of implementation rather than the programming paradigm (OOP vs FP) itself? A similar example would be tail recursion. Nothing in OOP or FP says that tail recursion optimization isn't supported, right? Currently, Java doesn't support TRO as far as I know but other JVM languages like Kotlin and Scala do.



Hi Junilu,

This is not my statement though, so maybe Stepankha can tell.

From my perspective, OOP doesn't deny parallel and concurrent programming. After all, there are a lot of things about this. What I see is that FP is much much more suitable for parallel and concurrent programs because of its concepts of purity, immutability and careful separation of concerns. OOP is imperative, mostly. You certainly can program it with purity and immutability, it's just not enforced by OOP languages.

Also, such things as (monadic) Software Transactional Memory, eliminate so many bugs and reduce so many problems with concurrency that I'd say it's unbelievable that this is possible.

Stepankha Yuliannia wrote:Hi Alex,

Embedded domain-specific languages are everywhere in functional programming, we can say FP and eDSLs/DSLs are natural partners. We use eDSL/DSL to reduce complexity of the system and to keep things decoupled from each other.

When we decide to be using eDSL/DSL so the client code will only work with the DSL (its dependency on native calls will be eliminated), we then have an option to use a native translator for the eDSLs/DSLs that converts high-level commands to native functions or we can test our scenario separately by inventing some testing interpreter. What is your personal preference and why?

Thanks



Hi Stepankha,

This is a great question! And actually, you've just repeated what I'm saying in my book. There is a chapter I finished recently - Chapter 5, Embedded Domain-Specific Languages. It has all the answers to your questions. Here, I'd confirm that eDSLs is a very natural and essential thing for FP, and I encourage to use them all the time. Not only for small things, but as an architectural solution: you can have eDSLs as interfaces to your subsystems, and then interpret them to make it work in the real environment. This is the main idea of my book and methodology I call Functional Declarative Design. I use it quite a lot in my work and in my hobby projects. I'm a very big fan of interpretable languages, to be added.

Sean Corfield wrote:Having built large web apps in multiple languages (and multiple paradigms) over two and half decades now, I think I'd place web apps in general squarely in the FP camp.

Handling a web request is a function from request to response, possibly producing side effects alongside that response, and as you noted concurrency is so much simpler in FP languages!

I think we can make a lot of inroads in UI work with an FRP style approach (Functional Reactive): React/Redux/etc has shown us what is possible, with some great FP wrappers around those (see Reagent/Reframe in ClojureScript, for example).

As background, I did OOP from early '92 (and was on the ANSI C++ Standards Committee for eight years before transitioning to Java, then Groovy, then Scala) although I'd studied FP at university in the '80s and via Scala I came back to FP and have been doing Clojure full-time since 2011 now.



Thank you, this is very interesting! Your experience from FP and OOP matches mine.

Stepankha Yuliannia wrote:I'm just going to add that performance is a big thing/reason to use FP (supports parallel programming). OOP does not support parallel programming.



Yes, agree. I'd only say that the term "performance" is quite overloaded, and we might be talking about different things here

Stepankha Yuliannia wrote:Hi Alex,

What is your criteria for whether you should we have a message broker in the middle of your solution? Like RabbitMQ, ZeroMQ, Apache Kafka etc.? I'm especially interested from functional programming point of view.

P.S. I understand your book is focused on an application architecture, but would this be covered too?



Hi Stepankha, thank you for your question!

Indeed, this relates to Solution Architecture rather than to Application Architecture. I don't really have that much experience with message brokers, but it seems I'd need them if:

- I want to receive messages asynchronously and concurrently
- I want to have some rules of storing messages
- There can be many interacting services, and it's better they could send messages not directly but indirectly
- There can be some other consumers like cold log storages and DBs for data analysis, and I'd like to connect them without touching my primary applications. For example, the system already works, and I need to do some analytics. I don't want to edit my code just to add this functionality, but I can connect external DBs and analytic services right to the queue.

I might be missing some criteria here, it's what thoughts I have on message brokers.

Karanveer Plaha wrote:Hi Alexander,

In my work I've encountered scripts and automations which are a collection of imperative functions which are called exclusively for their side effects.
They are composed entirely of I/O steps (fetching data from database, posting to another service, writing logs to file) which are also sequential in terms of time.

What strategies could be applied to begin to make these kinds of imperative programs more functional?



Hi Karanveer Plaha, thank you for your question!

FP developers have a long history of going into the pure world of avoiding side effects. FP has much more practices of pure data transformation rather than practices of dealing with the impure, unreliable real world. But we can't write useful programs without dealing with side effects, and the bigger and more complex the application is, the more problems are coming from the interaction with the external world. This is clear to me that FP can't be different here from other paradigms.

So, in FP, we started inventing approaches to this. Many Haskell programs do imperative IO explicitly and use different architectural patterns like Service Handle or ReaderT. IO is monadic in Haskell, this means it's sequential. There are other approaches like effect systems, Final Tagless/mtl and just a bare IO. In my book, I'm showing almost all of these approaches, and proposing my own based on Free monads. Its idea is that you can encode your actions purely in Free monadic eDSLs, and then you get the sequential / imperative-like property because of monads. Interestingly, your business logic code will stay pure, because it will be encoding DB operations, logs etc., and real actions will only happen on the implementation level.

This topic is a big part of my book. In the second half, I'm showing how to build a Free monadic framework that has all the needed things to write usual web backends and services. You can even checkout the related showcase project Hydra: a framework I built for my book. It was used as a prototype for creating more real-life technologies like EulerHS which are used in real production.

https://github.com/graninas/Hydra

jared kellerman wrote:Hi! I'm currently working on a career transition and going through training to be a full-stack developer. I've only recently become aware of the differences between functional and object oriented programming. My question for you is, how did you decide functional programming was the right path for you and what you wanted to do in your career? Based on your experience, what would you advise a newbie to be asking themselves when deciding which programming path to pursue?



Hi Jared,

Thank you for the question. It's a bit broad though. I'll try to answer briefly.

I started from C++, and then learned some approaches which are more natural for FP. After that, I've been captured by Haskell. The difference was so big that I decided to never return to C++. Moving to the full-time Haskell job took 5 more years though.

My advice will be to broaden your horizons. OOP and FP are a must, kind of. Many technologies have FP concepts, many languages have FP features, it's inevitable.

The rest depends on what you really want to achieve.

Joe Buckle wrote:Hello all,

I am in an small team of C# developers, and we are tasked to rebuild a medium-sized ASP.NET application written in C# to F#. We have been given a year to be able to put the new application to production. How should we approach this? How do we go about training to be able to attain that functional mindset? How do we extract/retain all that business/domain knowledge and logic present in the current application?

My apologies for all the questions. Thanks!



Hi Joe,

Building a project from scratch is always a risk, and there is no guarantee that the attempt will succeed. But I think it's possible to reduce this risk by following a systematic approach.

In my book, I'm proposing a complete methodology, from requirements gathering to designing of subsystems and implementation. You might find it useful for training and learning high-level FP concepts. Especially considering that F# and Haskell are very close (most samples in my book are in Haskell)

What about extracting the logic, this is no doubt tough. A closer analysis of the codebase will help. Tests, documentation, domain experts in your team, the properties of your product. You really need to collect some requirements before doing any architectural decisions.

Also, I would strongly recommend having an F# expert in your team.

I wish you good luck in this!

T H Lim wrote:There are many Scala collections like List, Set, Priority Queue, etc. They are in immutable and mutable forms and they are "functional". However, they do not support the effect F[_] out of the box. Fortunately, Cats Effect provide some of the commonly used collection like queue, dequeue, etc. For the developers, what are the options they have to get an effect-ful collection like Map and List, without writing overly complicated collections that support the effect F[_]? How do other pure FP languages developers manage in general?



Hi, thank you for your question!

I'm afraid, I'm unable to answer it any expertly. I was never involved into work on collections and didn't have any chance to learn Scala.

What I see is our terminology differs a bit. In Haskell, we don't call F[_] an effect, it's a type parameter of some data structure, for example:



We can make it to be a Functor, and even a Monad if we wish. Not sure if this fits into the "simple enough" characteristics though.

Campbell Ritchie wrote:You seem to be doing well for questions



Doing my best!