Saturday, November 09, 2024

Why the struggle with functional programming?

Slow FP adoption...

Why no widespread adoption even though functional programming exists already now for over sixty years?

Not so long ago I explained this as:

The reason is actually pretty complicated: The strength of FP is much due to its ability to be very strong. This strength in the code weakens the ability of developers to make local changes. Initially, this sounds like something good, yet it creates a new challenge: developers are bound to the constraints of code written by others, and they are not only not happy, they are less productive! You can solve this by bringing your FP to the next level: math. A few companies do this, now a developer is not subject to constraints but to mathematics. If the developer understands the math she/he finds this acceptable.
I am simplifying things a bit here, yet FP, or any language that is strong enough, brings in a whole complexity of technical ownership and people dynamics that does not need to be dealt with with OO. The reality is that FP allows more scaling, but maintaining the stability of people within that scaling is a major challenge.

I want to present this a bit differently here, because the above put too much blame on people. Yes, FP is tricky for teams, yet the root cause is not the teams, the teams just highlight the root cause!

The Design - Features - Tasks trilemma

Let's start with the following trilemma

Design - Features - Tasks

And by trilemma, I mean that you cannot simultaneous set goals to progress all three. (And by task, I mean "effective coding work"). You must specify two of these, and let the third one be determined by the outcome of your work. You can specify design and features, you can specific design and tasks, you can specify features and tasks... but you cannot specify design, features, and tasks before you start working.  To be more concrete: when you focus on architecture before coding, and come up with a design, you are in fact constraining the features that will be implementable with tasks that follow that design. If now you specify additional features, before you start your tasks using the given design, you will likely fail.

Functional programming done seriously "ties" design and tasks together. By which I mean that FP that pushes its higher order design model highly constrains the design. The result is that by construction, a team that pushes its FP design culture, is also a team that is "squeezing themselves" into an over constrained design-features-tasks trilemma. To be specific, an FP team may be imposing design, features and tasks all at the same time, and not understand that this is an over-constrained setup that will most often fail.

There is a solution: Just like I mentioned in that earlier post, you get a around trilemma by splitting one of its terms. Here we split tasks into design tasks and non-design tasks. The approach is then the following:

  1. Given some desired features
  2. Work on design-tasks so that the design can implement the features
  3. Then work on non-design-tasks, that implement the features with the developed design.

From a work triplet perspective, we have:

  1. features & design-tasks -> new-design
  2. features, non-design-tasks -> implemented features

Here, the new-design produced by 1, are used in 2.

However, the challenge is that now we have a two phase work process, and by default teams, especially agile teams, are single phase process. Agile typically asks teams to focus on tasks that deliver MVP features, and therefore agile typically sets people up to fail, as there is no new feature in good FP without new design, and... and teams often struggles to juggle the three needs to progress design, features and tasks within a same agile effort.

TDD helps

Test driven development (TDD) is one way to escape the limits of a one phase agile process. The idea is the following: 

  1. Given some design features
  2. Develop tests for these features, AND extend the design to cover the features.
  3. Then work on non-design-tasks, that implement the tasks, and pass the tests.

However...

Yet there is still a challenge: design changes most often depend on strong opinions. FP depends on design changes. FP depends on strong opinions. Getting teams to gel around strong opinions is often not trivial. And that why I wrote the statement shared above.

All original content copyright James Litsios, 2024.

Sunday, October 06, 2024

A software mind's eye

