BuildStuff 2016: Single Value Objects in .NET – Using structs to build custom scalars a Domain-Driven way

November 21st, 2016

Today I was one of the speakers during the BuildStuff 2016 Kiev conference. The site announced my talk with the following introduction:

This talk focuses on how to make Single Value Objects. Value objects that represent just a single scalar/primitive type using value types/structures as provided by the .NET platform.

Value Objects are essential to Domain-Driven Design, and help to make richer, type safe models. Modelling Single Value Objects as explained during this talk, will make your live easier, because of its lightweightness, and because of its re-usability characteristics (i.e. the behaviour for an IBAN, email address, etc. is unlikely to be different in different domains). It can be widely (re)used both within and outside a Domain-Driven context.

We will deep-dive into how to create a structure in .NET that fulfils these needs, like JSON and XML serialization, parsing, formatting, etc.

I hope my message came across. For those who missed it, or want to view the powerpoint. It can be downloaded here: www.corniel.nl/download

The (prepared) code snippets can be found at my Github repository:
github.com/Corniel/HelloWorld/HelloWorld/Buildstuff2016

The Open (Single Value Object) Source library Qowaiv can be found both on github and NuGet.

If you have any comments, feel free to reply.

Yet another limitation in VB.NET

October 7th, 2016

Visual Basic is not my favourite coup of tea. Today I add an extra reason:

[code=vb]Public Class YetAnotherLimitationInVbNet

Public Function Total(list As List(Of Integer)) As Integer
‘ Return list.Count(Function(n) n < 17) Does not compile.
‘ Return list.Where(Function(n) n < 17).Count() is performing smart not the best option.
Return list.AsEnumerable().Count(Function(n) n < 17)
End Function

Public Function Total(list As IEnumerable(Of Integer)) As Integer
Return list.Count(Function(n) n < 17)
End Function

End Class[/code]

You can not call an extension method (with different) argument if it matches the name of a property. Argh…

Single Value Objects as C# structs

June 8th, 2016

Domain-Driven Design bottom-up – a talk

Some time ago, I decided that would like to be come a speaker at tech events. Speaking about software development is besides coding itself just so fun to do! The talks/presentations a gave for colleagues in the past where always nice, and it was about time to speak somewhere out in the wild. When a friend of mine told me that Searchlite was organizing small events and searching for speakers I did not hesitate, and applied.

