21 November 2015

Interview Carlos Blé

After Sebastian my dear friend Carlos Blé agreed to talk to me about his values and meaningful work. Unfortunately we did not find a time to discuss the topic in person, but he took the time (I assume during nights) to answer my questions nevertheless. I reproduce his answers here - still all (spelling) mistakes are mine to blame. Read Carlos' blog or find him on Twitter to get in touch with him.

Carlos BléPeter: Carlos, please take a few sentences to introduce yourself in a professional context.
Carlos: My father bought an Intel 8086 back in 1987, I was just six years old. He had several books with examples of source code in BASIC. That fascinating language got me hooked, I used to copy listings from the book to the computer to see the program run. That marvellous machine seemed to be the gate to the future, as it turned out to be... Years later I had an Amiga 500, then Amiga 1200 and was an active member of the Amiga community. Later I discovered Open Source and installed GNU/Linux on my machine back in 2000, it was Mandrake, then Debian...

When I was in my second year in college I sold my first program, it was a Delphi program to read data from files and render as graphs. With the local Debian community I volunteered as system administrator in several LAN parties, installing and monitoring servers. My first "official" job was as a PHP developer and Linux system administrator. My third job was my own company which made me grow as an individual. I started with three good friends and ended without company and without friends, but I learned a lot about myself and many other things.

Moving to Ireland was another milestone in my career, I went there without job and without a place to stay, spending a couple of weeks in a cheap hostel. I was over optimistic and did not really know how hard it is to start from scratch in a different country with a different spoken language. As you can imagine that was an awakening. That year in Dublin my brain learned to think in English and I learned that I could make a living as a developer anywhere. That gave me confidence to start up new projects when I moved back to home. I thought that if everything went wrong I could move abroad for good while this crazy bubble was still growing in Europe and the US.

What do you consider your biggest successes?
In the long term, the success lies in the perseverance. Working in many different places and learning from different people has helped me a lot. Writing a blog and self-publishing the first book on TDD in Spanish opened new doors. Sharing what you know and learning from others is essential. I have been using computers my whole life pretty much and I have been making a living out of it for about 15 years now. Today I run a successful company providing training and consulting as well as development services.

I know that you are vegetarian since more than ten years and I noticed you sharing content about cruelty to animals in factory farming. Why does that matter to you?
Once you know what happens in the factory farms and the slaughterhouses it is not very difficult to become vegan. Discovering the lies of the system is like taking the red pill in Matrix. I am slowly transitioning to a way of life that is sustainable for the planet. I do not want to take part in the animal holocaust. Most people do not know the truth about the system, the way the planet is dying so I feel like sharing what I know.

The reason to become vegan goes way beyond respect and empathy for animals. The carnist system (meat industry, consumers, etc.) is killing the planet at a dramatic rhythm:
  • 51% of the greenhouse gas comes from the meat industry.
  • 45% of the Earth's solid surface is used by the meat industry.
  • 10.000 square metres of land may produce 27.600 kilograms of vegetables, however it only produces 280 kilograms of meat.
  • Between 4.000 and 8.000 square metres of Amazon rain forest disappear every second, they are destroyed to grow grain for animals in the factory farms.
  • Three quarter of animal life in the ocean has disappeared already, species like tuna are disappearing quickly.
  • A single hamburger requires 3000 litres of water.
  • 70.000 million of animals die every year for meat.
  • Most of the food for animals is transgenic, which is killing the diversity of the vegetable species on the planet and giving even more power to large corporations like Monsanto.
And there is the protein myth, people believe that we need more protein that we actually need which is causing many diseases. The myth is promoted by the carnist system. The time of our life when we experiment the highest growth is within our first two years of life, when we only drink breast milk, consisting of only 6% of protein. There are top level vegan athletes like Carl Lewis. Look at the muscles and power of vegan Frank Medrano. It is interesting that after all these years as vegan myself, people keep telling me it cannot be healthy, despite my excellent health. I am a living empirical evidence!

Carlos planting cropFor references and more information about the numbers above I highly recommend the book Why we love dogs, eat pigs and wear cows by Melany Joy, it is an eye opener, a terrific book. Our ignorance is causing our own extinction but I believe we still can change it, I am very positive about it. I see more and more people aware of their consumer habits. Consumers have the power to change the world. I recommend the documentaries Cowspiracy and Home for those how want more numbers and facts.

