Class-less Coding – Minimalist C# and Why F# and Function Programming Has Some Advantages

Summary

Can we use just the native .NET classes for developing code, rather than immediately writing an application specific class that often is little more than a container?  Can we do this using aliases, a fluent style, and extension methods?  If we’re going to just use .NET classes, we’re going to end up using generic dictionaries, tuples, and lists, which gets unwieldy very quickly.  We can alias these types with using statements, but this means copying these using statements into every .cs file where we want to use the alias.  A fluent (“dot-style”) notation reduces code lines by representing code in a “workflow-style” notation.  In C#, if we don’t write classes with member methods, then we have to implement behaviors as extensions methods.  Using aliases improves semantic readability at one level at the cost of confusing generic type nesting in the alias definition.  Extension methods can be taken too far, resulting in two  rules: write lower level functions for semantic expressiveness, and avoid nested parens that require the programmer to maintain a mental “stack” of the workflow.  In contrast to C#’s using aliases, F# type definitions are not aliases, they are concrete types.  New type definitions can be created from existing types.  Type definitions can also be used to specify a function’s parameters and return value.  The forward pipe operator |> is similar to the fluent “dot” notation in C#, but the value on the left of the |> operator “populates” the last parameter in the function’s parameter list.  When functions are written that return something, the last function must be piped to the ignore function, which is slightly awkward.  F# type dependencies are based on the order of the files in the project, so a type must be defined before you use it.  In C#, creating more complex aliases get messy real fast — this is an experiment, not a recommendation for coding practices!  In F#, we don’t need an Action or Func class for passing functions because F# inherently supports type definitions that declare a function’s parameters and return value — in other words, everything in functional programming is actually a function.  Tuples are a class in C# but native to functional programming, though C# 6.0 makes using tuples very similar to F#.  While C# allows function parameters to be null, in F#, you have to pass in an actual function, even if the function does nothing.  F# uses a nominal (“by name”) as opposed to structural inference engine, Giving types semantically meaningful names is very important so that the type inference engine can infer the correct type.  In C#, changing the members of class doesn’t affect the class type.  Not so with F# (at least with vanilla records) — changing the structure of a record changes the record’s type.  Changing the members of a C# class can, among other things, lead to incorrect initialization and usage.   Inheritance, particularly in conjunction with mutable fields, can result in behaviors with implicit understanding like “this will never happen” to suddenly break.  Extension methods and overloading creates semantic ambiguity.  Overloading is actually not supported in F# – functions must have semantically different names, not just different types or parameters lists.  Object oriented programming and functional programming both have their pros and cons, with some hopefully concrete discussion presented here.

Full article on Code Project here.

Advertisements

Luna – Visual and textual functional programming language with a focus on productivity, collaboration and development ergonomics.

Take a look at what these folks are doing.   Very cool stuff!!!

Software design always starts with a whiteboard. We sketch all necessary components and connect them to visualize dependencies. Such component diagram is an exceptionally efficient foundation for collaboration, while providing clear view over the system architecture and effectively bridging the gap between technical and non-technical team members.

However:

Unfortunately, it is impossible to execute the diagram itself, therefore the logic has to be implemented as a code.

Now that’s the part I disagree with, in the sense that, once the code-behind is written, and written in a modular and semantic way, you should be able to visually build the workflows, reduce/map/filter operations from “primitive” blocks, which then become bigger blocks from which you build from, etc.

Function Composition, Function Chaining, Currying, and Partial Functions / Application in F# and Ruby

A while ago I wrote an article comparing / contrasting language elements in Ruby with C# with regards to classes: constructors, destructors, fields, properties, initializers, events, methods, etc.  Ruby however also has a foot in the functional language paradigm, though it requires a certain discipline to ensure that you’re adhering to qualities of a functional programming language such as statelessness and immutability.  However, for purposes of this article, what I am more interested in is exploring how Ruby handles certain concepts that seem to be core to most functional programming languages:

  • function composition
  • function pipelining (chaining)
  • continuation functions
  • currying
  • partial functions
  • partial application

These concepts are all intertwined with each other, and as we’ll see, you can certainly implement these behaviors in Ruby, though not as elegantly as with F# (or other FP languages.)  Incidentally, one of the reasons Ruby gets away with being called an FP language is its support for lambda expressions and the ease in which code blocks yielded to for iteration, application specific handling (like IoC), and so forth.  Again, those are not areas that I’m interested in pursuing in this article because at this point they are part of most imperative languages as well, such as C#, further blurring the lines between imperative, declarative, and functional programming.

Continue reading this article on The Code Project!