|
|
|
|
|
by shadowwolf007
3803 days ago
|
|
Yeah - not surprised the DNX stuff is wonky. It seems like every time there's a new project format the first version is just really awful. I think they really only test it on small almost toy-level projects thoroughly but fully conjecture. That's a very cool project though - what got you going on that? If I could convince my coworkers to not kill me for doing so, I would try to introduce using that at work :-) I've definitely gotten them on to the immutability by default train of thought tho - a lot of people very happy with that mindset considering how much of work has become parallel processing. It's amazing how much faster you can do things like build invoices of thousands of items when you can process the whole thing in parallel :-D My pref has always been command line tbh - getting away from TFS was the best thing that ever happened for me. |
|
Thank you :)
> what got you going on that?
Heh, long story...
I'm a CTO of a healthcare software house in London, we've been developing a very large web-app in C# over the past 10 years. Over the years it has evolved as any project does, but I started noticing more and more that OO was really not the right tool for the job of managing large inter-dependant systems (well, the Java/C# brand of OO anyway). The promise of re-use, decoupling, composition, ... all seemed to be lies. On top of that I started to get a sense of the common bugs that were coming through: null-reference errors being by far the biggest. The in-your-face bugs like null-ref errors are relatively easy to spot though, what becomes more problematic over time is shared mutable state logic errors. They can remain buried for some time.
I'd already had an interest in functional programming piqued by LINQ and Erik Meijer's talks on Haskell. I spent some time learning Haskell and F#, and came to the understanding that the stability and reliability of a system could be massively improved if null didn't exist, if objects were immutable by default, and if functions were pure/referentially transparent. Expression oriented programming became my order-of-the-day, but C# kept getting in the way. Unfortunately I couldn't just drop it and move to F# because our code-base is huge and written in C#.
So that's when I started writing csharp-monad [1], it was my first attempt at bringing functional concepts into C#. It had a couple of problems though, and they were:
* The types were classes, and therefore if a function returned Option<T> then it could still be null
* It followed the '.NET BCL way' of having functions like GetValueOrDefault() - again breaking the safety net that an Option type (for example) is supposed to give.
It had benefits though, primarily that I could make composable computations with the various monads (using LINQ). The problem with that approach was that it quickly bumped up against the rest of the BCL. And, in my case, the rest of our multi-million line C# OO app.
So I mothballed that project to an extent. I'd use it now and again where I had control over a process end-to-end. But it got me thinking, that the main issues I had were:
1. Non-expression based C# constructs (if/else, switch, etc.)
2. OO-heavy core types, like List<T>, Dictionary<K,V>, etc.
3. Whenever I brought in 3rd party libraries that 'did functional', they wouldn't work with my Option type in csharp-monad, or any of my functional types - and they never could because there's no baseline for functional (other than LINQ) in C#.
4. The lack of more expressive LINQ grammar makes it less useful and sometimes more cumbersome than Haskell's 'do' notation or F#'s computation expressions.
1-3 cries out for an equivalent of a BCL for functional constructs. I was under no illusion how big a job that would be, but I could see real value in it: a unified set of types for Option, Either, Try as well as collections Lst, Map, etc.
And once I saw that C# 6 allowed 'using static' I saw that as an opportunity to really create a 'functional BCL' that actually looks like a functional language. A chance to take C# in a more Scala-like direction (which if you think about it, is where it's going, it just doesn't have the libraries to support it). So that's when language-ext [2] was born.Item 4 was more problematic. I couldn't create more LINQ grammar. So I started thinking about it in a different way. Mostly I wanted to create expression oriented code. It was just safer. But with C# OO you always hit that expression boundary. So I thought about how I could control the boundary. Some of that was to build 'matching' constructs into the core types, but that wouldn't deal with all boundary issues. That's where the actor system comes in (LanguageExt.Process [3] ). I'd looked at Akka.net and its very Java-like API horrified me - it looked like C# 1.0. So I took the idea that a LanguageExt Process (an actor) is a fold over a stream. That suddenly created a very powerful idea that I could create packets of pure computation and wrap them with their state, and each message would evolve that state. In one fell swoop it created a better and more controlled OO that can interact with pure functions - and all fully integrated with the functional BCL I'd developed. It also allowed us to start breaking up our monolithic app in a much more controlled way.
So yeah, that's the back story! Sorry if it turned into War & Peace.
Btw, I am in the market for two developers at the moment. So if none of what you just read horrified you, please drop me an email with your CV to plouth AT gmail :)
[1] https://github.com/louthy/csharp-monad
[2] https://github.com/louthy/language-ext
[3] https://github.com/louthy/language-ext/blob/master/LanguageE...