Showing posts with label f#. Show all posts
Showing posts with label f#. Show all posts

Saturday, 29 March 2014

F# Type Providers

Solving F# problems at a Skills Matter session earlier this week allowed me to fully appreciate the power of the Type Provider. The task can be found here for those interested: https://github.com/tpetricek/Dojo-Type-Provider-Treasure-Hunt

The aim of this post is not to provide the solution to the problem but to underline useful of the type provider - which was the ultimate goal behind the exercise. Type Providers succeed at bridging the gap between code and data. Type providers makes data easy to navigate by extracting the schema and publishing it through intellisense.

This is a gift for developers who are used to working with static types. Type Providers have been written for all the most popular data sources, so you can perform tasks against almost anything as though it had already been translated into domain objects. This is often the goal of an ORM, to abstract away the plumbing of persistence interaction. However, Type Providers are more data-driven rather than being a 'code first' affair. You specify the source of the data and the Type Provider will do the heavy lifting of examining the schema, taking the naming conventions and sample data and presenting the developer with a suitable API to explore.

If you were to try to do this with an ORM you would need to create the DTO classes yourself and plug them into the Data Context (or equivalent). Type Providers are productivity boosting in this sense as they require very little bootstrapping.

The power of intellisense:




Type Providers have done what WCF Web Services did - making strongly typed data access possible over a network - but has liberated the publisher of that data to do so in whatever format they choose. Previously, if you wanted your data to be discoverable to the developer in the IDE you would have needed to create a Web Service wrapper around your data and model all the types yourself. Now you can just provide direct access to the data source and let Type Providers do the rest!

I'm yet to make use of FunScript but this looks like a great implementation of a Type Provider - applying the same principles to the html DOM API. Meaning you can create strongly typed web pages! It even includes common js libraries so you can create rich SPAs and interact with your domain with the same workflow and familiarity across both contexts.

Friday, 10 January 2014

Why Functional Programming?

I was in attendance at FPDays2013 to hear Bodil Stokke's talk: Programming, Only Better. I revisited this talk recently in order to put together the case for functional programming and F# to my colleagues. The first part of my presentation is largely taken from Bodil's talk, so this is basically a transcript with a couple of points from different sources. Primarily Scott Wlaschin's F Sharp for Fun and Profit.


Programming Techniques

We strive to make it simple to create programs. We use technology, tools and techniques to make programs better and to make better quality programs. The most basic tool we have is our own reasoning. Other techniques include testing, pair programming & code reviews. We'll explore 2 of things.

Reasoning - We reason about code when we are trying to infer what it will do. We reason to better understand what is going on. Debugging is the most tangible form of reasoning. Typically, we are following the code path and understanding the flow of data. In every program we write we have to reason about what the code is doing. In its most basic form, we are walking through the program in our minds.

Testing - while we can be sure that programs are always reasoned about - they are certainly not always tested. That is because testing is useful, but limited. Testing can only show you the presence of bugs, but never their absence. TDD is based around this fact. The Red; Green; Refactor; process highlights the presence of a bug as the code is not yet written to perform this task - so the test fails. Writing the code to make the test pass is the process of removing a bug. Just because a system has 100% code coverage it cannot be said to be 'bug free'.


Programming Difficulties

Programming is difficult largely because programs grow to be complex. Code volume also makes it difficult to maintain programs, but volume and complexity are not necessarily linked. Its very easy to create an overly complex program without applying thought to its design. Simplicity is much harder to achieve. We'll look at one source of complexity:

State - object oriented languages idealise encapsulated state. OO languages are useful precisely because we use more code to manipulate an object's state. So state changes with time - known as entropy in the mathematical world. Most of the time, we are intentially changing state in a useful way. But state is also permitted to be changed by something outside our control (unless we are very careful). The code example below highlights what it means to have an object enter a 'bad state' and not have that communicated back to the calling code.


State Spoils Testing - how can you test an object in all its possible states? You can only test for the states you think the object might enter into. State increases exponentially, so the more potential state you create, the lower the meaning of your tests!

State Spoils Reasoning - state allows for unpredictability. You can never be sure that you will get the same output with the same input. An objects state can change, so how can you be sure of it at any given time? This becomes even worse when you consider concurrent programs. It is much harder to describe the control flow of a program concurrent stateful program. In OO you have to use Locks to be able to protect against unwanted state change. This is cumbersome, inefficient and still imperfect.


Functional Languages

What can they do to help? They idealise Referential Transparency. RT means dealing with inputs and outputs. A function just maps an input to an output.

Predictability - is guaranteed in a functional language because you will always get the same output for the same input. It can be thought of as nothing more than a glorified switch statement!

No Side Effects - as there is not state! There are no variables in pure functional languages, only values. Once a value is created, it cannot be change. Values can be created local to functions, but that function is also immutable and cannot be changed. State is instead managed by passing values around as inputs and outputs. When you think about it, it doesn't make sense to want to change a value you have set. What makes sense is to simply set a new value. This is essentially what functions do.


State

What happens when we have no state? Reasoning becomes much simpler! Predictability makes programs easier to understand. Tests also becomes more meaningful for the same reason. However, your tests are still unable to tell you that bugs do not exist, and they are only meaningful for the inputs you are testing with.

Optimizing - once you realise that output will never change for a given input, you understand that it no longer matters what order functions are called in. This allows you to perform functions in parallel, such as map reduce. Lazy Evaluation also becomes possible, because you know it doesn't matter when you call a function - the result will always be the same for the give input. Caching is more widely permitted for the same reason. Also, as there are no side effects, it means that you can be sure nothing is going be changed from underneath you! This makes concurrent programs easier to manage, as you don't need to worry about race conditions and lock objects.


Conclusion

The techniques we use to help delivery quality software are undermined by state. Functional Languages remove state from the programming paradigm and in doing so prevent an entire class of bugs from ever entering our code. Functional programming makes our code easier to understand because of its predictability and has greater potential to optimize.


Thursday, 6 June 2013

Implement a C# Interface in F#

Whilst seeking ways to learn F# and weave it into predominantly C# projects I have started to implement interfaces written in C# with an F# version. That sometimes means re-writing a C# implementation with an F# implementation. It works particularly well for a number of reasons:

Motivation - Provides direction rather than just 'hacking about' with the language.

Confidence - If you have test coverage, you can use the same tests to be sure your code is working.

Syntax - Provides a sound introduction to the indentation and parenthesis use in F# by forcing you to translate your own C# code.

Insight - Helps to reinforce that F# still compiles to IL underneath and is executed on the CLR - its all .NET after all!

Communication - Helps others to learn by examining the 'before' (C#) and 'after' (F#) implementations.

Seamless - Integrates with your existing C# solution when using dependency injection and IoC maintaining your decoupled architecture.

In F#, interfaces are implemented Explicitly as opposed to Implicitly in C#. This means that we must provide pointers to the functions we wish to fulfil the interface per method or property. The Gist below provides examples of the various signatures we would expect to implement.