Posts

Showing posts from 2011

The beauty and the beast: explicit and implicit types

Working with Haskell has brought on an unexpected question: Is it more productive to work with implicit types or explicit types? By this I mean: “Should major types be mostly inferred or mostly specified with type signature”? The bizarre fact is that you may well use two different parts of your brain to work with inferred types or with “defined” types!   Here is the reasoning: Programming is an incremental process: changes are made locally and then overall consistency is assured. When programming around types, changes are made to type specifications or to expressions which affect type. The two kinds of changes lead to two styles of programming: the first is to start by changing a type definition or type annotation, the second is to start by changing an expression, which results in a change to the inferred types, and possibly needing a fix to a type signature. The bare minimum of type annotation is not even to provide argument to “top level” functions, such as ...

Stream oriented and parallel programming

Good software design comes to applying simple patterns; for many years now my simple pattern is stream oriented programming, and in the functional programming monads. In this post, I will introduce the concept of stream oriented programming by showing the value it brings to parallel program. Parallel programming design has three basic patterns: Sequential execution Parallel execution Hierarchical execution (or “compositional”, “encapsulating”; please help with name) The two first are classic: operations happen sequentially along the execution, operations can happen in parallel along synchronous or unsyncronized execution flows. One way to present the third pattern is through hierarchical state machines (HSM) where each sate can be a yet another HSM, recursively to any depth. Hierarchical patterns of execution are important because they are really expressing higher order properties of the solution space. Sequential and parallel patterns are good: they do work, they make things ...

Delivery focus versus creative slack

I made a presentation on scrum today in which I first presented a generic agile framework, to then present scrum within that agile framework. Although I had not planned it, I found myself emphasizing the need to focus on delivery in order to make time available, what I call slack time, to be creative and bring your development up to a new level. One can compare agility and running hedge funds: management and product development processes share much with how one maximizes a portfolio. The key learning is that you cannot afford to waste time when you are squeezed by your boss, by your investors, or even by the market! Agility from this view is much about maximizing your productivity while reserving time to ensure growth. That is the notion of focusing on delivery and on your client, and yet still have time (and space) to tackle the hard problems! You need time to reinvent yourself as you progress. That is the notion of making space for slack time. Make sure you accumulate enough of it a...

Bad scrum, good scrum and trust

Years ago I switched my development team to scrum. Or at least what I thought was scrum: we had teams, product owners, we carefully followed the sprint and stand-up process. Then we carefully sized our stories and we carefully worked to produce average work. of decent quality. It was scrum, but now I would call it "bad scrum". It was bad because we had built ourselves a straight jacket, and none of us dared to step out of line with the risk of blowing the sprint. Arguably, there were attenuating circumstances: the teams were walking on eggs, working on a large C++ program that few us understood. Still I have seen this behavior elsewhere. It is a behavior of risk aversion, sustained by worries of the whole team. So you might ask, "What is then good scrum"? Good scrum is when you follow the process but stop worrying about it.But most importantly, good scrum is when you have managed to build a liberating trust among all members of the team. All too often developer...

Immutable, mutable, higher order designs and monads

One of the great pleasures of programming functionally is to be able to rely on immutable data. With immutability, side effects need to be explicitly defined, either as return values from functions or as encapsulations in monadic states. Immutability allows two important properties: first it increases productivity by diminishing what needs to be cared about (freeing the mind to care about the right things!), then, almost as more importantly, it provides the foundation for higher order programming concepts by preserving an acyclic relationship between functions and data. By higher order, I mean that data is replaced by functions or that functions encapsulated in data; for example, in a context like data differentiation or in the use of monads. By acyclic, I mean that all trace trees are acyclic (trace tree can be seen as dynamic call graph where recursion is not a loop). Let me explain… It is OK to have cycles in the static call graph. That is because we know how to infer invarian...

What to recommend to a young quant

I share with you my recommendation to a "young quant" that wrote me asking for leads: ... A tricky question. As with any industry, there is a certain “commoditization” of derivative technology including quant work, that plus the uncertain future of the US regulations on derivatives, and to add to that a bleak economic outlook in Europe and the US. The grass is not necessarily greener on the other side and many parts of the market are in a squeeze. Having said that, there are still smart people out there making money and there is still a lot of new development in Asia. My recommendation is not to look for change of activity, but to get closer to successful firms. I know that is easier said than done. Still, one idea is that you are better off accepting a low pay to be closer to success than a higher pay that keeps you out of the fast lane. Again, I know this is not easy. And worse than that, you are in competition with many others. The best I can do is to give you th...

OO versus functional programming versus agile

Have you ever asked yourself the question of why database tables do not have two primary keys? Or maybe you have started a spreadsheet with a choice of columns and rows to only change them later? One of the little understood properties of programming is that at the lowest level things tend to be single dimensional. So for example, the balanced tree has just one key, and so on. There is theoretical reason for this, but the general fact is that it is much easier to design a structure or algorithm to do one thing than to do two or more. Object orientation starts with the fundamental idea that objects can do many things. And this naturally leads to the expectation that they can do them equality well. We know from the previous paragraph that this is not true, and yet many do not know this or forget it. You would think that this mismatch between expectation and reality is not really a big problem, yet sadly it is. OO programmers are constantly trying to fit multiple dimensio...

Should you use F# in your projects?

