Pure functional programming in D - functional-programming

To my mind the power of functional purity is when deep code paths can be verified as side-effect free. What are people's experiences in the scale of the code tree that can be inside a pure specifier, and what of the level of code reuse?
A few things I spotted:
std.algorithm is mostly not marked as pure, but could potentially be largely pure, either by a pure version of algorithms demanding purity of the instantiating function or mixin, or else by the purity specifier itself being statically polymorphic.
Useful convertors like to!string( someInt ) aren't currently pure.
User defined structs seem to have problems (as illustrated below) with:
1. pure destructors on a nested struct
2. a pure postblit function even on a non-nested struct
The following code currently gives multiple errors on DMD 2.052 win 32-bit
struct InnerStruct
{
pure this(this) {}
pure ~this() {}
}
struct OuterStruct
{
InnerStruct innerStruct;
pure this(this) {}
pure ~this() {}
}
pure void somePureFunc()
{
OuterStruct s1 = OuterStruct(); // pure nested destructor does not compile
OuterStruct s2 = s1;
InnerStruct is1 = InnerStruct(); // pure non-nested destructor seems to compile
InnerStruct is2 = is1; // pure non-nested postblit does not compile
}
void main()
{
somePureFunc();
}
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'
pure_postblit.d(20): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '~this'
pure_postblit.d(17): Error: pure function 'somePureFunc' cannot call impure function '~this'

In theory the point of pure in D is that it's supposed to allow guarantees that a function is side effect free regardless of how that function is implemented. There are two kinds of purity in D:
All functions marked pure are weakly pure. They may not access any global mutable state (global variables, thread-local variables, static variables, etc.) or perform I/O. They may, however, mutate their arguments. The point of these functions is that they may be called from strongly pure functions (detailed below) without violating the guarantees of strong purity.
All functions that are weakly pure and do not have any arguments with mutable indirection are strongly pure. The const and immutable type constructors can be used to guarantee this. (When dealing with structs and classes, the this pointer is considered a parameter.) Strongly pure functions have all of the nice properties that functional programming people talk about, even if they're implemented using mutable state. A strongly pure function always returns the same value for any given arguments and has no observable side effects. Strongly pure functions are referentially transparent, meaning their return value may be substituted for a call to them with a given set of parameters without affecting observable behavior. Any strongly pure function can be safely executed in parallel with any other strongly pure function.
Unfortunately the interaction between generic code and pure (as well as const and immutable) is rather poor. There have been several proposals to fix this, but none have been accepted yet.
\std.algorithm is written to be as generic as possible, so it can't require that its lambda functions and the ranges it accepts be pure. Furthermore, the type system features that were added in D2 are generally the most buggy features in the language, because more basic things have been prioritized ahead of fixing the relevant issues. Right now, pure is basically not usable except for trivial cases like std.math.

Related

Functions with no side effect but with readonly access to state