What other topics are you concerned about and what do you actually do regarding these things?
I try to reduce my ecological footprint as much as I can, everyday a little step further towards a sustainable life which involves many areas, a lot of thing to learn and unlearn. We have been educated for competition but the current situation requires collaboration. So I want to be the change that I want to see in the world as Gandhi said, I am the first one who has to change in many respects. Every little gesture helps.

The easy way for us to change the world is by changing our consumer habits. Buy local food rather than going to a massive shopping centre. By organic food. Reduce the amount of animal products in your diet (you do not have to be vegan) and buy them directly from sources where you can see with your own eyes how the animals are treated. Help local producers first. Ask big corporations to be transparent when it comes to the way they produce their products. We need to know how things are made to make good decisions.

Make sure that cosmetics and cleaning products have not been tested on animals. There is no need for that at all. Laundry and dish-washing detergent as well as other cleaning products have a big impact in the nature, causing water pollution. Search for sustainable alternatives. Recently I have found a woman who makes soap in the traditional way and I am buying her soap and using it for the washing machine and dish-washing.

Do not buy stuff you do not really need, consider buying second hand. You do not need a new laptop every year or a new cell phone every six months. Do you have an idea on the ecological footprint caused by mobile devices? It is a good time to start wondering about these type of things. The way you spend your money has a direct impact on the life of the planet. Governments and large corporations are not taking care of the planet for us, we are the ones with the power to change. Your choices when you buy are way more important than your choices when you vote for a politician party. See the interesting documentary the story of the stuff for more details.

Outside your personal topics discussed above, what do you consider the biggest challenges of our times?
To survive our own ignorance, to stop living as if the resources of the planet were infinite.

What could we do to engage in these topics?
Whatever you do, it has to be fun or rewarding in some respect, otherwise it will not be sustainable and you will finally stop it. The transition movement is very inspiring, it is like a great promise and it is working in many places, e.g. agroecology, permaculture, de-growth, and so on. There are nice and cool things to get involved in, more than we think. I recommend the documentary In Transition.

Carlos' first cropThe less money you need the more freedom you get. I am starting to grow my own food at home, my plan is not to need money for food soon. I plan to instal clean energy at home so I am able to survive without money while my lifestyle is humble. The way we spend our money, the way we shop is more important and more powerful than we think. I am also limiting the number of flights per year, this explains why I am attending less conferences than usual.

Most of our time is spent on regular work and thus I want to see more impact of my work. While I could quit my job and do charity only, I would rather keep doing what I can do best and earn my salary as usual, just working on "the right things". Do you think that is possible in general?
Everyday at work we have an opportunity to be nice to others, help and support them with love. We do not have to quit our jobs or run charity organisations. We just have to be aware and consistent with our thoughts, our feelings and our words. Take a look at Radical Simplicity.

Do you have any examples where you took professional decisions based on your values and social responsibility?
I have been lucky not to work on projects or at companies that I consider deeply against my principles. I try to listen to my gut feeling. Sometimes I take a day off to disconnect and get some inspiration from nature.

How do you think about selecting customers and projects based on your values?
I try to know more about my customers before working with them. I do some research and if I do not like what I find or what I see during my first visit then I just do not work with them. As I said I have been lucky enough to stand in a position where I can say no to some jobs. I understand that not everybody can say this all the time.

Sometimes a company does not sound very good but it is still worth visiting it to see what they do and how they do it. There is always time to reject projects or customers. I try to avoid companies where everybody's goal is to make money. Money is a means and not a goal in itself.

Let's be more specific. Would you work for an animal factory? Would you work for a company producing equipment for animal factories?
I might visit some of those companies to meet people before saying no beforehand. The list of undesired industries or projects would be big man ;-) But yeah, I do not work for money, money is a secondary effect.

Did you ever reject a customer or an actual project based on your values?
When you leave a company, most of the times the reason is that you feel you have different values and principles, a different vision. Otherwise you stay. I do not want to write any company names in here.

BatCat from Carlos' cat shelterWhat would be customers and projects that you consider important and have an impact on society and the problems we discussed earlier?
As a software developer, your colleagues are the ones who make projects interesting and fun. People are the key. I recently saw that the guys from Avaaz were recruiting. They work for a better world and I signed many of their petitions, but I have enough years of experience not be enticed for their job offer because I do not know anyone working there, I do not know about their values as software developers.