The talk was about designing structs to represent Single Value Objects, the most elementary building blocks of your Entities and Value Objects within Domain-driven Design. The idea behind it, is that it results to cleaner code, that is easier to read, maintain and validate, than when you use only the default primitives of your language of choice (in this case C#).

Pitching Qowaiv

It was also the first time that I pitched Qowaiv, an open source .NET library (and NuGet package) that contains some of these Single Value Objects. The (closed source)  predecessor is used by my previous company, and Qowaiv is used within Exact Online, the on-line platform of my current company. But I think that it deserves a wider usage than that, so I gave it a try.

Looking back (and forward)

Overall I think it was an okay talk. The feedback from the audience was positive. Apparently, I was able to to bring the enthusiasm I have for software development in general and this topic in particularity, across. I’m really looking forward to BuildStuff Kiev, where I will be a speaker!

Download

Too bad, there is no live recording of the talk, but you can download the PowerPoint here:
corniel.nl/../2016-06-08_Single_Value_Objects_as_CSharp_structs.odp

Kubisme BlockBattle AI

May 29th, 2016

Coding should be fun. That’s why I like to participate in coding challenges/competitions. Specially those where you have to code an AI (see also: Truusje).

This time I participated in Block Battle by The AI Games.com. It’s name might have given it away (partly), its a (two player) Tetris like battle. You have to play the game of Tetris, and if you play good your opponent will get lines of garbage (and you if he plays well). When one of the two dies, the other wins. Quite simple. I named it Kubisme, Dutch for Cubism.

You know two blocks in advance, the current block to move, and the next one, and the current position of your opponent (he will get the same blocks). When you both have a lot of playing space, the situation your opponent is in is not really important, but that changes when the fields get crowded.

Approach of Kubisme

I most of these challenges speed is key in being successful. That gives you no other option than to represent the board with a bitboard. In my case an array of Int16’s, one short (integer) per line. This allows not only to store a lot of positions in a search tree, but also enables quick manipulations of positions, and calculating scores based on its characteristics.

Move generator

When you do Minimax  search (Alpha–beta pruning) you need also a fast move generator. Here I made a clear distinction:

  1. I have enough space to rotate my block before dropping it
  2. I have a (potentially reachable) hole I can get a block in
  3. I’m running out of space

The vast majority of moves you will find (unless you are running out of space) will come from option 1. The move requested to get this can be pre-generated, you don’t have to find a path, you just scan the board where the block (for every rotation) will stick/fit, and you know upfront how many options there will be. For an O there will be 8, for I, S and Z there will be 17, and for J, L, and T it is 34.

I waited some time before implementing path finding to fill some of those reachable holes. When I did, I implemented as follows: first do a quick scan if there is a (potentially) reachable hole. If there is some path finding to get to that hole (and return that moves before the regular ones as described for option 1). This saves a lot of time, and will have a positive effect on the move generator itself, because it returns this move (what is in most cases an improvement on keeping the hole) before the others.

Search depth

To get good Minimax (with ect…) results you need a branching factor that is not to bad. For the first two ply that is okay because you know which block you have to check. However, I defined per block the number of options I’d tested the child nodes for (an O-block 5 on ply 1 and 4 on ply 2, and for a T-block 14 vs 10 children). For ply 3 I took per node the average of the best response per block, and for ply 4 and higher the average of 3 random blocks. Those random blocks were picked per turn, so that all ply 4 and ply 5 (and sometimes ply 6) nodes tested the same blocks to prevent strange outliers (and because of speed, picking 3 random blocks all the time costs some time). I experimented with skipping the search for reachable holes (just testing the drop blocks only) for ply 4 and deeper. Instead of 350k to 45ok nodes/s it checked up to 750k nodes/s and sometimes reached ply 8, but the the results were (just slightly) better when applying the expensive/extensive search for all nodes, specially after introduction of the T-spin bonus.

Evaluation

As most contesters I experimented with a lot of characteristics of the field and taking them into account. In the version that run during the finals I had basically 15 parameters. Almost all parameters I had were basically a curve on their own:

Score(height) = a * Math.Pow(height, power) + delta

Where a, power and delta were determined in long (local) simulations settings. The parameter that could lead to the biggest addition to the evaluation of its own was the parameter for (double) T-spin potential.

Score(height) = 1.14 * Math.Pow(height, 2.01) + -35
{ -34, -30, -25, -16, -6, 7, 22, 40, 60, 82, 107, 134, 163, 195, 230, 266, 305, 347, 390, 437, 485, 536 }

Where the height in this case was the row where the T-spin potential existed. As you can see, Kubisme gives high values on having a potential (double) T-spin, as long as it is placed low at the field, but at the top, it gives a penalty instead.

To make Kubisme found even more T-spins, the evaluation also valued single T-spin potential, and a bonus for  the two row clear by a T-block.

I also made the distinction between reachable and unreachable holes. A hole was marked as reachable when (at least) at one side two (or more) free cells where reachable. Those values ended up being -26 for reachable ones and -38 for unreachable ones.

Opponent

I tried different ways to take the current state of the opponent into account. All failed. The only thing that worked, is checking of the opponent could be kill within 2 ply, or that Kibisme could kill. Other approaches failed all when I searched more than 2 ply.

Tweaking  parameters

To get the parameters right, I run zillions of games (2 ply per bot) via some genetic algorithm. Doing this with ‘only’ 2 ply, I could run roughly 25 games per second, while with 3 ply that number dropped to just 0.7 games per second.

Weaknesses

Kubisme has at least 3 weaknesses, that I tried to solve but failed on.

  1. If the frequency of T-blocks is (way) lower than expected, it handles positions  worse than most competitors.
  2. In some situations holes where created without any logical explanation. Specially when the first filled row was low, and there where plenty of options to avoid this.
  3. Sometimes it blocked the access to accessible free cells, adding some holes. This leaded to bigger chunks of attaches unreachable holes.

Ouput

To see what Kubisme was doing I tried to make some human readable output:

01/01. +2.55 0.009s ( 0.0kN, 1.8kN/s): {left,left,left,turnleft,left,drop}
01/02. +2.84 0.012s ( 0.1kN, 6.7kN/s): {right,right,right,drop}
01/03. +2.78 0.022s ( 6.1kN, 276.7kN/s): {left,drop}
01/04. +2.88 0.061s ( 31.5kN, 512.0kN/s): {left,drop}
01/05. +3.30 0.243s (127.9kN, 527.3kN/s): {right,drop}
01/06. +3.86 0.990s (562.8kN, 568.6kN/s): {right,drop}

(..)

// cleaning up an hole
10/01. +16.95 0.002s ( 0.0kN, 15.7kN/s): {down,down,down,down,down,down,down,down,down,down,left,left,left,down,turnleft,down,down,turnleft}
10/02. +16.94 0.004s ( 0.6kN, 150.4kN/s): {down,down,down,down,down,down,down,down,down,down,left,left,left,down,turnleft,down,down,turnleft}
10/03. +17.93 0.084s ( 25.5kN, 302.6kN/s): {down,down,down,down,down,down,down,down,down,down,left,left,left,down,turnleft,down,down,turnleft}
10/04. +18.65 0.567s (213.6kN, 376.9kN/s): {down,down,down,down,down,down,down,down,down,down,left,left,left,down,turnleft,down,down,turnleft}

(..)

// Sometimes Kubisme changed his mind more than once
38/01. +31.21 0.000s ( 0.0kN, 70.7kN/s): {turnright,drop}
38/02. +31.31 0.001s ( 0.2kN, 262.9kN/s): {turnright,drop}
38/03. +31.51 0.025s ( 10.7kN, 429.9kN/s): {skip}
38/04. +31.71 0.134s ( 54.5kN, 408.0kN/s): {right,right,right,right,turnright,drop}
38/05. +32.75 0.499s (236.1kN, 473.5kN/s): {right,right,right,right,turnright,drop}

(..)

// Spotted a win in 2
43/01. +27.99 0.002s ( 0.0kN, 12.7kN/s): {down,down,left,turnright,turnright,left}
43/02. +oo 2 0.004s ( 0.4kN, 121.5kN/s): {down,down,left,turnright,turnright,left}

// Spotted a win in 1
44/01. +oo 1 0.001s ( 0.0kN, 41.9kN/s): {down,right,turnleft,down,down,down,turnleft}

Final thoughts

This competition was fun! Special thanks to my friend and colleague Ad (developer of the BBKing bot) for all the nice talks and thoughts shared. It was awesome watching games where Kubisme was totally rocking (like this game against TaroKong where it made an 1.59 point/block average!). When things went bad, because a new version was okay during test runs but failed miserably life, or was just playing crap without any indication why, it could also be some what frustrating.

In the end Kubisme was 6th out of 329 competitors. Just one spot before Ad’s BBKing (main goal anyway ;)) and best Dutch participant. I could have been more lucky in the final, but things could have turned out worse too. Winner artoppod, and hogeris where cleary the two strongest bots. After them, 6 bots had more or less the same level, including Kubisme (and BBKing).