Considering the common definition of pure functions:
the function return values are identical for identical arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams)
the function application has no side effects (no mutation of local static variables, non-local variables, mutable reference arguments or input/output streams).
What are the implications of using (only) impure functions that still have 2 but do not have 1, in the sense that they can read the current value of (some) immutable state, but can not modify (any) state ? Is such a pattern have a name and is useful or is it an anti pattern ?
An example can be using a global way to get a read only immutable version of a state, or passing as an argument a function that return the current immutable value of a state.
(Rationale - I have been trying to structure my (C#) code in a more functional way, using pure functions where possible (as static members of static classes).
It quickly became obvious how complex and tedious it is to pass state values to these pure functions even when they only need to read the value. I need to know the relevant state value at the point of calling and that often means passing it around through parts of the code which have no need to know it otherwise.
However if for example I initialize such static classes with an internal member function that can return the current immutable value of the state, other members can use it instead of having that value passed to them. And This pattern has greatly simplified my code where I used it. And it feels like I still get most of the benefits of isolating state changes etc)
An potentially impure operation without side effects fits the description of a Query in Command-Query Separation (CQS) - a decade-old object-oriented design principle.
CQS explicitly distinguishes between operations with side effects (Commands) and operations that return data (Queries). According to that principle, a Query must not have a side effect.
On the other hand, CQS says nothing about determinism, so a Query is allowed to be non-deterministic.
In C#, a fundamental example of a Query is DateTime.Now. This is essentially a method that takes no arguments - which is equivalent with unit as an input argument. Thus, we can think of DateTime.Now as a Query from unit to DateTime: () -> DateTime.
DateTime.Now is (in)famously non-deterministic, so it's clearly not a pure function. It is, however, a Query.
All pure functions are Queries, but not all Queries are pure functions.
CQS is a nice design principle, but it's not Functional Programming (FP). It's a move in the right direction, but you should attempt to have as few non-deterministic Queries as possible.
People often tend to focus on avoiding side-effects when learning FP, but it's just as important to avoid non-determinism.

Objects Referential transparency for functional programming in Java 8

I have been studying functional programming and one of the requirements is that they are pure in the sense that they only return the computed value and not touch anything else or throw exceptions, they don't also access shared mutable objects - this makes them inherently thread safe.
So then what would be the correct approach to implement a pure function that takes objects as arguments rather than primitive values. Would I have to deep clone them when passing to a function ?
If the function is a pure function, i.e. does not modify existing objects, whether they are passed as parameters or lying around somewhere else, there is no sense is copying or cloning the argument objects.
You could also see it the other way round: if cloning arguments is necessary, the invoked code is not functional and cloning the arguments doesn’t turn it into functional code, it’s actually working around a design flaw.
In the best case, you would be working with immutable objects which prevent modifications intrinsically, however, using immutable objects doesn’t change the way how the functional code should behave, they just enforce some aspects of it. When a particular class does not offer immutable objects, you can still use it in the right way, without the need to re-implement it in an immutable way.
Generally, it is not a good idea to develop your code assuming that all other code will misbehave and that it was your code’s task to solve the issues of that misbehavior.
The objects should ideally be immutable. Immutability and functional programming go hand-to-hand.
If having all immutable objects isn't feasible, yes, you would ideally need to make deep copies of everything to ensure changes to them don't effect anything else outside of the function.

Do purely functional languages really guarantee immutability?

In a purely functional language, couldn't one still define an "assignment" operator, say, "<-", such that the command, say, "i <- 3", instead of directly assigning the immutable variable i, would create a copy of the entire current call stack, except replacing i with 3 in the new call stack, and executing the new call stack from that point onward? Given that no data actually changed, wouldn't that still be considered "purely functional" by definition? Of course the compiler would simply make the optimization to simply assign 3 to i, in which case what's the difference between imperative and purely functional?
Purely functional languages, such as Haskell, have ways of modelling imperative languages, and they are not shy about admitting it either. :)
See http://www.haskell.org/tutorial/io.html, in particular 7.5:
So, in the end, has Haskell simply
re-invented the imperative wheel?
In some sense, yes. The I/O monad
constitutes a small imperative
sub-language inside Haskell, and thus
the I/O component of a program may
appear similar to ordinary imperative
code. But there is one important
difference: There is no special
semantics that the user needs to deal
with. In particular, equational
reasoning in Haskell is not
compromised. The imperative feel of
the monadic code in a program does not
detract from the functional aspect of
Haskell. An experienced functional
programmer should be able to minimize
the imperative component of the
program, only using the I/O monad for
a minimal amount of top-level
sequencing. The monad cleanly
separates the functional and
imperative program components. In
contrast, imperative languages with
functional subsets do not generally
have any well-defined barrier between
the purely functional and imperative
worlds.
So the value of functional languages is not that they make state mutation impossible, but that they provide a way to allow you to keep the purely functional parts of your program separate from the state-mutating parts.
Of course, you can ignore this and write your entire program in the imperative style, but then you won't be taking advantage of the facilities of the language, so why use it?
Update
Your idea is not as flawed as you assume. Firstly, if someone familiar only with imperative languages wanted to loop through a range of integers, they might wonder how this could be achieved without a way to increment a counter.
But of course instead you just write a function that acts as the body of the loop, and then make it call itself. Each invocation of the function corresponds to an "iteration step". And in the scope of each invocation the parameter has a different value, acting like an incrementing variable. Finally, the runtime can note that the recursive call appears at the end of the invocation, and so it can reuse the top of the function-call stack instead of growing it (tail call). Even this simple pattern has almost all of the flavour of your idea - including the compiler/runtime quietly stepping in and actually making mutation occur (overwriting the top of the stack). Not only is it logically equivalent to a loop with a mutating counter, but in fact it makes the CPU and memory do the same thing physically.
You mention a GetStack that would return the current stack as a data structure. That would indeed be a violation of functional purity, given that it would necessarily return something different each time it was called (with no arguments). But how about a function CallWithStack, to which you pass a function of your own, and it calls back to your function and passes it the current stack as a parameter? That would be perfectly okay. CallCC works a bit like that.
Haskell doesn't readily give you ways to introspect or "execute" call stacks, so I wouldn't worry too much about that particular bizarre scheme. However in general it is true that one can subvert the type system using unsafe "functions" such as unsafePerformIO :: IO a -> a. The idea is to make it difficult, not impossible, to violate purity.
Indeed, in many situations, such as when making Haskell bindings for a C library, these mechanisms are quite necessary... by using them you are removing the burden of proof of purity from the compiler and taking it upon yourself.
There is a proposal to actually guarantee safety by outlawing such subversions of the type system; I'm not too familiar with it, but you can read about it here.
Immutability is a property of the language, not of the implementation.
An operation a <- expr that copies data is still an imperative operation, if values that refer to the location a appear to have changed from the programmers point of view.
Likewise, a purely functional language implementation may overwrite and reuse variables to its heart's content, as long as each modification is invisible to the programmer. For example, the map function can in principle overwrite a list instead of creating a new, whenever the language implementation can deduce that the old list won't be needed anywhere.

