views:

392

answers:

6

Is it possible to force F# to behave like a pure functional language like Haskell? May be using some compiler directives?

ps: since i come from a C/C++ background, I want to force myself to learn functional programming without learning haskell :)

+8  A: 

Nope, sorry. You just have to use discipline.

Brian
Can you even do it? You'd have to create monads for everything you'd ordinarily do that have side-effects (like I/O).
Gabe
@Gabe: There are other models for IO besides Haskell's monad system, though it is the best tradeoff between flexibility and simplicity (amazingly enough) that I've heard of. You might be interested in reading Simon Peyton Jones's "Awkward Squad" paper if you want to read some very in-depth reasoning on the subject.
Chuck
Chuck: Are you saying that F# has a purely functional I/O primitive that isn't a monad? Or that whatever you'd implement to do I/O wouldn't have to be a monad?
Gabe
F# has no purely functional I/O primitive -- it uses effectful functions and call-by-value. And yes, there are other ways to purely functional IO than monads. Check out the awkward squad paper.
luqui
A: 

No. Currently F# compiler cannot do this checking.

Why not just start writing some F# program to learn functional programming? I know a few people who learned ML/Ocaml/F# first and then moved to Haskell.

Then you will have a better understanding of purity. (If you really haven't touched any functional programming language before, your understanding of pure functional could be superficial. )

Yin Zhu
+2  A: 

If you're anything like me, you will probably avoid the 'good stuff' if you don't force yourself to use Haskell instead of F# and use Haskell as idiomatically as you can. Using algebraic data types instead of objects, learning to love laziness, embracing the monad, and more are much more of a core part of Haskell, and arguably some of the finer points (in my opinion) of pure functional programming.

F# doesn't have as steep of a learning curve in many ways, but you sound like you are learning it for fun, so why not challenge yourself anyways? I can attest that moving to F# after using Haskell can give you a much better feel for how F# in general ought to be used anyways.

Food for thought.

iand675
A: 

The purely functional aspects of Haskell are fundamental to the language. You can't just transplant it between languages. It leads to major design decisions — for instance, Haskell's purely functional nature led to the invention of the IO monad. F# does not have such an "escape-valve" for stateful computation.

Also, learning to program in a language that supports functional programming but doesn't absolutely enforce it might actually be instructive. Many people get confused between Haskell's individual design decisions (e.g. the IO monad, to hit the big example again) and how functional programming works in general.

In short: No, you can't this. But what you can do is watch very carefully and question everything you do that involves maintaining state and sequencing operations to make sure that there isn't a more pure abstraction you're missing.

Chuck
+5  A: 

You can't force this behavior in F#, but as Brian said discipline is your best friend. E.g. don't use mutable, for or while loops, ref keywords, etc. Also stick with purely immutable data structures (discriminated union, list, tuple, map, etc). If you need to do IO at some point, architect your program so that they are separated from your purely functional code.

Don't forget functional programming is all about limiting and isolating side-effects.

Stringer Bell
"Don't forget functional programming is all about limiting and isolating side-effects." - or representing them, so they're no longer on the "side" :)
mokus
"Don't forget functional programming is all about limiting and isolating side-effects" - For me at least, it's also about being able to define types correctly such that invalid states become unrepresentable. You can do this in other languages (like C++) but the type system of F# and other functional languages makes this easier.
sashang
A: 

There is no such thing as "pure". All languages have to deal with the real world and this is where the so called "purity" begins and ends. F# is as pure as Haskell in every way, even if you use imperative means to get the IO, which basically what Haskell does anyway.

What F# gives you, is the option to use declarative practises much more easily than say its cousin C#. This is its niche in the market. Great for financial and scientific programming.

I think that reading around the subject as opposed to the implementations would give you a heads up of what people are talking about when dealing with purity. Its only pure in respect to "side effect free" programming.

What cracks me up though is that keyboards, mice, monitors, computer hardware all depend on these evil evil things called side effects to be useful!

WeNeedAnswers
Sigh. Pure is a descriptive term, not a moral term. Haskell is pure because all functions are referentially transparent -- given the same input they yield the same output, and hence all side effects are modeled explicitly. This lets you specify large subsets of your program which *are* entirely pure, even if at the top level, there's some IO going on. There's no meaning of "pure" that makes F# as pure as Haskell, but this is not an insult to F#. It's just a way of describing the differences between languages.
sclv
@sclv Yes, I agree, but when you read some of these posts it does seem as if there is a moral narrative. Making input and output "look" transparent can be done in ANY programming language, just that the syntax of Haskell and functional programming languages lend to this explicit nature a lot easier. "pure" is wrong. It does lead to evangelical programming. I prefer the Buddhist way "skill" and "unskilled". Maybe we should dub the whole purity thing as skilful programming, a good technique have you will. :)
WeNeedAnswers
@WeNeedAnswers - purity can also lead to fundamentalist programming: http://www.youtube.com/watch?v=UuamC0T3hv8. :)
Stringer Bell
skilled and unskilled *is* a judgement. pure and impure are purely descriptive. Furthermore, only Haskell or Clean or other purely functional languages can provide strongly-typed *guarantees* (modulo cheating functions such as `unsafePerformIO`) as to whether or not a function is pure or not. Haskell reflects effects at the type level. F# does not. End of story.
sclv
@Stringer Bell, thanks for the post, I really enjoyed that.
WeNeedAnswers
@sclv. What you saying, Haskell will never break down when IO is broken inside one of your monads. Don't make me laugh, I seen plenty of network IO fail inside of a monad, and guess what, it looks exactly the same as any other stream of data that fails that have been programmed correctly in any other language. People are getting too hung up on these super fast calculations were depending on. So a monad will always return a value based on a type. So what, if there has been an IO network error, don't matter how you cut the stream up in your program, your program never got the stream and bomb.
WeNeedAnswers
The only language that is truly pure is that of mathematics. IO is dirty in any language. Its filthy and rotten and smells terrible. Wrap it up in the cotton wool of a monad (mini procedural program, that executes in a sequence), but if the IO interface between the outside world (hardware) and the divine place that we call "pure". Your program will not work, produce results. Yes it will trap and report on the error but what good is this? can be done in any language.
WeNeedAnswers
http://leibnizdream.wordpress.com/2008/10/21/why-use-computation-workflows-aka-monads-in-f/, nice article on computation workflows.
WeNeedAnswers
I'm not saying that IO is more reliable in Haskell -- I'm saying that monads provide a mechanism to *isolate* the unreliability of IO. Either you get why that's useful, or apparently, you don't. For exceptions, there's handlers in Haskell just like any other language. But if you're careful, you can isolate where exceptions do and don't appear.
sclv
I get it all. I just don't like people putting languages up there as holly grails when they have the same issues as any other program. There are certain problems such as IO that can not be solved. period. Monads are wonderful creations and I think that every good programmer should use them directly or indirectly. but monads can be implemented in any language, not just haskell. Isolating IO is best done in a Monad. I can achieve all that haskell can do in f# and even more in python (duck typing rocks). I think that using haskell does make you a better programmer.
WeNeedAnswers