Code

For those who like to see the actual code: https://github.com/Corniel/AIGames.BlockBattle.Kubisme

Exact TechTalks 2016

May 19th, 2016

Machine learning is hot. If my colleague Ad and where not aware before we decided to do our Exact TechTalks 2016 about  applying this on the Exact Online (EOL) domain, we would have been afterwards. Half the board entered our talk, including the CEO at the first session. Zillions of questions by the attendees, and full-house 5 times in row.

Background

It might be wise to point out what these Exact TechTalks where about in the first place. It was an internal event where the different development teams could give 20 minute presentations on a subject they are currently working on. Ad and I represented the EOL System team (responsible for the core libraries and framework of EOL).

So what is Machine Learning?

Specially since AlphaGo beat a human Go player, machine learning and AI became both hot and mythical. So, our main goal was to demystify it, and show with an simple example that it can be easily applied, if you have (good) data.

Machine Learning:

Writing a program to perform a task
With more information, the program performs the task better
Without having to change the code

That’s all. Yes, you can apply it by building complex neural networks, and dedicated server parks, but in most cases, you don’t have to go down that road. A consequence of this is also that without proper data, you will not be able to learn your machine anything.

Allocating bank statements

We showed some functionality that can take up a lot of time while bookkeeping: allocating bank statements. By comparing new imported statements with historical data that was already assigned to a GL-account and an account, in a lot of cases new statements can be matched automatically. A developer has to build some specific matching algorithm to determine which historical record is the closed match. This is called statistical classification.