Years ago I used to work as the "computer man for everything" in a little charity shop and I it was not nice at all because time and energy was spent discussing irrelevant stuff, fighting with egos, with no impact at all in the final goal. It is a romantic idea to think that a software project might have a positive impact on the world. Sometimes it does but in my experience the values and principles of the team are what really matter. I search for a combination of projects with less negative impact on the world, whose team members are people I know and who are aligned with my values and principles as a professional.

For example, one of my current customers is a car importer and dealer. The cars they sell need oil to run, they are just regular cars. It does not sound like a company that helps the planet. But I do have a gasoline car as well and so far I could not find a way to live without it. I try to minimise gasoline waste and hopefully someday I will not need the car or I will at least have a solar car. But it would be silly to say "I don’t want to work for a car company" while using a car myself. Moreover, the employees have a great sense of collaboration. People help one another in the office, the company really cares about the employees and people are happy working in that environment. I had the chance to meet the CEO several times for lunch and he has told me that they donate almost half a million Euro every year to local NGO's. I have shared my concern for the climate change and the peak oil with him. These guys have a lot of potential to change things for better so I see the job as an opportunity to help influential people awake awareness apart from growing myself as a professional.

I have been brief but if people read the answers and write comments or further questions I will go deeper into the subject, I just need some feedback to do so ;-)

Credits
Thank you Carlos for taking the time to answer my questions. This has become a long article but I believe it is worth it. I really enjoyed discussing these important topics with you and appreciate that you took the time to share. Thank you very much and I wish you all the best for your projects in the future.

16 November 2015

Interview Sebastian Göttschkes

Following up on my previous post on meaningful work I want to further dive into the topic started there. As most of our time is spent on regular work, i.e. in our day job, I am especially curious about the impact we could have there. For me as software developer my day job is to sit in a chair and press keys on my keyboard in weird sequences almost all day. And by doing that, what can I do about the important issues of preserving the environment or cruelty to animals to name just two examples? Is it possible for my work to help these issues? Is it possible to make a difference by just working on the "right" things? What are these "right" things?

To get some answers, I decided to use a more structured approach. This topic is complicated, probably highly philosophical, and I do not expect to get good answers by analysis alone. I think we need to start a dialogue with one another to discuss and define what our responsibilities might be. I created a list of questions and started asking some of my peers, i.e. developers with solid experience of working in our industry. I have collected their answers and will mark their ideas and opinions either by quoting or typing in italics to separate from my own interpretations and errors.

Introducing Sebastian
Sebastian Göttschkes was the first to accept my invitation. Sebastian is a developer living in Vienna. He is interested in programming since he was a kid and started coding when he volunteered for programming classes in school. After finishing his studies at university he has been working as professional software developer for ten years. He likes to build stuff. Read his blog or find him on Twitter to get in touch with him.

Vegetarian food or notBeing Vegan
I noticed that Sebastian was vegan and asked him about it. Some time ago he had started to eat less meat due to health problems. Being concerned about what to eat and what to avoid, he thought more about food in general which led him becoming vegan for ethical reasons. He said that being vegan is important to him because as developed being he does not want to treat other beings badly. Cruelty and killing is not necessary for his survival. It is disappointing how we, human beings treat other beings. We should be able to do better.

Other Topics of Concern
Sebastian is also very concerned how we treat one another as individuals and as society on the whole. The current refugee crisis in Europe is a perfect example. If people are starving we have to help them. We have to help first, there will be enough time for discussion later. Currently there are many discussions in the European Union regarding refugee quotas and refugees are forced to wait. Surely they need to be registered and their claims have to be verified, but that could come later. These people should not be treated like numbers on some form. Sebastian believes this to be the result of our capitalist ways. There are more and more areas where people and whole systems are reduced to numbers.

Challenges for Humanity
When I asked Sebastian about what he considered to be the biggest challenges for humanity he laughed. There are plenty. The environment is obviously very important. We need to fight climate change and forest deaths. We must not destroy our planet. Further politicians and governments need to work together smoothly to avoid wars and all the unrest caused on a global scale.

How to engage in these topics?
Sebastian likes to talk about being vegan but he makes sure not to have a reproachful attitude. People are open for the discussion when they are not attacked or forced a bad conscience. Even a single meal without meat each week makes a difference. In the current refugee crisis in Vienna he keeps donating goods and actively supports the NGOs helping refugees around Westbahnhof where he lives. He has also organised charity concerts in the past.

