NoVA Code Camp Wrapup and Thoughts
Lessons Learned For Me
Some of the things I came away with is that I need to schedule a little better. I would have much preferred to have the F# and Foundations of Functional Programming talk come first as it would give people more of a basis of what functional programming is and how it is expressed in a more pure functional language in F#. Next time I should be a bit more upfront about this and get the schedule changed accordingly. Two sessions in a row is a situation which could be improved as well.
Functional C#
The first talk I gave was on Functional C#. This was to take the ideas of the more pure functional programming of Haskell, OCaml and F#. To bring these ideas and apply them in a C# ish manner. Some of the things in functional programming languages such as pattern matching isn't an easy concept, so, there are things that can apply and some things that don't.
Some of these lessons include:
- Immutable types
Focus on immutable types and opt-out mutability instead of mutable by default and opt-in immutability such is the case in C# versus F#. Remember, I've been talking about this in context of multi-threaded, parallel programming where this is absolutely crucial to mutate in very controlled circumstances, putting them in isolation. This also applies to the Domain Driven Design world where I was coming from in regards to Value Objects and supple design.
- Side Effect Free (Pure) Functions
The idea here is to control the side effecting in your system. Ideally in the functional programming world, when you call such a function as myList |> List.map (fun x -> x * x) will return another list and not the list you gave it with mutated state. This is important once again as we get into the concurrent programming paradigm to focus on method purity and follow the Command Query Separation (CQS) principle. Once again, this has roots in Domain Driven Design as well when following Intention Revealing Interfaces and Supple Design.
- Functions as First Class Types
The delegate in the .NET world has made the function pointer a first class citizen. With the use of extension methods, generics and lambda expressions, we are now able to take full advantage of performing such critical computations as Reduce, Filter, Map and other High Order function operations. Other areas in this realm include Currying and partial application of functions.
- Lazy Evaluation
In functional programming we have the ability to specify infinite ranges, such as all Fibonacci numbers or some other number sequence. The last thing we'd want is to evaluate that and get the length. Haskell takes the approach of be lazy by default. But that's not practical in a framework like .NET when we want deterministic behavior in the execution order of our code. So, instead, languages like C# and F# are eager evaluators. But, that doesn't mean we cannot take advantage. In fact, when we talk about .NET 2.0 and beyond, such things as IEnumerable<T> is a somewhat lazy execution model when we only calculate when we call the MoveNext() function and so on for each value in the collection. So, when you think about it, LINQ follows that delayed execution model and is pretty powerful for doing large sequences and evaluation.
So, as you can see, there are quite a few lessons the C# developer can learn from functional programming and F#. The key really is when to apply this knowledge and marry the ideas of OOP and FP in a cohesive manner. Speaking of which, Anders Hejlsberg was recently on Software Engineering Radio Episode 97 to talk about the past, present and future of C#. In there, he talked about some of the more functional programming ideas that have been incorporated into C# and a focus on immutability, and how we can make concurrent programming easier. Definitely not time to stick a fork in C# just yet, as I think there are plenty of ideas yet to come to express some of these problems a little bit better. In my ext post, I'll dive a little deeper into Anders' appearance on SE Radio and some of the interesting things going on around static versus dynamic typing.
Introduction to F#
My second talk for the day was on an introduction to functional programming with F#. This was more of my bread and butter presentation on explaining functional programming as I have with my Adventures in F# series. From this presentation, I focused on many of the 101 level aspects of functional programming and how they are implemented in F#. Of course there was some deviation as I explored some of the features that are more library based and exclusive to F# (async workflows, quotations, etc).
Often, the question comes up with the value proposition of F#. Yes, many can get behind many of the ideals of the language and would rather have C# adopt most of these features and not have to learn another language. This to me strikes me as a bit sad that many people are not stretching their wings outside of their comfort zone of the MSDN help files and their language of choice. Learning a new language with a new paradigm is essential to learning. This doesn't mean learning C# coming from VB.NET, but instead, gravitating towards functional programming with a language that fully supports it (F#, OCaml, Haskell, Erlang, Lisp/Scheme, etc), or towards a dynamically typed language (Ruby, Python, etc). Then once you have fully understood and become more fluent in said paradigms, you can learn those lessons and help express your solutions to your problems in more interesting ways.
But, back to F# for a moment here. What is the value of F# and why use it?
- Concurrency Programming Is Hard
It is hard, and don't let anyone fool you otherwise. With locks, mutexes and so on, it is literally impossible on a dual processor machine to have a concurrent program. Period. Instead, with a focus on immutability, side effect free functions, asynchronous workflows, the ideas of concurrent programming becomes a bit easier. Without the first two, concurrency is quite difficult. Messaging is first class through the use of the Mailbox patterns and lessons learned from Erlang.
- Representing Data Can be Hard
With the ideas of tuples, records and discriminated unions, F# gives you a powerful new way of representing your data succinctly. Then to be able to use such techniques as pattern matching against them makes for an even more compelling case.
- Creating Other Languages Is Hard
F# has a firm foundation as a language used to create other languages. With first class support of lexer generators and yacc parsing, tokenizing and parsing becomes a bit easier. Also, the inclusion of quotations as a part of the libraries make it possible for really interesting metaprogramming constructs, such as Tomas Petricek's journey into AJAX and metaprogramming.
Teaching Versus Speaking
D'arcy Lussier had an interesting post which took at Scott Bellware tweet about teachers versus speakers. It's a pretty good post, but I enjoy the comments a bit more on the subject. So, when you get up in front of that podium, just think, are you just another speaker, or are you being a teacher? Is it a dialog or death by PowerPoint?
Wrapping It Up
It was another great experience at this code camp, but I think the one hour sessions just aren't enough sometimes to fully get into any particular subject. I sometimes leave a session wanting, not because the presentation wasn't good, but there wasn't enough time to fully express the full intent of it. I could have gone on and on for hours about functional programming and F# for quite some time as I barely scratched the surface. Maybe in the future, there will be a better venue for this, but I hope to get more in depth in future iterations.
Don't forget that I'll be at Philly ALT.NET this Wednesday night for an F# presentation and then Thursday night is the DC ALT.NET meeting in Alexandria on Applying Lessons Learned from Common Lisp with Craig Andera!