User experience

Speed is important in this scenario, as a user does not like to wait. In our test set-up we where able to test a new entry against 450 historical records within 0.29 milliseconds, so 1.5 million matches per second. But even more important is how to present the findings of the algorithm to the user. Does a user like to be bothered with poor and potential wrong matches? Or with (almost) identical matches? Not per se. And which options should there be to show the user what was allocated automatically?

Food for thought

Ad and I split our talk in two parts: 10 minutes of talking/presenting, 10 minutes of discussion. Although stated clearly during the talk, still quite some people thought it hard to believe that machine learning could be that simple. Some of them where searching for the silver bullet to solve all issues at once. Spoiler alert: such a bullet does not exist in this case. But most questions and remarks where about the potential issues of matching automatically and by that making mistakes. And that is good! Because how brilliant your algorithm might be, there will be inconsistencies, exceptions, on previous decisions. If you don’t understand the data and/or the domain, you will not be able to come up with a solution.

What’s next?

As members of the EOL System team, this part is not our responsibility. The functional team that is responsible is, guided by us, now working on shipping it. Besides that, a lot of awareness is raised throughout Exact. You should not be surprised if the customer will benefit from that in the near future.

Build Stuff 2015 – shared thoughts

November 22nd, 2015

{Build Stuff}15

After visting the TechDays in 2014, I’d was pleased that a good friend – and former colleague – tipped me about Build Stuff. Visiting the TechDays (formally known as the DevDays) felt more and more as watching a detergent commercial: Now with improved formula.

Wed 18 November 2016

Key Note – the future of programming

Uncle Bob (Robert Martin) had a nice story about the history of computers, software engineers, and software languages, starting with the famous Alan Turing. He ended addressing the issue that software development is becoming so important, that at some moment in time, a bad decision of a developer will kill many (say 10,000) people in one go. This will result in tons of regulations forced on us (developers), and he hoped that we as an industry can be a step ahead of this and come with this upfront. Food for thought.

Categories for the Working Programmer

I really felt clueless after leaving the room. The talk was about Haskell (a ‘hot’ functional language). The speaker showed some elegant math, to prove some generic ways of dealing with iterators/recursive functions within Haskell. But you might expect an answer to question why this is useful to a working programmer…

 Anti-Patterns in designing API’s

There is always a risk in telling people how to do things right by telling what they should NOT do. It was not the best talk ever (may be, because of that), but the examples that were given were nice. In short:

  1. Chauvinist Server: designing the API from server’s perspective failing to hide its complexity behind its API (API designed from the server’s perspective)
  2. Demanding client: client enforcing its special need onto the signature of the API (certain client’s limitation becomes server’s default behaviour)
  3. Transparent Server: server exposing its internal implementation to its clients (server’s underlying or private domain bleeds into the public API)
  4. Presumptuous Client: The client assuming the role of a server and engage in taking responsibilities that cannot guarantee
  5. Assuming Server: Server that assumes the responsibility of tailoring the response based on what it assumes client is (e.g. browser sniffing)