My first questions were just introducing Sebastian and setting the stage. The really interesting question was about the impact of our regular work. I asked him several questions regarding impact, choice of work, choice of project, customer or industry and so on.

Is it possible to have impact on your day job?
There is the social entrepreneurship movement which has similar goals. Today almost every product or service needs supporting technology so we developers have many options. As our technology is everywhere we should be able to find jobs with more impact in general. But the problem is to find suitable companies and keep the standard of living at the same time. Also it is more difficult for people with a high degree of specialisation. Sebastian looks for companies who help people in some way. Even regular companies can do that, it is not necessary to work for NGOs exclusively. But it is difficult to recognise such companies. You have to check each project you work on individually. Sometimes you cannot tell up front at all.

Poppyseeds Mom And DadChoice of Industry
While software development is an industry on its own, most of us work to support another industry, e.g. finance, insurance or energy, although often we do not take this choice deliberately. Sebastian does not believe that the choice of industry matters. It is more important which company you work for and even more so which project you actually work on. While the finance sector has a bad reputation, supporting micro loans to help poor people is a good thing, unless the project's goal is to rip off everybody and just make more money. In general Sebastian recommends to stay away from finance and overly capitalist industries, because of their problems discussed earlier.

Choice Based on Values
On the other hand it is not easy to find a company according to one's values. We cannot be too particular because we need the money. As we are part of the system, i.e. our society, our current way of life, our capitalist world, we have to live by its rules. All I can do is to decide according my values inside my possibilities and choose from the options I have. But the system is complex and hard to understand. There is much indirection and it keeps getting more and more indirect. For example some things we consume are not made locally. And even if we know where something was made, we do not know where its raw materials came from. It is not unusual for raw materials to travel halfway around the world. It is impossible to think about all the problems and implications so they are usually ignored.

Choice of Companies
I was not satisfied by Sebastian's answers and continued asking because I wanted to explore his values and decision process more. For example I asked him if he would work for a butcher? He denied, but he would work for a company working for a butcher. In fact he has worked on some platform of local advertisements where butchers would be able to advertise their goods as well. I kept asking and asking, but Sebastian did not have a list of undesired customers. Sebastian prefers small companies. In general small companies are less "evil" than larger ones because they have less power and cannot ignore laws. Small companies have other goals and there are still people in charge who have a conscience.

Projects are especially interesting to Sebastian when they try to change people's way of thinking without blaming. For example he mentioned TREEDAY, a gamification of checking CO2 footprints, or WienRadeltZurArbeit where you win prices by collecting miles of going to work by bike. These initiatives are great because by making people think they have more impact than by just supporting people who already care for the topic.

Conclusion
I enjoyed talking to Sebastian and it took us around 90 minutes to cover all questions. The conclusion is that there is neither black nor white. What should we do if we write software that - in the end - destroys 100, 1000 or 10000 jobs? Maybe there is no way we can do the "right" thing - either we do not know all its implications or we have no choice. But to ignore the situation is definitely wrong. We need to address the issues, preferably in a positive, improving manner.

Credits
Thank you Sebastian for sharing your values and ideas with us. I am glad you took the time and I appreciate the interesting discussions we had. Thank you very much.

6 November 2015

Bank-OCR Kata in Scheme

Why is it when I wanted to do something completely different from work to relax - I end doing code katas in Scheme? (Last week on Twitter.)

SoCraTes Belgium
Two weeks ago I attended SoCraTes Belgium, the Belgian branch of the Software Craftsmanship and Testing family of (un-)conferences. Being an un-conference the complete agenda of both days was created by the participants. Early during the first day, a participant proposed a session to work through the exercises of the well known SICP book using the Scheme programming language. We worked through the exercises as a mob and it was a lot of fun so another session was scheduled for afternoon. Time and again Scheme sessions were scheduled outside the official agenda. In the end I had spent several hours playing with Scheme and I really enjoyed it.

Why Scheme?
Later I started doing code katas in Scheme, which surprised me, see my initial quote. I do not know why I chose Scheme. There were other programming languages I had planned to learn. Maybe, as my friend Thomas remarked, I chose Scheme because it is seldom used in commercial projects, at least in my surroundings. As it is far away from anything I might touch during my regular work, it is easier to have fun with.

