Uncategorized
C# needs to allow us to write code in a more functional, immutable style
Since C# 6.0 is now feature-locked (and I can’t wait) it’s time to start talking about something that might be in the next version, assumedly called C# 7.0.
The big feature for me would be to get C# to help us write immutable code. That means they need to make it easy to write immutable classes (see my last post on Record types) and immutable local variables too.
I propose the following syntax:
An introduction to F#: Part 1
A few days ago I ran an introduction to F# course for colleagues at work. The idea of the course was to explain the basics of F# including syntax, programming style and the FSI window, as well as to get people excited. I didn’t correctly judge how long the presentation would take (people were asking lots of questions as I went, which is good!), so I ended up splitting it up into two parts. Here I am publishing a rough written copy of the presentation, compiled from my notes that I worked from as I talked, for you to peruse. It’s somewhat rough, but for those who were there it should serve as a reminder. Next time we will talk through some worked examples of Fizzbuzz & fizzbuzzbaz, we will cover types (classes, structs, interfaces, enums, records, units of measure and discriminated unions). We will also go through some application design, such as: MVC, DDD, CQRS, WTFBBQ.
Finding overlapping rectangles
This is a classic quick programming puzzle: write a function that, given two rectangles, will determine if the triangles overlap. I found this puzzle over on http://leetcode.com/2011/05/determine-if-two-rectangles-overlap.html, and thought it was worth talking about because the solution is wrong, and it was interesting to me because it shows how thinking about a domain can influence your implementation of behaviour.
The mistake made by the original author is with one of the assumptions / interpretations made during their reasoning process. They said “when two rectangles overlap, one rectangle’s corner point(s) must [be contained within] the other rectangle”. This appears reasonable, given the example below:
Programming interview questions
At my last company I was a team lead and, as such, was one of those responsible for interviewing new candidates. Although I didn’t enjoy the process much, I did become interested in the sorts of technical questions / exercises we could set to get a good judge of a candidate’s abilities.
Developer interviews typically cross a number of disciplines (often arranged in stages) that may include:
- a CV / résumé screening
- a telephone interview
- face-to-face questions and answers
- a technical exercise or written test to be done at home, or to be done in front of the interviewers
SOLID, CQRS and functional dependency injection
I was prompted to write this after reading Mark Seemann’s post (http://blog.ploeh.dk/2014/03/10/solid-the-next-step-is-functional/)
Following Single Responsibility Principle will lead you down the road of having plenty of small classes.
Open Close Principle will lead you down the way of encapsulating the core logic of each type in it, and then delegating all other work to its dependencies, causing most of those small classes to have multiple dependencies.
Exceptions and error logging
At my current work I see an awful lot of code that looks like this:
public class ServiceA : IServiceA { private readonly ILogger _logger; public ServiceA(ILogger logger) { _logger = logger; } public void DoIt() { try { // Do something... } catch(Exception e) { _logger.LogError(e); throw; } } }
At first blush this looks reasonable: it has constructor-based dependency injection, an abstraction, error logging… What could my issue be?
A functional Fizzbuzz
After reading Scott Wlashin’s post (http://fsharpforfunandprofit.com/posts/railway-oriented-programming-carbonated/) on writing FizzBuzz in a more functional style and with the ability to have more rules (other than 3 => fizz, 5 => buzz, etc) I decided to give it a go myself. This represents the most idiomatic F# I could come up with, and I think it reads pretty well. It uses partial application, list operations, shorthand match-expressions-as-functions and option types.
let carbonate rules i = rules |> List.choose (fun (divisor, replacement) -> if i % divisor = 0 then Some replacement else None) |> function [] -> string i | list -> String.concat "" list let carbonateAll rules = List.map (carbonate rules) let fizzbuzzbazz = carbonateAll [3, "fizz"; 5, "buzz"; 7, "bazz"] fizzbuzzbazz [100..110] |> printfn "%A"
See if you can follow how it works.
Automatically finding missing and duplicate files in CSProj (Revisited)
As promised in I have come back to the problem of detecting errors in Visual Studio project files. I have updated the script to now report CS files that are on disk that do not appear in the list of included (and compiled) files in the Project. This has a few limitations, including that it only works with CS files (although the script could be easily amended to look for any file extension you like).
Starting afresh
Some of you may know that I recently started a new position at asos.com. I meant to write about my experiences here a lot earlier, but free time has not exactly been in abundance these last two months. In short: the codebase has its problems but I’m really enjoying it.
First of all: the environment. The ASOS offices are located in Camden, London. This is a cool place to be (the eating to be had around here is simply amazing) and is a convenient 10-minute walk > 15-minute train ride > 10-minute walk from my house (not a bad commute for central London!). The offices are not quite as nice as those at my last company, but that place was pretty hard to top:
- The main atrium
- The escalators up from reception to the “Sky Lounge”
- The reception for my floor
.
Asos looks more like this:
- Upstairs seating area
- Behind the reception
- The cafeteria
- The main atrium
Automatically finding missing and duplicate files in CSProj
It’s not uncommon for your CSProj files to become corrupted, or at least invalidated, during a merge. This typically happens when merging two relatively large pieces of work and often takes the form of:
- Files referenced in the CSProj that do not exist on disk
- Files that exist on disk, are needed for the project to compile but are not included in the CSProj
- Files that are on disk and are included, but multiple times
Since this can be quite a pain to fix (the process involves loading the project in Visual Studio and trying to build, getting an error in the concerned project, fixing and trying again) I wrote a simple Powershell script that will analyse your CSProj file and will return all the duplicate file includes as well as all the included files that do not exist on disk. This is a solution for points 1 and 3 above only, as point 2 (finding files on disk that are not included in the CSProj) is a slightly harder problem. I will come back to that in a later revision of the script.
This works well (it’s extremely simple) at displaying errors in your Proj file, but so far you must actually solve the problems manually. It strikes me that actually fixing the CSProj file could also be done automatically, so I am going to revisit this soon (any automatic fixes will, of course, be displayed before they are actually performed and will require the user’s consent to continue).
Here’s the script, I’ll see you back here soon for the two extra features mentioned above.
Param( [string]$filePath = $(throw "You must supply a file path") ) $xml = ([xml] ( gc $filePath )) $filesIncluded = $xml.Project.ItemGroup.Compile | select -ExpandProperty Include $invalidPaths = foreach($path in $filesIncluded) { $fullPath = Join-Path (split-path $filePath) $path if(-not (test-path $fullPath)){ $path } } $uniquePaths = $filesIncluded | select –unique $duplicatePaths = Compare-object –referenceobject $uniquePaths –differenceobject $filesIncluded ` | select -ExpandProperty InputObject if($invalidPaths) { "" "---- Invalid paths ----" $invalidPaths } if($duplicatePaths) { "" "---- Duplicate paths ----" $duplicatePaths } if((-not $invalidPaths) -and (-not $duplicatePaths)) { "=> No errors found in $filePath" } ""