And yes, we as a company have violations of all in our codebase unfortunately.

Evil by Design – casino software

A nice follow up on the key note (I guess it was coincidence) was the talk by Jef Claes. He works for a company that builds and monitors an on-line casino. He started briefly be showing how an event based architecture allows them to monitor the usage in an anonymous way, and allows them to interact with cheaters or addicted users. Besides that, he shared his thoughts about the pro’s and cont’s of working in such a business, and if you should do that, or not. It reminded me about a time a worked on two applications providing consumer credit (for buying cars), something I would not easily do again. A lot of food for thought.

The Liberal Arts Programmer

A talk about learning from other disciplines. Basically, it was an encouragement to read books about things that are not (strictly) related to software (development). There were also some funny slides, including this one:

Company hierarchy: Sociopaths/clueless/losers Company hierarchy: Sociopaths/clueless/losers

Being Meta

A good talk. Code generation (CodeDom, T4), reflection, IL-optimisations, and tooling like PostSharp. The last thing is really something, I’d like to spend time on. If you are not familiar (yet) with the other topics, please do so yourself!

Thu 19 November 2016

Key Note – Coding vs. the Brain: Can’t We All Just Get Along?

Melvin Conway is a hero, but this talk was not his best ever (logically). He revitalised an idea he (and others) abandoned in the 90’s where code could be assembled by dragging controls on a designer canvas, and connect them with lines. His argument to pick this up again was that it could be useful when helping kids from primary school learning to write code. But hie was not convincing at all. Both because the lack of argumentation why this could help, of because of the examples he gave, and the design of the tool he showed. So 1993.

A board game night with geeks

The name of the topic is a bit misleading, as the talk was basically about boolean satisfiability problem solving (aka SAT solving). She showed a nice way of solving a problem that would take (proximally) 90 hours on a regular computer doing it the brute force way, but only a split second using SAT. On top of that she showed a nice way of combining the use of F# sharp for the functional stuff, and C# sharp for some proper plumbing. This all presented with flair, enthusiasm and slides from outstanding quality! (only that last part was already worth the talk)

From Power Chords to Power of Models: Insights from History of Rock Music via Machine Learning

A nice talk, from a not so gifted speaker. In short: he harvested a lot of data from Wikpedia about rock music, build a data model, filled it with the Wikipedia data, and did nice analysis on that. Some nice outcomes where presented with music of the bands, including some nice results, some of which were to be expected (Jimi Hendrix or Bob Dylan was the most influencing musician in the area, based on the analysing method) and some more surprising ones, like Jony Mitchell was the most visionary musician (meaning she was hardly influenced by others, but influenced a lot of them). A nice recently new method of data minding (tokenizing text, by converting words into vectors, with distances to other words in a sentence) looks very promising and could be applied in a a lot of areas!

 Unsafe at any Speed – Successful high performance low latency systems in C#

As you may (or may not) know, in C# (in contrast to VB.NET, and others) can be unsafe. This means that, if using the unsafe keyword, the garbage collector can be bypassed, and direct access to pointers is available. If you know think: Wait a minute, but that is what .NET is about, providing safe code, WITH garbage collection. That is true, but in some scenario’s, speed is key (in this case, real time analysis on video stream made by a camera for medical purposes). The basic idea presented at this talk was how to use this powerful option ONLY for those things that really need all speed you can get, and combine that with the other things that should NOT use be unsafe and handled by the good old garbage collector.

Artificial Intelligence that plays Atari video games: How did DeepMind do it?

A funny talk, about machine learning, only based on the visual output of Atari video games. Not really practical, but who cares?

Lies, Damn Lies and Consulting Lies – The Path to World Domination through Microservices