Unit Testing
Nevertheless I wanted to follow my typical development process, using TDD and looked for recommended unit testing frameworks. As minimalism is in the spirit of Scheme, I went with the Scheme Unit outlined on Cunningham's Wiki,
(define (report-error msg)
    (error (string-append "AssertionError: " msg)))

(define (assert msg b)
    (if (not b)
        (report-error msg)))
and added assertions whenever I needed them.

Banking the LightBank OCR
Today I want to share my take on the Bank OCR Kata using Scheme. The Bank OCR assignment is to parse files containing lists of numbers written in LCD style using only pipes and underscores. Each number has nine digits, all of which are in the range one to nine. I knew the Bank OCR kata and had done it before using different languages like Java or C#. I was familiar with the domain which allowed me to focus on functional programming in Scheme.

Outside-In
In the past I used the Bank OCR kata especially to practise the outside-in way of development. Using this approach you build the system from the "outside-in", following the user interaction through all the parts of the system. You start with the interactions and collaborators up-front, especially those at the top level and create fake implementations or mock necessary dependencies. With every finished component, you move to the previously mocked collaborators and implement them. See Emily Bache's article on Outside-In development for a discussion of Outside-In both with London school and classic TDD.

Outside-In vs. Functional?
So whenever I did the Bank OCR kata I tried to follow strict outside-in. But this time I wondered if the outside-in approach was feasible when using a functional language? As far as I knew the typical way of functional programming was to compose small functions to more powerful ones, which naturally lent itself to the bottom-up or classic approach. I was curious how these two would match, if at all.

The Guiding Test
Following Double Loop TDD I started with failing guiding test to parse a single number containing all possible digits,
(define all-digits (list "    _  _     _  _  _  _  _ "
                         "  | _| _||_||_ |_   ||_||_|"
                         "  ||_  _|  | _||_|  ||_| _|"
                         "                           "))

(assert-list= string=?
              "should parse a single number"
              (list "123456789")
              (bank-ocr all-digits))
which expected that bank-ocr(all-digits) yielded ["123456789"].

How to solve the problem?
Then I started to TDD the top level function bank-ocr.
(assert-list= string=?
              "should return empty list on empty input"
              (list)
              (bank-ocr (list)))
which created the initial function. Then I tested for a non-trivial case
(assert-list= string=?
              "not sure about the name of the test yet"
              (list "123456789")
              (bank-ocr all-digits))
Big Ben (London School TDD is Outside-In but Classic TDD can be as well.)But how would I solve the problem? I had no idea. Nevertheless, the first step of the algorithm was to split the input into groups of four lines each and another function, e.g. parse-line, would parse the line then. Following outside-in I defined a stub for parse-line and changed bank-ocr to call it.
;; stub
(define (parse-line ocr-line)
    "123456789")

(define (bank-ocr ocr-lines)
    (if (null? ocr-lines)
        '()
        (list (parse-line ocr-lines))))
The next test forced me to implement the recursion to call parse-line for each group of four lines.
(assert-list= string=?
              "should parse each group of lines"
              (list "123456789" "123456789")
              (bank-ocr (append all-digits all-digits)))

(define (bank-ocr ocr-lines)
    (if (null? ocr-lines)
        '()
        (append (list (parse-line (take ocr-lines 3)))
                (bank-ocr (drop ocr-lines 4)))))
Moving "in"
bank-ocr was complete but the guiding test told me that there was no parse-line function in the production code and I knew where to go next.
(define ocr-digit-one (list "   "
                            "  |"
                            "  |"))

;; should split and parse first digit
(assert-string= "1" (parse-line ocr-digit-one))
Parsing a line would need to split the line into digits and then parse each digit. I added another two stubbed functions and built parse-line to get the test green.
;; stub
(define (split-digits ocr-line)
    ocr-digit-one)

;; stub
(define (parse-digits ocr-digits)
    ;; use assert-list= to check that ocr-digits is ocr-digit-one
    "1")

(define (parse-line ocr-line)
    (parse-digits (split-digits ocr-line)))
