Sidebar Menu

Projects

  • Dashboard
  • Research Project
  • Milestones
  • Repository
  • Tasks
  • Time Tracking
  • Designs
  • Forum
  • Users
  • Activities

Login

  • Login
  • Webmail
  • Admin
  • Downloads
  • Research

Twitter

Posts by stumathews
Stuart Mathews
  • Home
  • Blog
  • Code
  • Running
  • Gaming
  • Research
  • About
    • Portfolio
    • Info

Pure functions

Details
Category: Code
By Stuart Mathews
Stuart Mathews
11.Jan
11 January 2019
Last Updated: 04 August 2019
Hits: 2832
  • Functional programming

There is a lot of mystery around how languageExt actually works and most of this I think is down to the fact that many of us start from a non-functional background, I think they call this an imperative style of programming or an object orientated style or....whatever.

Functional programming is declarative and less imperative and you can get a geneal idea about this here: Being a bit more functional

LanguageExt is used to deliver some of the benefits in inherently functional language to C#.

What are these benefits you ask? 

  1. Removal of boilerplate code (I'll show you how)
  2. Removal of some classes of errors that are prone to occur without functional ideas
  3. Remove state from code (I'll show you how)
  4. Make code easily parallelizable
  5. Make code produce no side-effects
  6. Same output with the same input
  7. Purely mapping domain → range
  8. Lazy loading ok for evaluating
  9. Can cache result of an input for an already evaluated input value because the function needs not bo run again and we'll always know the result for that input without having to send that input into the function again(if we know the input and the resulting output for that input)
  10. Order of which pure functions is not needed - any order yields the same results.

Let's talk about some concepts.

In maths, you have functions and these are not exactly like c# functions:

y is Add1(x) = x + 1

Exactly 1 input (x) for exactly one output (y) - is a mapping. A mathematical function is a mapping.

You can't have multiple inputs for mathematical functions as you can in c#- it's quite constrained. 

In Mathematical functions, y and x are both immutable and can't change.

if you were to create a c# function that mimicked a maths function, that's a seemingly restrictive function in C# -it would basically mean every single one of your functions could only take on the parameter and that parameter can't change over time and the result of that function can't change over time. Some of these ideas are very useful, however, specifically this requirement or inability for values to change or mutate over time.

A pure function any function(including a maths function) that operates solely on its input ie its parameters (but doesn't change it) and sole produces a result based on its input. Obviously, in a math function, you have exactly one input and exactly one output. In C#, if you wanted to create a pure function(such that the input and output don't/can't change you can do that). That input and that output once defined can't be changed(input can't change when passed in and output can't change once produced by function). Math functions are pure functions, c# function need to be made pure...and I'll show you that later.

The term used is immutability of the input and the output. Immutable can be used/read and operated on but they cannot be written to or modified. 

So if you wrote a c# function that did this, you have a pure function too. 

What pure functions give you are:

  • Same output with the same input - that is, each and every time you pass in input the same output for that specific input is produced.
    • This means its easy to reason about these kinds of functions. More on this later.
    • They dont depend on anything other than the input to produce the function therefore they will never give an alterative result, given the same input
  • No side effects, that is nothing about the input or output changes.
    • This obviously means nothing can't mess up the results later down the road or change them so that others relying on the outputs are affected because they've been changed.
  • Parallelizable, that is running fn(1)=2 or fn(2)=3, in any order or on any thread doesn't affect the results of these functions.
    • That's because these functions are independent of each other, and you can split up the various input into these functions across threads, and each thread will just act on its provided input and produce the respective input and at the end you can take the results of both thread's computation of functions and you have the whole set of results for the whole set of input.
  • Once you know the input and the output for a function, you can cache the input and the output values.
    • if you ever, later on, pass in the same input value, you can use the output value you cached or that input you stored as that function will never produce anything other than the output it produced the first time for the input. This is useful in programming.
  • Lazy loading for evaluating, you can run fn(1)=2 now or fn(1)=2 later, it doesn't matter - it will always result in the same result, ie 2 for input of 1.
    • It doesn't matter at which time(pure functions aren't dependant on time or state or anything that might change those) so you can run them now, or you can pass the function around as a parameter(Higher order functions) and have them executed at a later time and it won't make a difference to the output - the same input produces the same output every time all the time.

You can already see the power of using a pure function in programming, right? 

So some useful benefits of these pure functions if you can get 'em are that you can pass fn(x)=y around as parameters to function, you can put them in lists and you can, as mentioned earlier, evaluate them when you want, now, tomorrow or in five minutes. Generally passing around functions is cool and to this, you need to have a language that supports doing. This feature of a programming language of allowing functions to have other functions as parameters and is called higher-order function) this such as javascript, c# and c/c++(not functional languages), haskell, closure(functional programming languages), to mention a few have this ability to pass functions around is not restricted to passing around pure function(the only functions we've talked about up until now), but any c# functions can be passed around in c# but those that are not pure, don't have the benefits listed above. 

Restricting a C# function to not change its parameters(like ref params or seemingly classes passed in ie. reference types) or in general not being able to have more than one parameter might seem pretty restrictive to get all the benefits mentioned above... Also, the scenario that the function can't produce side effects means you can't call code that could cause side effects:

  1. Code calling IO like querying databases or reading from files or the internet
  2. Code that throws exceptions - as this would mean that for a particular input to a function, you might not get the same result for the input every time. 

That's a pretty dire prospect for a C# application right?

So we understand the benefits of using pure function and using immutable input and output types. But were are aware of the cost of doing this. Let's try and get the best of both worlds. So pure functions don't mutate their input when they use it and they prevent the output they produce from changing. If you don't use pure functions, you can try and maintain this idea of not changing the original input or output using a technique described here: Being a bit more functional but we're digressing a bit because we're talking about writing pure functions which by definition ensure immutability.

Mathematical functions are pure functions by definition and they are representable as Func<IN, OUT> delegates, but as you can see this defines any function that takes in one IN parameter and one OUT result. In math, the input is defined as the domain and the output is the range, in as much as you're producing a range for each item in the domain. Such that this is how you'd represent it in a C# function: Func<domain, range>

So how can you have multiple domain or INs? Theoretically, you can't in pure functions that are modelled like math functions - have one parameter.

Remember mathematical functions only take in one input and produce one output, and we want to maintain this idea for our C# functions but use multiple parameters - sounds impossible, doesn't it?

Side note:

  1. All of this functional programming stuff only really makes if you work with pure functions (no external dependency and input/output to function is immutable)
  2. Exceptions are not liked because they break the mathematical function model (whereby you need to produce an output which is always corresponding to an input…never does this change…exceptions cause this to change )

Generally, this is enough to get you started thinking about why functional programming and pure functions are useful.

You can actually pass multiple parameters to a pure function(woah, but didn't you just say ...) and still keeps the concept of only one input to a function, without any compromises! If your mind is blown by that statement, stick around and I'll show you how. This is done using partial functions. 

This is achieved in two ways,

  1. Pass a single tuple(with multiple items in it) - see we use only one tuple param.
  2. Pass a function as the parameter (this is called currying and I'll explain it later)

Ok keep those tow points in mind (even if they don't make sense)

To thus represent mathematical functions like Func<domain, range> you need a way to be able to pass in multiple parameters as in C# but still maintain this mathematic mapping consistency. Currying allows this:

Func<int, Func<int, Unit» f = x = y ⇒ Print(“{y+x}”)

What this C# declaration is saying is that we have a function f which takes in one int parameter x (as per our requirement) and returns a function as output (as per our requirements). The output is a function which is a function that takes in an int parameter y and adds it to x. So x is available to the 2nd param, ie the function (Func<int, Unit> which only explicitly takes in a int y. The body of the function uses it in the expression y+x and so can access x(and y) and use it sothe function get x for free alongside its already declared y input. Effectively x is baked into Func<int, unit> is returned as output, and when its run, it has x baked into it.

So this is what currying is, it captures the outer input and uses in the output provided. And it allows for passing more than 1 parameter to functions that explicitly take only one parameter.  Currying is a sideline topic for me at the moment and it's not crucial to use it but if you do, you get a pure function with all its benefits.

Perhaps what I'll do is later put an example here but as this is a theoretical discussion of curring and partial function(which uses currying), we'll happily gloss over this for now - perhaps until later.

 You can use functional ideas and notation mentioned above in C# even though C# is not a functional programming language. You can use the C# language.Ext library to simulate many of these ideas and get their benefits. It provides ways to use currying and partial functions and provides ways to prevent state change of input and outputs to functions. It also allows the removing of some boilerplate code such an eliminating for-each and if statements conditionals which are a source of errors.

Read the next part about using Language.Ext  in Functional programming Part 2: Using Language Ext to get an overview of what it offers to C# with respects to functional programming.

Complex or Elaborate

Details
Category: Code
By Stuart Mathews
Stuart Mathews
04.Dec
04 December 2018
Last Updated: 04 December 2018
Hits: 2810

The first programming language I ever learned was C++ and I must say back in the day it was simple and elegant. Now its complex and elaborate - maybe because back in the day I used C++ as perhaps a C with classes - maybe that's what it was. I look at the implementation of lambdas in C++ and it makes me want to throw an enranged wobbely(though they are cool but look terrible).

C, on the other hand is what I've routinely enjoyed to program in because its like the old C++ that I knew – simple and elegant. I think one of the reasons why C came to me so easily is because there is so much you can do in C when you're in Linux that C++ sorta goes by the way-side a bit. Obviously not so in Windows, where C has very much become a back-seat passenger.

That being said both have their flaws.

 Most of my recent career was been windows-based which is strange personally, having been so very much a Linux person(hence perhaps my affinity with C), and I've found the utility of C/C++ lacking in my day job. The last time I used it was when I worked for Citrix. Every oppurtunity since then has been my own personal projects...

I wrote a C library which included an implementation of various C data structures such this basic linked-list and other useful things.

This is primarily because C doesn't have these things by default. Thats bad and good. It good in as much as its something for you to do and bad in that its something for you to do. The language is simple, and it doesn't hurt your eyes as much as C++ does. C++ Looks terribly confusing at times, especially when you start overloading operators, start using generics, templates (though all quite useful) and using multiple inheritance. 

I also incorporated that particular library in a broker service i wrote to study the distributed nature of interconnected components in a network (the broker architectural design pattern).  I enjoyed that, despite it being a time of naivety( in terms of good practice).

The thing is, C doesn't have that stuff, and it doesn't have arguably the best part of C++ which is classes(and perhaps its stricter type rules). Some people would just forget C and go with C++ but I can't seem to make step. They are very much two separate langauges - although quite similar.

I look back at those projects with a bit of annoyance really - I wrote so many bugs and shot myself in the foot on more than one occasion and i never actually use that stuff anymore. I've basically shelved it, particularly my broker which I *think* I had big ambitions for(and perhaps here lies the problem). I really would like to give it another go and improve it...

So you(well maybe me) sit in this middle-ground of having to remember when and how to use either C or C++ every time we think we need to use it. So if its creating a really fast algorithm, I'd be more inclined to write it in C but equally I could write it in C++. If I wanted to design a system of components that connect together – in most cases I'd use classes in C++. If I wanted to interface with Windows DirectX I'd use C++. If I'd want to write Linux kernel code, it would be in C (btw I'd always use if C# if could but this ain't no discussion bout no C#!)

 The main two competing ideas I have is this:

  1.  Linux Kernel is written in C
  2. Game programming is really mostly written in C++
  3. Embedded programming seems to be pretty much the real of both.

 Why not keep at both, well because you can get confused because they are so similar but they are two different languages. I'm at odds with the idea that if I need to write a device driver, I should just re-familiarize myself with C and if I'm writing a piece of 3D simulation, I should reside myself to a weekend of C++ re-familiarization.

 Problem is...well I don't know. Maybe there is no problem? Maybe I should stop worrying about trying to be able to instantaneously be able to switch from one to the other (or in fact any programming language) and reason that perhaps moderation dictates a more case-by-case approach: When you get to Rome, copy the hell out of whatever the Romans are doing, even if they aren't programming in C. Same like when you get to Spain...or Austria or...

 

I guess, at the end of the day, you can't have everything can you? No one thing is the best, it always just depends. And perhaps thats OK, perhaps thats even *necessary. Perhaps you're just your own worst enemy.

 

So what all of this has convinced me is that I'd better start writing a new C library which is better, I should also write my C++ Direct X code and stop considering using OpenGL in C and finally that I should stop thinking so much about this stuff!

 

*still – I like most of C more than I do some parts of C++

Nullable checking in the Wild-West

Details
Category: Code
By Stuart Mathews
Stuart Mathews
27.Nov
27 November 2018
Last Updated: 28 December 2018
Hits: 2712
  • Rants
  • Programming
  • C#

I came across an interesting scenario recently. I am implementing a cache of sorts in some code.

As an aside, this is sort of a wild-west code base - shoot first, ask questions later type of thing. The kind of scenario I've tried to stay away from but business is a funny thing.  Anyway, I mention that because the caching system basically tried to find an entry in the cache and if it doesn't find one it returns null or otherwise the thing it found. 

Now that we've been firing a few rounds from the hip and the fights are now starting to die down. This code started to backfire like that banged up fender-bender you used to hear coughing past you as a kid: Code that expected cache entries to get fetched and retrieved would blow up when they somewhere down the track a null was returned from the cache. That type of thing. 

Actually, now that I come to think about, I don't think nulls were actually ever returned at all. In fact, it was something like we'd always get something from the cache (even if it was an incomplete cache entry which represented a previous cache-miss - I know crazy, what can I say.

So anyway, the problem was when code tried to work on incomplete cache entries, things started to 'blowed-up' (I like this expression -  heard a colleague say that in a stand-up this one time). The solution, well if you want to call it a solution, was to return a nullable cache entry when the entry was not found and stop putting incomplete cache entries in to begin with (that was a stupid idea). 

This meant that the caller looking for a cached item would need to check if the item was found or if the item was null(instead of assuming it would also get something all the time even if it was incomplete). I've already talked about how stupid that was but I digress...

So now, you get an item or you get a null, that means if its a null, the item was not found in the cache. The problem is that most of the code that used the cache now had to check if the item was null if it wasn't then use it, otherwise do something else. So the return type was Nullable<CacheEntry> and you found this a lot:

if (cacheEntry.HasValue) ...

Which is boring after the 3rd time of typing. So while we're in the wild west, I thought I'd made my life easier.

Make an extension method on any nullable type like this to prevent the repetitive carpel-syndrome-inducing code:

 public static class Extensions
    {
        public static bool Is<T>(this T? type, bool expected) where T : struct
        {
            if (type.HasValue && type.Value.Equals(expected)) { return true; }
            return false;
        }
    }

I explained what extension methods were here: Understanding how the Linq query syntax works

So now you can do this even if the data behind the expression was null:

if (Helper.GetInstance().IsPortfolio(statementRetrievalContext.Portfolio).Is(true)
{
...

Now, it's not the smartest code in the west, but heck out here anything goes!

Yee-ha!

More Articles …

  1. Understanding how the Linq query syntax works
  2. Lazy loading
  3. Parameter type validation
  4. Risk mitigation, software design and API Integrations
  5. Filters and Visualisation
  6. XML to Pandas Data frame
  7. Data analysis with Python/Pandas
  8. Being a bit more functional
  9. AWS Elastic Container Service's Task definitions
  10. Mocking out a function with an Action function as parameter

Subcategories

Game Development Article Count:  28

I discovered the realms of game development purely by accident, having picked up a book entitled 'Core Techniques and Algorithms in Game Programming' and discovered a surprising niche of innovation in programming quite unparalleled to my day-to-day needs as a developer. Here optimisation, graphics rendering, and algorithms are used on a totally different level and its very interesting.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Page 6 of 17