Worst talk by far. Period!

 Fry 20 November 2015

Mind Mining

This talk was an unpleasant surprise. The original topic of this talk was “Property Based Testing: Shrinking the Risk in Your Code”, but there was a last minute change. The nearby rooms were overloaded, so I stayed. So what was it about? Some USA mining village with a lot of unemployed (former) miners, where educated as programmers. Nice initiative, but not worth 55 minutes of my time.

Mutate your code and reveal you true test coverage

There is always the dilemma of choosing a talk with a talented speaker, and a talk with a interesting subject. The first will always result in a nice session, the second… Well, sometimes you learn something new. Mutation testing is an approach where your use some (sophisticated) tooling to mutate function logic (boolean and/or arithmetical operators mostly) to find unit tests that have no useful assertions. The idea itself is simply awesome, but the achievability is poor. I’d like to get some experience with it, but I would not be surprised (understatement) if it turns out that is just not worth the effort.

Programming with GUTs

Definitely the best talk of the week. Kevlin Henney has all properties a good speakers needs: knowledge,  storytelling, clarifying examples, humour, and a nice voice. The talk was about writing Good Unit Tests. The bottom-line: don’t blindly follow the procedure, but keep thinking. This sounds obvious but it is not. He used testing leap year logic, to make his point. The descriptiveness of the method names, the importance of the refactoring step in the TDD cycle, etcetera.

Goodhart’s law: Once a metric becomes a target, it loses its meaning as a measure.

Goodhart’s law: Once a metric becomes a target, it loses its meaning as a measure.

Are smart systems making us stupid?

The answer is – according to Dylan Beattie – no (as in all headlines with a yes/no question mark). It was more a philosophical, than a software talk, but nevertheless quite entertaining. One of the nice thoughts: Although we make smart systems, we should never make them arrogant, and should be extremely humble when the fail.

Programming For The Criminally Insane

Mark Rendle made a brilliant and hilarious show of the last talk of the conference. His talk had only one purpose: entertainment. He succeeded! I can not remember being a room of software engineers where there was half as much laughing as during this talk. Mark showed some insane languages who where only designed to be fun. Languages such as Brainfuck (only .,<>+-[]), Whitespace (like brainfuck but only with space, tab, linefeed), Shakespeare (reads as a Shakespeare play), INTERCAL (with keywords like PLEASE, COME FROM, GIVE UP) and others. I guess that if you are not a programmer, you would not have any clue…

Sat/Sun 21/22 November

Workshops machine learning with F#

During the weekend there where some nice workshops. Together with Ad and Wilko, I followed the workshop about machine learning. The first day, a lot of struggled with F# as most of us (including me) lacked experience with a functional programming languages in general and F# in particular. It was a nice course, with some classics to work on: OCR, user behaviour prediction, a spam-filter, and an AI using a simple neural network.

Conclusions