Parenthesis(Actually I was cheating here: I should have checked that the output of split-digits was fed into parse-digits. Nobody is perfect and I will atone for that later, but let's move on for now.) Again a function was finished but I had invented two new collaborating functions to do so.

Another step "outside-in"
Next came testing split-digits to split the three lines into nine digits containing three lines of three characters each.
(define two-ocr-digit-one (list "      "
                                "  |  |"
                                "  |  |"))

;; missing test "should split empty line into no digits"

(assert-list= (list-equals-for string=?)
              "should split single digit"
              (list ocr-digit-one)
              (split-digits ocr-digit-one))

(assert-list= (list-equals-for string=?)
              "should split two digits"
              (list ocr-digit-one ocr-digit-one)
              (split-digits two-ocr-digit-one))

(define (split-digits ocr-line)
    (define (take-3-chars s)
        (substring s 0 3))
    (define (drop-3-chars s)
        (substring s 3 (string-length s)))
    (if (zero? (string-length(car ocr-line)))
        '()
        (append (list (map take-3-chars ocr-line))
                (split-digits (map drop-3-chars ocr-line)))))
I did not start with the degenerate test-case that an empty line, a list of three empty strings, should be split into an empty list of digits. I did not add this test because it did not feel right from the solution's perspective. split-digits would always be called with a full line, i.e. three strings of 27 characters each. But as soon as I tried to get the recursion for the second digit right (as forced by the second test), I struggled because I had to figure out the recursion and termination condition at the same time.

ParenthesisA Functional TDD "Pattern"
There is some obvious pattern here. Consider we need a function that operates on a list of inputs and processing of a single input is either simple or can be delegated to another function. Then we need three tests to drive the implementation of that function:
  1. An empty input should produce an empty output, where empty is defined differently for input and output. This drives the creation of the function header and the body of the (future) termination condition.
  2. A single input should produce a single output. This drives the conditional for the termination condition and the processing of a single input. The processing must be simple otherwise the step is too large.
  3. A list of inputs should produce a list of outputs. This test drives the splitting of the first input from the remaining ones for the recursion.

Coming to an end
The second missing function was parse-digits. It was supposed to work on a list of digits, to parse each of them and return the list of parsed digits so I used my three steps from above.
;; should parse empty digits as empty string
(assert-string= "" (parse-digits (list)))

;; stub
(define (parse-digit ocr-digit)
    "1")

;; test for parsing a single digit omitted

;; should parse digits into numbers for each digit
(assert-string= "111"
                (parse-digits (list ocr-digit-one ocr-digit-one ocr-digit-one)))

(define (parse-digits ocr-digits)
    (if (null? ocr-digits)
        ""
        (string-append (parse-digit (car ocr-digits))
                       (parse-digits (cdr ocr-digits)))))
I skipped step two of my list above and omitted the test for parsing a single digit because I felt confident and delegated the actual parsing of a single digit to another function. parse-digit was the final function and compared a given digit against stored digits to determine the number.
(assert-string= "should parse one"
                (parse-digit ocr-digit-one))

(assert-string= "should parse two"
                (parse-digit ocr-digit-two))

;; etc.

(define (parse-digit ocr-digit)
    (let ((digit (apply string-append ocr-digit)))
        (cond ((string=? digit (string-append "   "
                                              "  |"
                                              "  |")) "1")
        ;; etc.
    )
  )
)
I did not push the final solution of parse-digit. Probably I could remove the duplication using some functional magic, but I had spent some hours already on coding, it was late and I was tired. The full source is available here.

Conclusion
Using Scheme was fun. I had to look up library functions a lot and spent some time on Stackoverflow, but I felt progress all the time. I committed on red, green and refactor, on average each ten minutes, and I was never stuck. The minimalist unit testing function gave me enough feedback to move forward quickly. I did not bother for expressive assertion messages because my steps were small and I never looked at the failures anyway - I knew which test would fail or pass next. Solving Bank OCR was straight forward, probably due to the nature of the assignment. Also knowing the solution - which is not the implementation - helped me a lot and I focused almost entirely on Scheme and the functional aspect.

I was able to do outside-in TDD by stubbing future functions. The stubbing was crude, I just redefined the functions in the test code. I was unhappy with this approach but it worked and I lacked in-depth knowledge of Scheme to come up with a proper way to stub functions. It seemed wrong to pass functions around according to Dependency Inversion Principle, because the called functions were low-level internals and no peer collaborators. In a way I followed Ralf Westphal's approach of True Stepwise Refinement, where he stubbed private functions. In the end I thought about deleting (some) unit tests of the internal functions but did not have any conclusive ideas how to do so.

P.S. for Claus
We had agreed to code together and do some serious product development, and again I spent time on weird ideas like Scheme or Assembly. I am sorry.