I have been writing higher-order functional programming in Python for the last few weekends:

  • hofppy (https://github.com/equational/hofppy) will be a Python library. For the moment it is a collection of Jupyter notebooks.
  • My initial goal was to have a handy FP toolkit which supports applied math with JAX's JIT. Yet I realise that in fact what I am really doing is reimplementing the generic part of a compiler for a reactive (trading) language I wrote in 2010 in F#, while including a few tricks I picked up since then, the primary one being to think of code as implementing a synchronous execution model.
  • There is really very little code like this on the web, therefore why I am doing this open source.

This blog is in part written to mention the above, as already the first JAX JIT supporting monad and comonad models are "nice". Yet this blog is also to bring up the subject of the process of creating new technology.

My recipe to do something new, such as lead a team on a new subject, write software that did not exist before is the following:

  1. Create a "mind's eye" imaginary world of "usage" of the end result.
  2. Imagine how it should work.
  3. Start very quickly to implement features.
  4. Review 1, 2, and 3, as you regularly cycle through them, again, again, and again!
I use the word imagine twice above. For a few reasons...

People are constantly asking me "how do you know?", with regards to client's requirements, technology, design, approach, etc. The reality is that I do not completely know: I know much, I have done much, written hundreds and hundreds of thousands of lines of software. Yet when something is new, no one knows fully how things will look in the end. The reality is the newer it is, the less you know. And... the more you think you know, the more you are fooling yourself. However, just like with poker, the optimal approach is to imagine much and often, and to work as hard as possible to build and maintain a mindful view of "new usage" and "new functioning technology".

The more experience, the better! As your imagination is only as good as the real details it contains. I have tons of real-life learning that I use for this higher-order FP in python. I mention here a few of them:
  • Lazy software design are easier express in code.
    • The most flexible design, is the code that does nothing but accumulates lazily what it could do, until finally because output is expected, it works backwards from output expectations to pull out the desired output.
  • Multi-stack semantics is perfectly normal. 
    • For example, in the project's above monadic code, the free monads have "their" variables, "normal" Python has its variables, and these are carefully kept separate.
    • Multiple flows of causality exist in the real world, stacks of various semantics is the only cheap way to capture these cleanly in software.
  • For every Ying, there is a Yang.
    • If there is more, there is also less; If there are variables, there are constraints, etc.
  • Structure is more important than types.
    • I started in functional programming without the types. Then I embraced types. And yet to understand that the sweet spot is somewhere in between. The reality is that it is much easier to use code to constrain software "just a right level" than to use types.
  • Math is the most powerful structure.
    • Think geometry, topology, and dualities!

 All original content copyright James Litsios, 2024.

Monday, October 30, 2023

The personality of going Infinite

 "A bit shallow" is my short review of Michael Lewis Going Infinite book on the rise and fall of Sam Bankman-Fried (SBF). Still, I don't have an issue with the lack of content, as that reflects the reality of the open legal situation. I do however find the psychological presentation of SBF a bit shallow. 

(Background info is that SBF started his career as a trader at Jane Street Capital, a high frequency trading firm).

When hiring a trader, you are looking for someone that balances drive and analytical thinking (personality state 2 below). You also want a trader that is emotionally connected to their work. In high-frequency trading the software and the math trades, not the person. As a result the trader must have "empathy" for their models, for their algorithms, as these do the trading. These models and algorithms are complicated, and need clear mind to be felt. As a result, when hiring an electronic trader, one might look for people that can "shut out normal emotions" and connect to the "made up emotions" of markets, models and machines. In a previous post this year, I mentioned this "shut out emotions" state as  "preserving a depleted emotional space" state (state 1 below).  

A depleted region in semiconductors, is an area where electrons have been "pushed away". Resulting in a region that needs electrons to be "normal" again. I use here the term depleted emotions in a similar maner: it is a state of mind that lacks emotions, and only becomes active emotionally with an inflow of emotions from others, or by a focused effort of the person. With no inflow, the amount, and the depth of emotions stays minimal.

Let's call "Goal Oriented-Analytical-Preserving emotional Personality" (GOAPP), as person that seeks to balance their personality state of analytical goal orientation with their need to preserve an almost none-emotional (e.g. intellectuel) view of the world.

Most of us react to social moments, many of us buy things. State 4 below captures the balance of the two. Most of us resonate with our emotions (state 3 below). 


There is a "Follower-Consumer-Emotional Personality" (FCEP) which is on the opposite corner of  GOAPP.  These two personalities can co-exist in multiple manners. From a GOAPP perspective:
  1. FCEP might be embraced as the ever elusive normality.
  2. FCEP might be rejected in a form of self-handicapping denial.  
My feeling is that SBF falls into the second category above: A goal-oriented analytical person, that in part denies their emotions, and yet also the emotions of others, as well as denies the normality of others to be part of society, both as consumers and as followers of social trends. This explain in part the crazy interviews: having denied himself the normality of emotions and social belonging, he lived out his fantasy of rational normality, which really does not end up containing much.

All original content copyright James Litsios, 2023.