Although not all talks reached my expectations, in general it was a great week. The workshop I followed was fantastic, and the congress as a hole was way better than the DevDays (my only reference). The software community is adapting Micro services, and using functional languages (such as Haskell and F#) to write smarter (self learning) systems. Test driven development is adopted widely by the industry (which is good), but there are still a lot difficulties to master. I hope, to be able to get hands on experience with most of the topics, and look forward to evangelise some of these ideas and approaches at Exact!

Programmers pull the cart

November 3rd, 2015

Programmers pull the cart

Exact 10 km (or 5 km) run

September 22nd, 2015

Sometimes, things get out of control.  Always. At least in my life. During a training run, I had a more or less random thought. It let to running event that will take place the 9th of October. So far more than 80 colleagues have signed up.  And than the questions came…

Why did you organize this event?
It all started after one of my pre-lunch training runs this winter. I stopped my GPS watch and noticed that I had run a 9.94 kilometre: “Wow that is almost exactly 10 kilometre. That could be a nice race course.” I decided to give it a go, and thanks to a lot of positive comments, and support for others, it went off.

What are your experiences with organizing this event?
It started small, but (also because of the massive response) ended quiet big. I have some experience organizing (bigger) sporting events, which helped me a lot, and it is a nice way to cooperate with colleagues I don’t work with on a daily basis. The only thing not yet arranged is nice running weather, so fingers crossed for that, for the rest I can’t wait.

What kind of reactions do you get?
In general, everybody was enthusiastic. For some people it was the trigger to de-couch-potato themselves, buy a pair of shoes, and get out to run. For others – like myself – it is a nice way to meet some colleagues during an activity they like to do. And fortunately, there are also some colleagues that don’t care much about running themselves, but like to help out as volunteers. Without them, we would not have the Exact 10 km (and 5 km) run!

Why did you start running?
At some point in my cycling ‘career’, I thought it would be nice to participate in a triathlon (not the full length, but only 500 meter of swimming, 20 km of cycling in 5 km of running). Participating in such an event requires proper training, so I bought some running shoes and started. My results during running test events where promising – the swimming was bad, so no continuation on that part – and from there I got worse: I spend more time running than cycling nowadays.

Why is running your passion? What do you like so much about it?
As mentioned, I both run and cycle. Both have their own up- and downsides. But in general: breathing fresh air, being out there, on your own, feeling your body working its way through, challenging the elements, and the excitement of the speed.

What’s especially nice about running, is that it is so easy to get your ass out. Just change gear, and go. Only a pair of shoes, shorts and a shirt is.  The downside is it’s not a proper alternative for travelling. I live 25 km from the office which can easily be done by bike. I run it sometimes as well , but then others have to take my laptop, clothes and stuff and as a one-way-trip it still takes two hours.

Pleasure is also in the small things. Cycling home through the rain, passing a traffic jam, knowing that you will be home earlier, with a hot shower waiting, or overtaking a (slow) cyclist while running, and seeing the surprised face of the cyclist.

What is your best running achievement? What are you most proud of?
That’s a tough one. But I think that my second place (out of 78) during the Avantri Dijkloop (half marathon) in a new personal record of 1:25:50 (14.75 km/h) is my best achievement (so far). I’m not sure if I’m proud of any running achievement in particular. I have a certain level which allows me to have nice results, but the truth is that on a world scale I’m not special. The world record on the half marathon is 58:23 (21.68 km/h), which is 47 percent faster than my p.b.

What does your running scheme look like? How do you train?
It varies, which should be a good thing. As my main goal for autumn is setting a nice p.b. in a Marathon (I’ll participate at Maratón Valencia, 15 November), the main focus is getting the distance. In practice, with training durations of at least one hour. To improve on pace and technique, I attend track training weekly.  And –because it is fun and proper training – I run some test events, both on the track and on the road.

What are your tips & tricks for our colleagues?
Run as fast as you can, but not faster. That is less trivial than you might think. Finding out what your maximum speed is (for a certain distance) takes time and experience. Most (inexperienced) runners, start way to fast, which is killing for the kilometres to come. Test yourself sometimes during training, and/or use sites like www.corniel.nl/runs to predict your potential based on times at other distances.

Perspective

September 15th, 2015
How users see the programmers v.s. How programmers see the users

How users see the programmers v.s. How programmers see the users

Git

September 5th, 2015

Although Git have been out their for while now, and it has become the de facto standard source control solution, I still think and can use extra advocating. Specially for all those developers that are still not using it (shame on them).

According to Wikipedia:

Git is a distributed revision control system with an emphasis on speed, data integrity, and support for distributed, non-linear workflows. Git was initially designed and developed by Linus Torvalds for Linux kernel development in 2005, and has since become one of the most widely adopted version control systems for software development.

To understand the strength of Git, you have to understand its internals. Those are explained brilliantly by Michael Schwern, in the following video. It will take 1:39, but every minute is well spend! (Thanks to Kraker for mentioning)

If you think you’re ready to get started, you should give GitHub a try. You can find me there: github.com/Corniel.