A few years back I read that a guy killed a child with his Ferrari: he missed the turn after a strong acceleration (as he left a Ferrari gathering!). And then more recently I read the same type of story, again with a Ferrari and an uncontrolled turn at an intersection. Well, F# is like a Ferrari (maybe that is what the F stands for ;-) ). It is incredibly more productive than the classical OO .net languages; see it as a language with an incredible acceleration. But the caveat is that programming in a functional language is much more of a balancing act, and therefore beware the slippery turns and “intellectual crashes”. This is especially a management and team issue, a language like F# allows you to blend in the same code concepts that can be dealt by your “standard” developer and concepts that take years to master. (It can be even worse than C++ template meta-programming.) If you were going to set up a taxi company would you buy a fleet of Ferraris if they were available at the sam...

Teaching and agile management

Today a friend's son asked me to help him with his math. The magic of internet meant that could read up the topic on wikipedia while listening to the request and accept in confidence. Here are a few hints on how to teach: Allow learning from mistakes : the young man's first request was to erase what he had done, as it was wrong. I stopped him and led him through the understanding of what he had done, building a knowledge of what "not to try again". This happened a few more times where I let him make his mistakes so that he could understand better how not to make these mistakes. Do not provide solutions but support the learning of decision making along the way : Learning is about associating together thoughts and methods and by doing so building a new way to do or understand something. In this case, I help him identify which of the mathematical tools he possessed already would help him for this type of problem. Help maintain a notion of goal at all times : The problem ...

C++ and functional programming

What to say to C++ programmers about functional programming, especially now that many compilers have implemented C++0X features like lambda and auto. I am pretty good at C++, having started using it with the Zortech compiler V1 and the first versions of CFront (the orginal C++ to C translator). I have also written much fancy template code. Therefore thinking about this post leaves me in the dilemma that there is one part of me that likes the features of C++0X that "wrap up" loose ends, and another part of me, the functional programming part, that makes me want to rant! I will not rant today, but part of that reasons for being upset needs to be said, as is relevant. The "magic" of mature functional programming are: Statements, expressions, functions and types support each other Type inference and polymorphism automate the relation between statements, expressions, functions and types Monadic and other "advanced" types are available to define new executio...

Personalize your containers (in F#)

Many years ago I implemented an augmented tree structure in C++. Inspired, I decided to implement the structure in F#. FYI by augmentation I mean storing extra data at each node of the tree that will accelerate the later operations on the tree. In DB terms, augmentations are typically used include secondary key conditions in your tree query. This is what I did: Take a balanced tree implementation off the web. I was thinking finger tree but then though better to start with a simpler implementation. I chose an AVL tree. (I may revert the code to a red and black tree to simplify). Add a node field to store the augmentation (a generic type) Refactor the code by replacing the call of the node constructor by a call to a function that will first build an augmentation and then call the node constructor Pass the generic augmentation "maker" function as argument to the function calls On this last point I wasted much time. Initialy, I tried to encapsulate the "augmentation...

Flash crash 2010 thinking

An old friend asked me if the flash crash had been caused by "spoofing" of the exchanges with very large flows of order entry/order cancel commands. My feeling was that this was not the case and a quick search on google picked up a confirmation in this article: The Microstructure of the ‘Flash Crash’: Flow Toxicity, Liquidity Crashes and the Probability of Informed Trading ” This article supports the explanation that the main cause of the flash crash was simply the lack of liquidity because the market makers had become too edgy due to too much new information coming in to the market. It is an excellent article and brings back the notion that some systems are only sustainable with enough "friction", or said differently, by being under-optimal with regards to certain ways to look at them. When a group of people need to work together, they nominate a chief, or at least they give specific roles and ownerships to members of the group. These people get an "unfair...

Types versus architecture

There are three invariants in a software system: Code Types The architecture One old rule is: more types, less code. This is because the less "sophisticated" type provides less "support" to the code, and therefore you need more code to keep things in control. Another way to put this is that the invariants provided by the use of more types allows the code to be more simple. For example, long ago I experienced this type of code simplification with the use of the record/struct moving to C and Pascal from early basic and FORTRAN (and assembly). And again with classes and objects moving to C++. And again with variant types and later monads with functional programming. Another rule is: better architecture, less code. I have repeated this mantra for many years and yet thinking about it, I am not even very sure I have a good definition for architecture. I use to say: 'architecture is what does not change in the system'. Now maybe I should say: 'it's what d...

What architecture for a trading system?

Listening to Randy Shoup's interview of his eBay’s Architectural Principles presentation I was at first surprised by how similar their architecture was to my views on how to design a trading system (something I have done for fourteen years!). Then to remember e-bay may not be a high-frequency trading system but it is both an exchange, a back office and a front end system.

narrowing and widening in type inference

The joy of googling yourself! I was (again) wondering about the deeper theories that tie type inference algorithms that use narrowing to those that use widening. A search on the web led to a comment on LTU (http://lambda-the-ultimate.org/node/1910)... Argh, that was my comment! Nevertheless, since then, I come to accept that one is the dual of the other and that is does make sense to combine the narrowing and widening either to simplify the type inference algorithm or to implement "approximate" types.

Local versus global monadic states in large applications

(Note: this needs a correction because there a third way which is to just transform the monad "top down", it has restrictions but is very usable too, so I will need to update this). Yesterday evening it occurred to me that two choices are possible when programming large monadic applications: A single common monadic state is shared among the modules while each module is written independently of this state and is given an accessor to access its local state in this global shared state. The application then defines the global states built from local states, and the accessors to go access these local states. Each module works on a state which presents primarily the local state of the module but which carries anonymously the global state. One way to do this is to "zipperize" the global state and walk over it with a "focus" (see . "Functional Pearl: The Zipper" ). I have been using solution 1 for my prototyping. Having now spent a few hours trying to ...