I know that in C# 3.0 you can do some functional programming magic with Linq and lambda expression and all that stuff. However, is it really possible to go completely "pure" functional in C#? By "pure" I mean having methods that are pure (always gives the same output for the same input) and completely free of side-effects. How do we get around the fact that we do not even have immutable integer type in C#?
If you want to program in a pure functional way, there is nothing stopping you.
On the other hand, if you have some program, there is no magic flag you can flip to force the program to behave in a pure functional way.
For ints (immutable)
If you use an int as a parameter, it is passed by value. Any changes are not propogated to the caller.
If you use an int declared in one method's scope in a closure within the method, than that int variable is shared. In this case, one must either pledge not to modify the int (programmer enforced), or simply not use an int in this way.
And if you truly need an immutable int, have you seen the readonly keyword?
Have you looked into F#? It seems much more along the lines of what you are talking about. C# just really isn't designed with functional programming in mind, and therefore won't really give you any of the benefits that are normally associated with a functional language.
Unfortunately no - C# is not a pure functional language and it does not intend to be. What has happened is that the C# team has seen that there are benefits to adding certain functionally-styled constructs and syntax to the language.
Functional purity is better found in other places (Lisp derivatives like Common Lisp and Scheme are good places to start).
Related
In most programming languages that have control-flow keywords, each control-flow keyword has one clear and unambiguous meaning. And then there's Ruby, in which the meaning of return is contextual: it does two very different things depending on whether or not you're inside of some (but not all!) types of anonymous functions. I'm not familiar with any other language with similar semantics.
That being true, if I have some Ruby code that's reasonably well written, and I want to translate it into another language, (let's say C#, because it's pretty popular around here,) how would I handle the "special" returns in order to preserve the original behavior?
The closest thing I can think of is to turn a "special" return into a throw new RubyNestedReturnException(<return value here>) and put all invocations in a try/catch block that catches RubyNestedReturnException and returns the value inside. This would probably work, but it would be very messy. Is there any better way to do it? (And no, "just turn all invocations that use a proc with "special" returns into a return statement" is not a good answer, since some invocations involve a proc that gets passed in as an argument from outside the function that invokes them.)
C# has no direct equivalent. The try..catch hack may work on the surface, but you'll be better served translating the code to the language of your choice.
I mean no self respecting programmer would ever write a plain for i=1 to 10 (or equivalent) in Python, no matter what other languages say. It's simply not the "Pythonic" way. C# has more traditional roots (C++), so writing C#-like code should be relatively straight forward.
If you are interested, both C (setjmp/longjmp) and Java (break label;) have something similar, and both are (generally) viewed as code smell generators. I suggest avoiding it altogether and rewriting the code using more traditional control flow operations.
I wrote some queries in C# using LINQ. After a while, I started using Haskell a little bit, which is a functional programming language (a not so popular one), and for me it seems that both of them are almost the same thing. But I am unsure about this. Please, if someone has used them more than me, could they tell me if they are almost the same thing regarding principles in programming ?
Also, could LINQ be considered functional programming ?
Thanks.
for me it seems that both of them are almost the same thing. But I am unsure about this. Please, if someone has used them more than me, could they tell me if they are almost the same thing regarding principles in programming ?
Yes, the design of LINQ query comprehensions was heavily influenced by the design of Haskell. Haskell expert Erik Meijer was on the C# language design committee when we designed LINQ; his insights were very valuable. (I joined the design team at the end of this process, so unfortunately I did not get to participate in all the interesting twists and turns the design went through over the years; it started being much more traditional OO than it ended up!)
If you've recently done a serious exploration into Haskell then you're probably becoming familiar with the idea of a monad. The LINQ syntax is designed specifically to make operations on the sequence monad feel natural, but in fact the implementation is more general; what C# calls "SelectMany" is a slightly modified form of the "Bind" operation on an arbitrary monad. You can actually use query comprehension with any monad, as my colleague Wes describes here, but doing so looks pretty weird and I recommend against it in production code.
Also, could LINQ be considered functional programming ?
Yes, LINQ is heavily influenced by ideas from functional programming. It is designed to treat functions as first-class objects, to emphasize calculation over side effects, and so on.
It may be worthwhile to take a look at Erik Meijer Lecture. Here's the description for it.
We kick off C9 Lectures with a journey
into the world of Functional
Programming with functional language
purist and high priest of the lambda
calculus, Dr. Erik Meijer (you can
thank Erik for many of the functional
constructs that have shown up in
languages like C# and VB.NET. When you
use LINQ, thank Erik in addition to
Anders).
It is true that C# has gained some aspects of functional programming. First and foremost is the lambda statement, implemented as an anonymous delegate. You now no longer need to define a method as belonging to an object, and you can define a method in a similar fashion as any other variable. This allows for many functional-type constructs:
var mult = (a,b)=>a*b;
var square = (a)=>Math.Pow(a,2);
var multandsquare = (a,b)=>square(mult(a,b));
//None of the above give a lick about what a and b really are, until...
multandsquare(5,3); //== 225
The basic paradigm of functional programming - that basically anything you can tell a computer to do can be told in terms of higher-order functions - can be applied to C# programs, especially now that C# actually has higher-order functions. The compiler will force you to have at least one class with at least one public main method (that's just how OO works), but from that point you can define pretty much everything only in terms of functions (def: a subclass of "methods" that take N parameters and produce 1 output without "side effects") instantiated as lambdas.
Linq does have some functional structure. Basically its method-chain paradigm is an example of monadic processing, which is how sequences of operations are structured through operation encapsulation in functional languages (and now in C#). Calling a Linq method on an IEnumerable returns another IEnumerable, which is really a different concrete class which contains a handle to the source Enumerable and some lambda to perform. You can replicate it in a functional language very simply; it's a tuple of the source (itself a tuple of the current element and everything else) and a function to perform that transforms the source tuple into the result, one element at a time (which in Linq, as it would be implemented in a functional language, is a nesting of some operation into a defined "rollup" function). Call a method that must produce an actual answer (a concrete typed result), and all these functions are evaluated sufficiently to produce the desired result.
Also could LINQ be considered
functional programming?
LINQ implies a functional style in that it resembles, for instance, a SQL select, which is read-only in principle. However, because the LINQ clauses in .NET are implemented by plain-old CLR routines, there is nothing to prevent LINQ expressions from modifying state.
Haskell, on the other hand, is a "pure" functional language, so expressions cannot modify global state. Although it is possible to perform IO and graphics operations, these are carried out using a very different idiom from anything in .NET — including F#, which lets you drop into a procedural style more or less transparently.
As a follow up to this question What are the advantages of built-in immutability of F# over C#?--am I correct in assuming that the F# compiler can make certain optimizations knowing that it's dealing with largely immutable code? I mean even if a developer writes "Functional C#" the compiler wouldn't know all of the immutability that the developer had tried to code in so that it couldn't make the same optimizations, right?
In general would the compiler of a functional language be able to make optimizations that would not be possible with an imperative language--even one written with as much immutability as possible?
Am I correct in assuming that the F# compiler can make certain
optimizations knowing that it's dealing with largely immutable code?
Unfortunately not. To a compiler writer, there's a huge difference between "largely immutable" and "immutable". Even guaranteed immutability is not that important to the optimizer; the main thing that it buys you is you can write a very aggressive inliner.
In general would the compiler of a functional language be able to make optimizations that would not be possible with an imperative language--even one written with as much immutability as possible?
Yes, but it's mostly a question of being able to apply the classic optimizations more easily, in more places. For example, immutability makes it much easier to apply common-subexpression elimination because immutability can guarantee you that contents of certain memory cells are not changed.
On the other hand, if your functional language is not just immutable but pure (no side effects like I/O), then you enable a new class of optimizations that involve rewriting source-level expressions to more efficient expressions. One of the most important and more interesting to read about is short-cut deforestation, which is a way to avoid allocating memory space for intermediate results. A good example to read about is stream fusion.
If you are compiling a statically typed, functional language for high performance, here are some of the main points of emphasis:
Use memory effectively. When you can, work with "unboxed" values, avoiding allocation and an extra level of indirection to the heap. Stream fusion in particular and other deforestation techniques are all very effective because they eliminate allocations.
Have a super-fast allocator, and amortize heap-exhaustion checks over multiple allocations.
Inline functions effectively. Especially, inline small functions across module boundaries.
Represent first-class functions efficiently, usually through closure conversion. Handle partially applied functions efficiently.
Don't overlook the classic scalar and loop optimizations. They made a huge difference to compilers like TIL and Objective Caml.
If you have a lazy functional language like Haskell or Clean, there are also a lot of specialized things to do with thunks.
Footnotes:
One interesting option you get with total immutability is more ability to execute very fine-grained parallelism. The end of this story has yet to be told.
Writing a good compiler for F# is harder than writing a typical compiler (if there is such a thing) because F# is so heavily constrained: it must do the functional things well, but it must also work effectively within the .NET framework, which was not designed with functional languages in mind. We owe a tip of the hat to Don Syme and his team for doing such a great job on a heavily constrained problem.
No.
The F# compiler makes no attempt to analyze the referential transparency of a method or lambda. The .NET BCL is simply not designed for this.
The F# language specification does reserve the keyword 'pure', so manually marking a method as pure may be possible in vNext, allowing more aggressive graph reduction of lambda-expressions.
However, if you use the either record or algebraic types, F# will create default comparison and equality operators, and provide copy semantics. Amongst many other benefits (pattern-matching, closed-world assumption) this reduces a significant burden!
Yes, if you don't consider F#, but consider Haskell for instance. The fact that there are no side effects really opens up a lot of possibilities for optimization.
For instance consider in a C like language:
int factorial(int n) {
if (n <= 0) return 1;
return n* factorial(n-1);
}
int factorialuser(int m) {
return factorial(m) * factorial(m);
}
If a corresponding method was written in Haskell, there would be no second call to factorial when you call factorialuser. It might be possible to do this in C#, but I doubt the current compilers do it, even for a simple example as this. As things get more complicated, it would be hard for C# compilers to optimize to the level Haskell can do.
Note, F# is not really a "pure" functional language, currently. So, I brought in Haskell (which is great!).
Unfortunately, because F# is only mostly pure there aren't really that many opportunities for aggressive optimization. In fact, there are some places where F# "pessimizes" code compared to C# (e.g. making defensive copies of structs to prevent observable mutation). On the bright side, the compiler does a good job overall despite this, providing comparable performace to C# in most places nonetheless while simultaneously making programs easier to reason about.
I would say largely 'no'.
The main 'optimization' advantages you get from immutability or referential transparency are things like the ability to do 'common subexpression elimination' when you see code like ...f(x)...f(x).... But such analysis is hard to do without very precise information, and since F# runs on the .Net runtime and .Net has no way to mark methods as pure (effect-free), it requires a ton of built-in information and analysis to even try to do any of this.
On the other hand, in a language like Haskell (which mostly means 'Haskell', as there are few languages 'like Haskell' that anyone has heard of or uses :)) that is lazy and pure, the analysis is simpler (everything is pure, go nuts).
That said, such 'optimizations' can often interact badly with other useful aspects of the system (performance predictability, debugging, ...).
There are often stories of "a sufficiently smart compiler could do X", but my opinion is that the "sufficiently smart compiler" is, and always will be, a myth. If you want fast code, then write fast code; the compiler is not going to save you. If you want common subexpression elimination, then create a local variable (do it yourself).
This is mostly my opinion, and you're welcome to downvote or disagree (indeed I've heard 'multicore' suggested as a rising reason that potentially 'optimization may get sexy again', which sounds plausible on the face of it). But if you're ever hopeful about any compiler doing any non-trivial optimization (that is not supported by annotations in the source code), then be prepared to wait a long, long time for your hopes to be fulfilled.
Don't get me wrong - immutability is good, and is likely to help you write 'fast' code in many situations. But not because the compiler optimizes it - rather, because the code is easy to write, debug, get correct, parallelize, profile, and decide which are the most important bottlenecks to spend time on (possibly rewriting them mutably). If you want efficient code, use a development process that let you develop, test, and profile quickly.
Additional optimizations for functional languages are sometimes possible, but not necessarily because of immutability. Internally, many compilers will convert code into an SSA (single static assignment) form, where each local variable inside a function can only be assigned once. This can be done for both imperative and functional languages. For instance:
x := x + 1
y := x + 4
can become
x_1 := x_0 + 1
y := x_1 + 4
where x_0 and x_1 are different variable names. This vastly simplifies many transformations, since you can move bits of code around without worrying about what value they have at specific points in the program. This doesn't work for values stored in memory though (i.e., globals, heap values, arrays, etc). Again, this is done for both functional and imperative languages.
One benefit most functional languages provide is a strong type system. This allows the compiler to make assumptions that it wouldn't be able to otherwise. For instance, if you have two references of different types, the compiler knows that they cannot alias (point to the same thing). This is not an assumption a C compiler could ever make.
I know this has been discussed many times, but I am not sure I really understand why Java and C# designers chose to omit this feature from these languages. I am not interested in how I can make workarounds (using interfaces, cloning, or any other alternative), but rather in the rationale behind the decision.
From a language design perspective, why has this feature been declined?
P.S: I'm using words such as "omitted", which some people may find inadequate, as C# was designed in an additive (rather than subtractive) approach. However, I am using such words because the feature existed in C++ before these languages were designed, so it is omitted in the sense of being removed from a programmer's toolbox.
In this interview, Anders said:
Anders Hejlsberg: Yes. With respect to
const, it's interesting, because we
hear that complaint all the time too:
"Why don't you have const?" Implicit
in the question is, "Why don't you
have const that is enforced by the
runtime?" That's really what people
are asking, although they don't come
out and say it that way.
The reason that const works in C++ is
because you can cast it away. If you
couldn't cast it away, then your world
would suck. If you declare a method
that takes a const Bla, you could pass
it a non-const Bla. But if it's the
other way around you can't. If you
declare a method that takes a
non-const Bla, you can't pass it a
const Bla. So now you're stuck. So you
gradually need a const version of
everything that isn't const, and you
end up with a shadow world. In C++ you
get away with it, because as with
anything in C++ it is purely optional
whether you want this check or not.
You can just whack the constness away
if you don't like it.
I guess primarily because:
it can't properly be enforced, even in C++ (you can cast it)
a single const at the bottom can force a whole chain of const in the call tree
Both can be problematic. But especially the first: if it can't be guaranteed, what use is it? Better options might be:
immutable types (either full immutability, or popsicle immutability)
As to why they did it those involved have said so:
http://blogs.msdn.com/ericgu/archive/2004/04/22/118238.aspx
http://blogs.msdn.com/slippman/archive/2004/01/22/61712.aspx
also mentioned by Raymond Chen
http://blogs.msdn.com/oldnewthing/archive/2004/04/27/121049.aspx
In a multi language system this would have been very complex.
As for Java, how would you have such a property behave? There are already techniques for making objects immutable, which is arguably a better way to achieve this with additional benefits. In fact you can emulate const behaviour by declaring a superclass/superinterface that implements only the methods that don't change state, and then having a subclass/subinterface that implements the mutating methods. By upcasting your mutable class to an instance of class with no write methods, other bits of code cannot modify the object without specifically casting it back to the mutable version (which is equivalent to casting away const).
Even if you don't want the object to be strictly immutable, if you really wanted (which I wouldn't recommend) you could put some kind of 'lock' mode on it so that it could only be mutated when unlocked. Have the lock/unlock methods be private, or protected as appropriate, and you get some level of access control there. Alternatively, if you don't intend for the method taking it as a parameter to modify it at all, pass in a copy of that object, or if copying the entire object is too heavyweight then some other lightweight data object that contains just the necessary information. You could even use dynamic proxies to create a proxy to your object that turn any calls to mutation methods into no-ops.
Basically there are already a whole bunch of ways to prevent a class being mutated, which let you choose one that fits most appropriately into your situation (hint: choose pure immutability wherever possible as it makes the object trivially threadsafe and easier to reason with in general). There are no obvious semantics for how const could be implemented that would be an improvement on these techniques, it would be another thing to learn that would either lack flexibility, or be so flexible as to be useless.
That is, unless I've missed something, which is entirely possible. :-)
Java have its own version of const; final. Joshua Bloch describes in his Effective Java
how you effectively use the final keyword. (btw, const is a reserved keyword in Java, for future discrepancies)
This is a question for anyone who has the pleasure to work in both Java and C#.
Do you find that you have to make a mental context switch of some kind when you move from one to the other?
I'm working in both at the moment and because the syntax and libraries are so similar and yet subtly different I'm finding it frustrating when i move from one to the other.
This is more so than I've experienced moving between any other programming languages.
Does anyone have any tips for making your brain work differently for languages that are so similar?
Yes, I have to make a mental context switch - because LINQ isn't available in Java :(
Beyond that, there are little things like foreach (X x in y) vs for (X x : y) which often trip me up, but not a huge amount otherwise.
As for a tip to make your brain work differently: don't give into the temptation to use the naming conventions of the other language. I find that using camel-cased method names in Java is a good nudge to my brain, for example.
EDIT: The differences in terms of generics are important and can occasionally be brain-warping, too.
I find that most difficult switches are around generics (which C# does better), delegates (which Java sort of hacks with anonymous inner classes) and the events (which Java doesn't have)
I find that making sure you are using the idioms of the language (i.e. using delegates instead of creating an interface in C#) will help snap your mind into gear.
The langauge differences as others have mentioned is the most obvious and problematic. I too find the library differences maddening at times and really wasting a lot of time.
The "details" can really get you as well, such as understanding how the memory model works or the way your runtime performs optimizations. Having intimate knowledge of the runtime environment's memory model, garbage collection techniques, threading model, etc can create significant changes in the way you think and develop software.
I cannot intelligently compare Java vs C#'s details at that level, but I can say that many things I would do in Java, I am uncomfortable or unsure if I can do in C# because I don't understand its low-level details. This affects code I write for everything from GUI-worker interaction to dealing with memory management.
I have found the best way to cope with the differences in Java and C# is to simply think of them as complete different languages--avoid the trap of "C# and Java are basicaly the same language with different class names".
The difference in how string equality comparisons work between Java and C# is one thing that needs to be kept in mind, particularly when moving from working in C# to working in Java.
In C# you can do a value comparison on two string instances with the == operator:
// C# string value comparison example
string string1 = GetStringValue1();
string string2 = GetStringValue2();
// Check to see whether the string values are equal
if (string1 == string2)
{
// Do something...
}
In Java, the == operator does a reference (not value) comparison on strings, so you need to use the equals() method:
// Java string value comparison example
String string1 = getStringValue1();
String string2 = getStringValue2();
// Check to see whether the string values are equal
if (string1.equals(string2))
{
// Do something...
}
Bottom line: When comparing strings in Java, don't forget that operator == doesn't do a value equality comparison, like it does when comparing strings in C#. (The same concept also applies to operator !=.)
They are similar enough that the differences trip me up. I learned Java in college and starting using C# when I got my first programming job.
C# in .Net 1.1 seemed a lot more similar, but now in C# 3.0, I use delegates, generics and especially API constructs like Dictionaries, way more than I ever did in Java. I've used the functional aspects of C# more and more as I work my way through learning F# (now writing in that or OCaml really forces me to change my way of thinking).