Defining point of functional programming

I can enumerate many features of functional programming, but when my friend asked me Could you define functional programming for me? I couldn't.
I would say that the defining point of pure functional programming is that all computation is done in functions with no side effects. That is, functions take inputs and return values, but do not change any hidden state, In this paradigm, functions more closely model their mathematical cousins.
This was nailed down for me when I started playing with Erlang, a language with a write-once stack. However, it should be clarified that there is a difference between a programming paradigm, and a programming language. Languages that are generally referred to as functional provide a number of features that encourage or enforce the functional paradigm (e.g., Erlang with it's write-once stack, higher order functions, closures, etc.). However the functional programming paradigm can be applied in many languages (with varying degrees of pain).
A lot of the definitions so far have emphasized purity, but there are many languages that are considered functional that are not at all pure (e.g., ML, Scheme). I think the key properties that make a language "functional" are:
Higher-order functions. Functions are a built-in datatype no different from integers and booleans. Anonymous functions are easy to create and idiomatic (e.g., lambdas).
Everything is an expression. In imperative languages, a distinction is made between statements, which mutate state and affect control flow, and expressions, which yield values. In functional languages (even impure functional languages), expression evaluation is the fundamental unit of execution.
Given these two properties, you naturally get the behavior we think of as functional (e.g., expressing computations in terms of folds and maps). Eliminating mutable state is a way to make things even more functional.
From wikipedia:
In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast with the imperative programming style that emphasizes changes in state.
Using a functional approach gives the following benefits:
Concurrent programming is much easier in functional languages.
Functions in FP can never cause side effects - this makes unit testing much easier.
Hot Code Deployment in production environments is much easier.
Functional languages can be reasoned about mathematically.
Lazy evaluation provides potential for performance optimizations.
More expressive - closures, pattern matching, advanced type systems etc. allow programmers to 'say what they mean' more readily.
Brevity - for some classes of program a functional solution is significantly more concise.
There is a great article with more detail here.
Being able to enumerate the features is more useful than trying to define the term itself, as people will use the term "functional programming" in a variety of contexts with many shades of meaning across a continuum, whereas the individual features have individually crisper definitions that are more universally agreed upon.
Below are the features that come to mind. Most people use the term "functional programming" to refer to some subset of those features (the most common/important ones being "purity" and "higher-order functions").
FP features:
Purity (a.k.a. immutability, eschewing side-effects, referential transparency)
Higher-order functions (e.g. pass a function as a parameter, return it as a result, define anonymous function on the fly as a lambda expression)
Laziness (a.k.a. non-strict evaluation, most useful/usable when coupled with purity)
Algebraic data types and pattern matching
Closures
Currying / partial application
Parametric polymorphism (a.k.a. generics)
Recursion (more prominent as a result of purity)
Programming with expressions rather than statements (again, from purity)
...
The more features from the above list you are using, the more likely someone will label what you are doing "functional programming" (and the first two features--purity and higher-order functions--are probably worth the most extra bonus points towards your "FP score").
I have to add that functional programming tends to also abstract control structures of your program as well as the domain - e.g., you no longer do a 'for loop' on some list of things, but you 'map' it with some function to produce the output.
i think functional programming is a state of mind as well as the definition given above.
There are two separate definitions:
The older definition (first-class functions) has been given by Chris Conway.
The newer definition (avoiding side effects like mutation) has been given by John Stauffer. This is more generally known as purely functional programming.
This is a source of much confusion...
It's like drawing a picture by using vectors instead of bitmaps - tell the painter how to change the picture instead of what the picture looks like at each step.
It's application of functions as opposed to changing the state.
I think John Stauffer mostly has the definition. I would also add that you need to be able to pass functions around. Essentially you need high order functions, meaning you can pass functions around easily (although passing blocks is good enough).
For example a very popular functional call is map. It is basically equivalent to
list is some list of items
OutList is some empty list
foreach item in list
OutList.append(function(item))
return OutList
so that code is expressed as map(function, list). The revolutionary concept is that function is a function. Javascript is a great example of a language with high order functions. Basically functions can be treated like a variable and passed into functions or returned from functions. C++ and C have function pointers which can be used similarly. .NET delegates can also be used similarly.
then you can think of all sorts of cool abstractions...
Do you have a function AddItemsInList, MultiplyItemsInList, etc..?
Each function takes (List) and returns a single result
You could create (note, many languages do not allow you to pass + around as a function but it seems the clearest way to express the concept)....
AggregateItemsInList(List, combinefunction, StepFunction)
Increment functions work on indexes...better would be to make them work on list using list operations like next and for incTwo next next if it exists....
function incNormal(x) {
return x + 1
}
function incTwo(x) {
return x + 2
}
AggregateItemsInList(List, +, incNormal)
Want to do every other item?
AggegateItemsInList(List, +, incTwo)
Want to multiply?
AggregateItemsInList(List, *, incNormal)
Want to add exam scores together?
function AddScores (studenta, studentb) {
return studenta.score + studentb.score
}
AggregateItemsInList(ListOfStudents, AddScores, incOne)
High order functions are a very powerful abstraction. Instead of having to write custom methods for numbers, strings, students, etc.. you have one aggregate method that loops through a list of anything and you just have to create the addition operation for each data type.

Functional programming and non-functional programming

In my second year of University we were "taught" Haskell, I know almost nothing about it and even less about functional programming.
What is functional programming, why and/xor where would I want to use it instead of non-functional programming and am I correct in thinking that C is a non-functional programming language?
One key feature in a functional language is the concept of first-class functions. The idea is that you can pass functions as parameters to other functions and return them as values.
Functional programming involves writing code that does not change state. The primary reason for doing so is so that successive calls to a function will yield the same result. You can write functional code in any language that supports first-class functions, but there are some languages, like Haskell, which do not allow you to change state. In fact, you're not supposed to make any side effects (like printing out text) at all - which sounds like it could be completely useless.
Haskell instead employs a different approach to IO: monads. These are objects that contain the desired IO operation to be executed by your interpreter's toplevel. At any other level they are simply objects in the system.
What advantages does functional programming provide? Functional programming allows coding with fewer potentials for bugs because each component is completely isolated. Also, using recursion and first-class functions allows for simple proofs of correctness which typically mirror the structure of the code.
What is functional programming
There are two different definitions of "functional programming" in common use today:
The older definition (originating from Lisp) is that functional programming is about programming using first-class functions, i.e. where functions are treated like any other value so you can pass functions as arguments to other functions and function can return functions among their return values. This culminates in the use of higher-order functions such as map and reduce (you may have heard of mapReduce as a single operation used heavily by Google and, unsurprisingly, it is a close relative!). The .NET types System.Func and System.Action make higher-order functions available in C#. Although currying is impractical in C#, functions that accept other functions as arguments are common, e.g. the Parallel.For function.
The younger definition (popularized by Haskell) is that functional programming is also about minimizing and controlling side effects including mutation, i.e. writing programs that solve problems by composing expressions. This is more commonly called "purely functional programming". This is made possible by wildly different approaches to data structures called "purely functional data structures". One problem is that translating traditional imperative algorithms to use purely functional data structures typically makes performance 10x worse. Haskell is the only surviving purely functional programming language but the concepts have crept into mainstream programming with libraries like Linq on .NET.
where would I want to use it instead of non-functional programming
Everywhere. Lambdas in C# have now demonstrated major benefits. C++11 has lambdas. There's no excuse not to use higher-order functions now. If you can use a language like F# you'll also benefit from type inference, automatic generalization, currying and partial application (as well as lots of other language features!).
am I correct in thinking that C is a non-functional programming language?
Yes. C is a procedural language. However, you can get some of the benefit of functional programming by using function pointers and void * in C.
May be worth checking out this article on F# "101" on CoDe Mag recently posted.
Also, Dustin Campbell has a great blog where he has posted many articles on his adventures on getting up to speed with F#..
I hope you find these useful :)
EDIT:
Also, just to add, my understanding of functional programming is that everything is a function, or parameters to a function, rather than instances/stateful objects.. But I could be wrong F# is something I am dying to get in to but just dont have the time! :)
John the Statistician's example code does not show functional programming, because when you're doing functional programming, the key is that the code does NO ASSIGNMENTS ( record = thingConstructor(t) is an assignment), and it has NO SIDE EFFECTS (localMap.put(record) is a statement with a side effect). As a result of these two constraints, everything that a function does is fully captured by its arguments and its return value. Rewriting the Statistician's code the way it would have to look, if you wanted to emulate a functional language using C++:
RT getOrCreate(const T thing,
const Function<RT<T>> thingConstructor,
const Map<T,RT<T>> localMap) {
return localMap.contains(t) ?
localMap.get(t) :
localMap.put(t,thingConstructor(t));
}
As a result of the no side-effects rule, every statement is part of the return value (hence return comes first), and every statement is an expression. In languages that enforce functional programming, the return keyword is implied, and the if statement behaves like C++'s ?: operator.
Also, everything is immutable, so localMap.put has to create a new copy of localMap and return it, instead of modifying the original localMap, the way a normal C++ or Java program would. Depending on the structure of localMap, the copy could re-use pointers into the original, reducing the amount of data that has to be copied.
Some of the advantages of functional programming include the fact that functional programs are shorter, and it is easier to modify a functional program (because there are no hidden global effects to take into account), and it is easier to get the program right in the first place.
However, functional programs tend to run slowly (because of all the copying they have to do), and they don't tend to interact well with other programs, operating system processes, or operating systems, which deal in memory addresses, little-endian blocks of bytes, and other machine-specific, non-functional bits. The degree of noninteroperability tends to be inversely correlated with the degree of functional purity, and the strictness of the type system.
The more popular functional languages have really, really strict type systems. In OCAML, you can't even mix integer and floating-point math, or use the same operators (+ is for adding integers, +. is for adding floats). This can be either an advantage or a disadvantage, depending on how highly you value the ability of a type checker to catch certain kinds of bugs.
Functional languages also tend to have really big runtime environments. Haskell is an exception (GHC executables are almost as small as C programs, both at compile-time and runtime), but SML, Common Lisp, and Scheme programs always require tons of memory.
Yes you are correct in thinking that C is a non-functional language. C is a procedural language.
I prefer to use functional programming to save myself repeated work, by making a more abstract version and then using that instead. Let me give an example. In Java, I often find myself creating maps to record structures, and thus writing getOrCreate structures.
SomeKindOfRecord<T> getOrCreate(T thing) {
if(localMap.contains(thing)) { return localMap.get(thing); }
SomeKindOfRecord<T> record = new SomeKindOfRecord<T>(thing);
localMap = localMap.put(thing, record);
return record;
}
This happens very often. Now, in a functional language I could write
RT<T> getOrCreate(T thing,
Function<RT<T>> thingConstructor,
Map<T,RT<T>> localMap) {
if(localMap.contains(thing)) { return localMap.get(thing); }
RT<T> record = thingConstructor(thing);
localMap = localMap.put(thing,record);
return record;
}
and I would never have to write a new one of these again, I could inherit it. But I could do one better than inheriting, I could say in the constructor of this thing
getOrCreate = myLib.getOrCreate(*,
SomeKindOfRecord<T>.constructor(<T>),
localMap);
(where * is a kind of "leave this parameter open" notation, which is a sort of currying)
and then the local getOrCreate is exactly the same as it would have been if I wrote out the whole thing, in one line, with no inheritance dependencies.
If you are looking for a good text on F#
Expert F# is co-written by Don Syme. Creator of F#. He worked on generics in .NET specifically so he could create F#.
F# is modeled after OCaml so any OCaml text would help you learn F# as well.
I find What Is Functional Programming? to be useful
Functional programming is about writing pure functions, about removing
hidden inputs and outputs as far as we can, so that as much of our
code as possible just describes a relationship between inputs and
outputs.
Prefer explicit when param
public Program getProgramAt(TVGuide guide, int channel, Date when) {
Schedule schedule = guide.getSchedule(channel);
Program program = schedule.programAt(when);
return program;
}
over
public Program getCurrentProgram(TVGuide guide, int channel) {
Schedule schedule = guide.getSchedule(channel);
Program current = schedule.programAt(new Date());
return current;
}
A functional language is actively hostile to side-effects. Side-effects are complexity and complexity is bugs and bugs are the devil. A functional language will help you be hostile to side-effects too.

Resources