News for hackers. Stuff that matters.
Re:The Problem with F# Evangelism by zubspace on Wednesday August 16, 2017 @11:46AM (#15028407)
Good post. I really hoped for some f# code after listing all those scenarios where c# fails.

Anyway. I work in a c# shop with a large monolithic code base developed by a small team with lots of fluctuations over more than 10 years. I have no functional programming experience at all.

I love c# because we actually try to keep the code as simple and linear as possible and only introduce complexity in certain areas if performance requires it. Yes there are hacks and dirty code passages, but if you stick to basic code constructs they are easy to decipher.

If your facing more than 10 million lines of code you start to appreciate simple code. Moreover if different developers, which come and go, are working on it. Living without refactoring and inspection capabilities of resharper is nearly unthinkable to me.

Now, how would you convince someone like me to try out f#?

There are only drawbacks: Obscure things we would need to learn (type classes? monads? xyz?). Probably hard to read, 'clever' code. A mixture of c# and f#. Unknown library, build and deployment issues. And I guess, f# developers are rare around here.

Even after reading this post, there's unfortunately no convincing reason for me and management to give f# a try...

Re:The Problem with F# Evangelism by jasim on Wednesday August 16, 2017 @12:05PM (#15028595)
I'll tell you my experience. I never liked the arguments about reduced bugs or concise code. As a programmer the reason I would use F# (or OCaml, or Haskell, or Elm, or PureScript) is because it increases by day-to-day well-being.

I'm happier writing Typed FP because the system is very concrete in my head as I work with it. In a dynamic language, there is always a nagging uncertainty about the system - if you're using dictionaries to pass data around, you don't have certainty in what keys it'll have, and what data will be available inside it, and what could possibly be null.

When you add a new kind of a domain object (a Guest user in a user management system for example), you have no idea where all you need to handle it. You fix the obvious places, and do a text search, and find a few more. And the rest you fix over time.

The runtime robustness of untyped systems in my experience generally is a function of time. The more it sits in production, the more bugs we discover in the most commonly trafficked codepaths. We fix them - duct tape works - and then it sits and chugs along. (Robustness to change is another matter altogether).

But if you use a Typed Functional language, when you introduce a new domain object the compiler will tell you exactly where they are being used and will refuse to compile till you've made sure you're handling it in all the right places.

Value-based programming (ala Immutability) lets you write code as if you were writing mathematical definitions (high-school mathematics; no category theory or monad). While we can be disciplined about not writing mutating code, there is a real difference between 99% confidence and the second-guessing it entails, and just not having to worry about it at all. Everything is a value. There are no objects/references.

All this adds up to a state of clarity when you program. You don't have to keep second guessing yourselves; you don't have to do defensive checks that makes you feel a little bit ugly inside; you don't have to deploy worrying about the unknown unknowns that can break your system.

Re:The Problem with F# Evangelism by nurettin on Wednesday August 16, 2017 @12:56PM (#15029057)
In Delphi, I hide this kind of complexity behind methods which check everything for nulls and types at runtime. I imagine I'd do the same thing in C#, too. So if I have json = TJSON.parse('{}'); json.Node['something'].Nodes[0].each(procedure(pNode: TJSONNode) begin; list.add(pNode.GetValue<int>()); end); { Nodes and Node properties actually create empty nodes and keep a debug string to show you where exactly your code failed so you can go back and take a look at which assumption was wrong. I then cleanup everything when the main node is freed.

So my point is; it all depends on how you code something, the language may do it at compile time to prevent runtime assertions, but that also comes with extra baggage (I assume you need to write more code to define your types, function call conditions and mappings)

Re:The Problem with F# Evangelism by zubspace on Wednesday August 16, 2017 @01:15PM (#15029247)
Your response raises some intersting points and sounds reasonable. But also kind of too dreamlike.

Is it possible to seamlessly integrate a user managment system in f# into existing c# code? I guess, it's not that simple.

It also reminds me of an experience I had in a former job with C++. There was a very, very experienced senior who wrote a very clever library which allowed us to add varous metadata to domain objects in a a compile-time checked, type-safe and very performant way. When the guy left, everything went downhill and the code from then on was regarded as mysterious black box noone dared to touch.

Somehow I am reminded if this when I read about 'magic' solutions in FP. Is it possible to reach a state with FP where seeing through it all gets too troublesome?

Re:The Problem with F# Evangelism by lmm on Wednesday August 16, 2017 @12:01PM (#15028547)
As someone on the JVM side: I find the biggest advantage of functional programming is being able to replace "magic" - reflection, bytecode manipulation, AOP - with plain old code. If you can get everything you need to get done in plain old C#, you should probably stick with that. But if the most error-prone parts of your program are the cross-cutting concerns and the not-quite-C# you use to handle them - things like error handling, transaction boundaries, audit records, access control, that tend to be done with a "magic" API that doesn't follow the normal rules of the language - then maybe F# could help you by letting you replace those things with normal code. Slightly fiddly code, perhaps, but I'll take fiddly normal code over AOP-style magic any day.

Trivial example: what if you could do away with exceptions but still be able to "bubble up" errors in a lightweight way, so that your error handling still wouldn't get in the way of your straight-through business logic code? "Everyone knows" to never use exceptions as control flow, but it happens by accident anyway - have you hit bugs because of that? (I have). If you could avoid having them in the language, wouldn't that make things simpler?

You have less need to learn things like monads because they're just plain old library code; if need be you can click through to the function definition, just like any other function you call. That for me is one of the big things FP is about: reduce what's in the core language, push stuff out into libraries instead. There are a few language features to learn, sure, but they're language features you wanted anyway. Type classes are a small feature, and boil down to just a slight bit of extra syntax support for the strategy pattern. (Indeed I find most of the FP features come down to taking classic OO principles - SOLID, composition over inheritance, and the like - and actually following through on them).

And maybe as you get comfortable with it you'll be able to turn those 10 million lines into 5 million, or 1 million, or less (and maybe those lines are slightly more complex than the lines they replace, but that's a good tradeoff). Certainly that's what using Scala has felt like for me.

Re:The Problem with F# Evangelism by brianberns on Wednesday August 16, 2017 @12:02PM (#15028566)
Is your programming language unreasonable? or, why predictability is important

http://fsharpforfunandprofit.com/posts/is-your-language-unre...

Re:The Problem with F# Evangelism by AnthonyLloyd on Wednesday August 16, 2017 @12:50PM (#15029005)
This is it for me.

Large projects in OO often end up as mutable monoliths which become harder and harder to work with. New features sometimes require large painful and scary changes. Hacks are irresistible. Of course you need refactoring tools because you have to change many things in many files.

OO promised modularity but the languages never delivered because of their unreasonable design.

Highly reasonable, concise and refactorable code is the answer to complex systems.

Re:The Problem with F# Evangelism by yawaramin on Tuesday August 22, 2017 @11:52PM (#15078398)
> ... more than 10 million lines of code....

https://twitter.com/kot_2010/status/898941837372686336

Re:The Problem with F# Evangelism by skybrian on Wednesday August 16, 2017 @12:15PM (#15028668)
Presumably it wouldn't be with your current project (since it sounds well-maintained and doesn't need a rewrite) but when starting on some other, entirely unrelated project?