Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
This is the unabashed attempt of a similar C# question.
So what are your favorite F# hidden (or not) features?
Most of the features I've used so far aren't exactly hidden but have been quite refreshing. Like how trivial it is to overload operators compared to say C# or VB.NET.
And Async<T> has helped me shave off some real ugly code.
I'm quite new to the language still so it'd be great to learn what other features are being used in the wild.
User defined numeric literals can be defined by providing a module whose name starts with NumericLiteral and which defines certain methods (FromZero, FromOne, etc.).
In particular, you can use this to provide a much more readable syntax for calling LanguagePrimitives.GenericZero and LanguagePrimitives.GenericOne:
module NumericLiteralG = begin
let inline FromZero() = LanguagePrimitives.GenericZero
let inline FromOne() = LanguagePrimitives.GenericOne
end
let inline genericFactorial n =
let rec fact n = if (n = 0G) then 1G else n * (fact (n - 1G))
fact n
let flt = genericFactorial 30.
let bigI = genericFactorial 30I
F# has a little-used feature called "signature files". You can have a big implementation file full of public types/methods/modules/functions, but then you can hide and selectively expose that functionality to the sequel of the program via a signature file. That is, a signature file acts as a kind of screen/filter that enables you to make entities "public to this file" but "private to the rest of the program".
I feel like this is a pretty killer feature on the .Net platform, because the only other/prior tool you have for this kind of encapsulation is assemblies. If you have a small component with a few related types that want to be able to see each other's internal details, but don't want those types to have all those bits public to everyone, what can you do? Well, you can do two things:
You can put that component in a separate assembly, and make the members that those types share be "internal", and make the narrow part you want everyone else to see be "public", or
You just mark the internal stuff "internal" but you leave those types in your gigantic assembly and just hope that all the other code in the assembly chooses not to call those members that were only marked 'internal' because one other type needed to see it.
In my experience, on large software projects, everyone always does #2, because #1 is a non-starter for various reasons (people don't want 50 small assemblies, they want 1 or 2 or 3 large assemblies, for other maybe-good reasons unrelated to the encapsulation point I am raising (aside: everyone mentions ILMerge but no one uses it)).
So you chose option #2. Then a year later, you finally decide to refactor out that component, and you discover that over the past year, 17 other places now call into that 'internal' method that was really only meant for that one other type to call, making it really hard to factor out that bit because now everyone depends on those implementation details. Bummer.
The point is, there is no good way to create a moderate-size intra-assembly encapsulation scope/boundary in .Net. Often times "internal" is too big and "private" is too small.
... until F#. With F# signature files, you can create an encapsulation scope of "this source code file" by marking a bunch of stuff as public within the implementation file, so all the other code in the file can see it and party on it, but then use a signature file to hide all of the details expect the narrow public interface that component exposes to the rest of the world. This is happy. Define three highly related types in one file, let them see each others implementation details, but only expose the truly public stuff to everyone else. Win!
Signature files are perhaps not the ideal feature for intra-assembly encapsulation boundaries, but they are the only such feature I know, and so I cling to them like a life raft in the ocean.
TL;DR
Complexity is the enemy. Encapsulation boundaries are a weapon against this enemy. "private" is a great weapon but sometimes too small to be applicable, and "internal" is often too weak because so much code (entire assembly and all InternalsVisibleTo's) can see internal stuff. F# offers a scope bigger than "private to a type" but smaller than "the whole assembly", and that is very useful.
I wonder what happens if you add
<appSettings>
<add key="fsharp-navigationbar-enabled" value="true" />
</appSettings>
to your devenv.exe.config file? (Use at your own risk.)
Passing --warnon:1182 to the compiler turns on warnings about unused variables; variable names that begin with underscore are immune.
Automatically-generated comparison functions for algebraic data types (based on lexicographical ordering) is a nice feature that is relatively unknown; see
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!548.entry
for an example.
Yes, F# doesn't have any 'hidden' features, but it sure does have a lot of power packed into the simple language. A less-known feature of the language, is where you can basically enable duck typing despite the fact F# is staticaly typed.
See this question
F# operator "?"
for info on the question-mark operator and how it provides the basic language mechanism to build a feature akin to 'dynamic' in C#.
Not really hidden, but as a non-ML person this escaped me for quite a while:
Pattern matching can decompose arbitrarily deep into data structures.
Here's a [incredibly arbitrary] nested tuple example; this works on lists or unions or any combinations of nested values:
let listEven =
"Manipulating strings can be intriguing using F#".Split ' '
|> List.ofArray
|> List.map (fun x -> (x.Length % 2 = 0, x.Contains "i"), x)
|> List.choose
( function (true, true), s -> Some s
| _, "F#" -> Some "language"
| _ -> None )
Use of F# as a utility scripting language may be under appreciated. F# enthusiasts tend to be quants. Sometimes you want something to back up your MP3s (or dozens of database servers) that's a little more robust than batch. I've been hunting for a modern replacement for jscript / vbscript. Lately, I've used IronPython, but F# may be more complete and the .NET interaction is less cumbersome.
I like curried functions for entertainment value. Show a curried function to a pure procedural / OOP program for at least three WTFs. Starting with this is a bad way to get F# converts, though :)
Inlined operators on generic types can have different generic constraints:
type 'a Wrapper = Wrapper of 'a with
static member inline (+)(Wrapper(a),Wrapper(b)) = Wrapper(a + b)
static member inline Exp(Wrapper(a)) = Wrapper(exp a)
let objWrapper = Wrapper(obj())
let intWrapper = (Wrapper 1) + (Wrapper 2)
let fltWrapper = exp (Wrapper 1.0)
(* won''t compile *)
let _ = exp (Wrapper 1)
There are no hidden features, because F# is in design mode. All what we have is a Technical Preview, which changes every two month.
see http://research.microsoft.com/fsharp/
Related
I am currently doing the exercism.io F# track. For everyone who doesn't know it, it's solving small problems TDD style to learn or improve a programming language.
The last two tasks were about the usage of classes in F# (or types as they are called in F#). One of the tasks uses a BankAccount that has a balance and a status (open/closed) and can be altered by using functions. The usage was like this (Taken from the test code):
let test () =
let account = mkBankAccount () |> openAccount
Assert.That(getBalance account, Is.EqualTo(Some 0.0)
I wrote the code that makes the test pass using an immutable BankAccount class that can be interacted with using free functions:
type AccountStatus = Open | Closed
type BankAccount (balance, status) =
member acc.balance = balance
member acc.status = status
let mkBankAccount () =
BankAccount (0.0, Closed)
let getBalance (acc: BankAccount) =
match acc.status with
| Open -> Some(acc.balance)
| Closed -> None
let updateBalance balance (acc: BankAccount) =
match acc.status with
| Open -> BankAccount (acc.balance + balance, Open)
| Closed -> failwith "Account is closed!"
let openAccount (acc: BankAccount) =
BankAccount (acc.balance, Open)
let closeAccount (acc: BankAccount) =
BankAccount (acc.balance, Closed)
Having done a lot of OO before starting to learn F# this one got me wondering. How do more experienced F# developers use classes? To make answering this question more simple, here are my main concerns about classes/types in F#:
Is the use of classes in a typical OO fashion discouraged in F#?
Are immutable classes preferred? ( I found them to be confusing in the above example)
What is the preferred way to access/alter class data in F#? (Class member functions and get/set or free functions which allow piping? What about static members to allow piping and providing the functions with a fitting namespace?)
I'm sorry if the question is vague. I don't want to develop bad coding habits in my functional code and i need a starting point on what good practices are.
Is the use of classes in a typical OO fashion discouraged in F#?
It's not discouraged, but it's not the first place most experienced F# developers would go. Most F# developers will avoid subclassing and OO paradigms, and instead go with records or discriminated unions, and functions to operate on them.
Are immutable classes preferred?
Immutability should be preferred when possible. That being said, immutable classes can often be represented other ways (see below).
What is the preferred way to access/alter class data in F#? (Class member functions and get/set or free functions which allow piping? What about static members to allow piping and providing the functions with a fitting namespace?)
This is typically done via functions that allow piping, though access can be done directly, as well.
For your above code, it would be more common to use a record instead of a class, and then put the functions which work on the record into a module. An "immutable class" like yours can be written as a record more succinctly:
type BankAccount = { balance : float ; status : AccountStatus }
Once you've done this, working with it becomes easier, as you can use with to return modified versions:
let openAccount (acc: BankAccount) =
{ acc with status = Open }
Note that it'd be common to put these functions into a module:
module Account =
let open acc =
{ acc with status = Open }
let close acc =
{ acc with status = Closed }
Question: Is the use of classes in a typical OO fashion discouraged in F#?
It is not against F#'s nature. I think that there are cases when this is justified.
However, usage of classes should be limited if developers want to take full advantage of F# strengths (e.g. type interference, ability to use functional patterns such as partial application, brevity) and are not constrained by legacy systems and libraries.
F# for fun and profit gives a quick summary of pros and cons of using classes.
Ouestion: Are immutable classes preferred? ( I found them to be confusing in the above example)
Sometimes yes, sometimes not. I think that immutability of classes gives you lots of advantages (it's easier to reason about type's invariants etc.) but sometimes immutable class can be a bit cumbersome to use.
I think that this question is a bit too broad - it's somewhat similar to a question if fluent interfaces are preferred in object-oriented design - the short answer is: it depends.
What is the preferred way to access/alter class data in F#? (Class member functions and get/set or free functions which allow piping? What about static members to allow piping and providing the functions with a fitting namespace?)
Piping is a canonical construct in F#, so I would go for static member. If your library is consumed in some other languages, you should include getter and setter inside class as well.
EDIT:
FSharp.org has a list of quite specific design guidelines which include:
✔ Do use classes to encapsulate mutable state, according to standard
OO methodology.
✔ Do use discriminated unions as an alternative to class hierarchies
for creating tree-structured data.
There are a few ways of looking at this question.
This could mean several things. For POCO's, immutable F# records are preferred. Then the operations on them return new records with the requisite fields changed.
type BankAccount { status: AccountStatus; balance: int }
let close acct = { acct with status = Closed } // returns a *new* acct record
So that means you've got to get past the idea of an account "object" that represents a single "thing". It's just data that you operate on to create different data, and eventually (likely) store into a database somewhere.
So rather than the OO paradigm acct.Close(); acct.PersistChanges(), you'd have let acct' = close acct; db.UpdateRecord(acct').
For "services" in a "service-oriented architecture (SOA)" however, interfaces and classes are perfectly natural in F#. For instance, if you want a Twitter API, you'd probably create a class that wraps all the HTTP calls just like you would in C#. I've seen some references to the "SOLID" ideology in F# that eschews SOA completely but I've never figured out how to make that work in practice.
Personally, I like an FP-OO-FP sandwich with Suave's FP combinators on top, a SOA using Autofac in the middle, and FP records on the bottom. I find that works well and is scalable.
FWIW also you may want do make your BankAccount a discriminated union, if Closed can't have a balance. Try this out in your code samples. One of the nice things in F# is it makes illogical states unrepresentable.
type BankAccount = Open of balance: int | Closed
In Expert F# 2.0 by Don Syme, Adam Granicz, and Antonio Cisternino, pg. 44
Type inference: Using the |> operator lets type information flow from
input objects to the functions manipulating those objects. F# uses
information collected from type inference to resolve some language
constructs such as property accesses and method overloading. This
relies on information being propagated left to right thorough the text
of a program. In particular, type information to the right of a position
isn't taken into account when resolving property access and overload.
So clearly using |> can help type inference.
As always, declaring the type is also helpful.
Are there any other means/tactics that can be used to help F# type inference?
EDIT
As RamonSnir correctly pointed out one is supposed to let type inference do as much work as possible. So adding type declarations just because you can is not what one should do. Do not take this question or answers as something that should be done. I asked the question to help better understand the nuance of type inference and what might help in those occasions when type inference needs help. So if type inference can resolve all of the types without help, then don't give it any, but when it does, it would be nice to know some ways to help it.
A few points:
1) Prefer module functions to properties and methods.
List.map (fun x -> x.Length) ["hello"; "world"] // fails
List.map String.length ["hello"; "world"] // works
let mapFirst xss = Array.map (fun xs -> xs.[0]) xss // fails
let mapFirst xss = Array.map (fun xs -> Array.get xs 0) xss // works
2) Prefer methods without overloading. For example, QuickLinq Helpers define non-overloaded members to avoid a bunch of type annotation in LINQ extension methods.
3) Make use of any available information to give some hints to the type checker.
let makeStreamReader x = new System.IO.StreamReader(x) // fails
let makeStreamReader x = new System.IO.StreamReader(path=x) // works
The last example is taken from an excellent write-up about F# type inference.
To conclude, you don't often need to help F# type checker. If there is a type error, the summary from the link above gives a good fixing guideline:
So to summarize, the things that you can do if the compiler is
complaining about missing types, or not enough information, are:
Define things before they are used (this includes making sure the files are compiled in the right order)
Put the things that have "known types" earlier than things that have "unknown types". In particular, you might be able reorder pipes
and similar chained functions so that the typed objects come first.
Annotate as needed. One common trick is to add annotations until everything works, and then take them away one by one until you have
the minimum needed. Do try to avoid annotating if possible. Not only
is it not aesthetically pleasing, but it makes the code more brittle.
It is a lot easier to change types if there are no explicit
dependencies on them.
I've been watching an interesting video in which type classes in Haskell are used to solve the so-called "expression problem". About 15 minutes in, it shows how type classes can be used to "open up" a datatype based on a discriminated union for extension -- additional discriminators can be added separately without modifying / rebuilding the original definition.
I know type classes aren't available in F#, but is there a way using other language features to achieve this kind of extensibility? If not, how close can we come to solving the expression problem in F#?
Clarification: I'm assuming the problem is defined as described in the previous video
in the series -- extensibility of the datatype and operations on the datatype with the features of code-level modularization and separate compilation (extensions can be deployed as separate modules without needing to modify or recompile the original code) as well as static type safety.
As Jörg pointed out in a comment, it depends on what you mean by solve. If you mean solve including some form of type-checking that the you're not missing an implementation of some function for some case, then F# doesn't give you any elegant way (and I'm not sure if the Haskell solution is elegant). You may be able to encode it using the SML solution mentioned by kvb or maybe using one of the OO based solutions.
In reality, if I was developing a real-world system that needs to solve the problem, I would choose a solution that doesn't give you full checking, but is much easier to use.
A sketch would be to use obj as the representation of a type and use reflection to locate functions that provide implementation for individual cases. I would probably mark all parts using some attribute to make checking easier. A module adding application to an expression might look like this:
[<Extends("Expr")>] // Specifies that this type should be treated as a case of 'Expr'
type App = App of obj * obj
module AppModule =
[<Implements("format")>] // Specifies that this extends function 'format'
let format (App(e1, e2)) =
// We don't make recursive calls directly, but instead use `invoke` function
// and some representation of the function named `formatFunc`. Alternatively
// you could support 'e1?format' using dynamic invoke.
sprintfn "(%s %s)" (invoke formatFunc e1) (invoke formatFunc e2)
This does not give you any type-checking, but it gives you a fairly elegant solution that is easy to use and not that difficult to implement (using reflection). Checking that you're not missing a case is not done at compile-time, but you can easily write unit tests for that.
See Vesa Karvonen's comment here for one SML solution (albeit cumbersome), which can easily be translated to F#.
I know type classes aren't available in F#, but is there a way using other language features to achieve this kind of extensibility?
I do not believe so, no.
If not, how close can we come to solving the expression problem in F#?
The expression problem is about allowing the user to augment your library code with both new functions and new types without having to recompile your library. In F#, union types make it easy to add new functions (but impossible to add new union cases to an existing union type) and class types make it easy to derive new class types (but impossible to add new methods to an existing class hierarchy). These are the two forms of extensibility required in practice. The ability to extend in both directions simultaneously without sacrificing static type safety is just an academic curiosity, IME.
Incidentally, the most elegant way to provide this kind of extensibility that I have seen is to sacrifice type safety and use so-called "rule-based programming". Mathematica does this. For example, a function to compute the symbolic derivative of an expression that is an integer literal, variable or addition may be written in Mathematica like this:
D[_Integer, _] := 0
D[x_Symbol, x_] := 1
D[_Symbol, _] := 0
D[f_ + g_, x_] := D[f, x] + D[g, x]
We can retrofit support for multiplication like this:
D[f_ g_, x_] := f D[g, x] + g D[f, x]
and we can add a new function to evaluate an expression like this:
E[n_Integer] := n
E[f_ + g_] = E[f] + E[g]
To me, this is far more elegant than any of the solutions written in languages like OCaml, Haskell and Scala but, of course, it is not type safe.
I'm quite interested in learning F#.
My only experience with functional languages has been 2 introductory courses on Scheme in college.
Are there any things that I should keep in mind while learning F#, having previously learned Scheme? Any differences in methodologies, gotchas or other things that might give me trouble?
Are there any things that I should keep in mind while learning F#, having previously learned Scheme? Any differences in methodologies, gotchas or other things that might give me trouble?
Static typing is the major difference between Scheme and F#. This facilitates a style called typeful programming where the type system is used to encode constraints about functions and data such that the compiler proves these aspects of the program correct at compile time and any violations of the constraints are caught immediately.
For example, a sequence of one or more elements of the same type might be conveyed by a value of the following type:
type list1<'a> = List1 of 'a * 'a list
let xs = List1(1, [])
let ys = List1(2, [3; 4])
The compiler now guarantees that any attempt to use an empty one of these sequences will be caught at compile time as an error.
Now, the reduce function makes no sense on an empty sequence so the built-in implementation for lists barfs at run-time with an exception if it encounters an empty sequence:
> List.reduce (+) [];;
System.ArgumentException: The input list was empty.
Parameter name: list
at Microsoft.FSharp.Collections.ListModule.Reduce[T](FSharpFunc`2 reduction, FSharpList`1 list)
at <StartupCode$FSI_0271>.$FSI_0271.main#()
Stopped due to error
With our new sequence of one or more elements, we can now write a reduce function that never barfs at run-time with an exception because its input is guaranteed by the type system to be non-empty:
let rec reduce f = function
| List1(x, []) -> x
| List1(x0, x1::xs) -> f x0 (reduce f (List1(x1, xs)))
This is a great way to improve the reliability of software by eliminating sources of run-time errors and it is something that dynamically typed languages like Scheme cannot even begin to do.
Scheme is a nice functional language; learning it in school should provide a good foundation for functional programming.
F# is statically-typed whereas Scheme is dynamic, so that is one obvious difference. If you have experience with other static languages (especially .NET languages like C#) then that will not be a big deal, but if most of your experience is dynamic, that will be a change.
Learning the names of the main F# functional programming functions (things like List.map) is important; most every functional language has the same basic set but often with different names (I don't recall the main Scheme names to compare).
If you have old Scheme 'programming assignments' with sample inputs/outputs handy, it may be useful to re-code them in F# as a way to 'warm up' with the language.
I suggest considering Haskell too, and they are roughly in the same family as F# and ML, and Haskell contains a lot of interesting functional concepts not found elsewhere.
Take a look at tryhaskell.org for an interactive online tutorial.
Please advise. I am a lawyer, I work in the field of Law Informatics. I have been a programmer for a long time (Basic, RPG, Fortran, Pascal, Cobol, VB.NET, C#). I am currently interested in F#, but I'd like some advise. My concern is F# seems to be fit for math applications. And what I want would require a lot of Boolean Math operations and Natural Language Processing of text and, if successful, speech. I am worried about the text processing.
I received a revolutionary PROLOG source code (revolutionary in the field of Law and in particular Dispute Resolution). The program solves disputes by evaluating Yes-No (true-false) arguments advanced by two debating parties. Now, I am learning PROLOG so I can take the program to another level: evaluate the strenght of arguments when they are neither a Yes or No, but a persuasive element in the argumentation process.
So, the program handles the dialectics aspect of argumentation, I want it to begin processing the rhetoric aspect of argumentation, or at least some aspects.
Currently the program can manage formal logic. What I want is to begin managing some aspects of informal logic and for that I would need to do parsing of strings (long strings, maybe ms word documents) for the detection of text markers, words like "but" "therefore" "however" "since" etc, etc, just a long list of words I have to look up in any speech (verbal or written) and mark, and then evaluate left side and right side of the mark. Depending on the mark the sides are deemed strong or weak.
Initially, I thought of porting the Prolog program to C# and use a Prolog library. Then, it ocurred to me maybe it could be better in pure F#.
First, the project you describe sounds (and I believe this is the correct legal term) totally freaking awesome.
Second, while F# is a good choice for math applications, its also extremely well-suited for any applications which perform a lot of symbolic processing. Its worth noting that F# is part of the ML family of languages which were originally designed for the specific purpose of developing theorem provers. It sounds like you're writing an application which appeals directly to the niche ML languages are geared for.
I would personally recommend writing any theorem proving applications you have in F# rather than C# -- only because the resulting F# code will be about 1/10th the size of the C# equivalent. I posted this sample demonstrating how to evaluate propositional logic in C# and F#, you can see the difference for yourself.
F# has many features that make this type of logic processing natural. To get a feel for what the language looks like, here is one possible way to decide which side of an argument has won, and by how much. Uses a random result for the argument, since the interesting (read "very hard to impossible") part will be parsing out the argument text and deciding how persuasive it would be to an actual human.
/// Declare a 'weight' unit-of-measure, so the compiler can do static typechecking
[<Measure>] type weight
/// Type of tokenized argument
type Argument = string
/// Type of argument reduced to side & weight
type ArgumentResult =
| Pro of float<weight>
| Con of float<weight>
| Draw
/// Convert a tokenized argument into a side & weight
/// Presently returns a random side and weight
let ParseArgument =
let rnd = System.Random()
let nextArg() = rnd.NextDouble() * 1.0<weight>
fun (line:string) ->
// The REALLY interesting code goes here!
match rnd.Next(0,3) with
| 1 -> Pro(nextArg())
| 2 -> Con(nextArg())
| _ -> Draw
/// Tally the argument scored
let Score args =
// Sum up all pro & con scores, and keep track of count for avg calculation
let totalPro, totalCon, count =
args
|> Seq.map ParseArgument
|> Seq.fold
(fun (pros, cons, count) arg ->
match arg with
| Pro(w) -> (pros+w, cons, count+1)
| Con(w) -> (pros, cons+w, count+1)
| Draw -> (pros, cons, count+1)
)
(0.0<weight>, 0.0<weight>, 0)
let fcount = float(count)
let avgPro, avgCon = totalPro/fcount, totalCon/ fcoun
let diff = avgPro - avgCon
match diff with
// consider < 1% a draw
| d when abs d < 0.01<weight> -> Draw
| d when d > 0.0<weight> -> Pro(d)
| d -> Con(-d)
let testScore = ["yes"; "no"; "yes"; "no"; "no"; "YES!"; "YES!"]
|> Score
printfn "Test score = %A" testScore
Porting from prolog to F# wont be that straight forward. While they are both non-imperative languages. Prolog is a declarative language and f# is functional. I never used C# Prolog libraries but I think it will be easier then converting the whole thing to f#.
It sounds like the functional aspects of F# are appealing to you, but you wonder if it can handle the non-functional aspects. You should know that F# has the entire .NET Framework at its disposal. It also is not a purely functional language; you can write imperative code in it if you want to.
Finally, if there are still things you want to do from C#, it is possible to call F# functions from C#, and vice versa.
While F# is certainly more suitable than C# for this kind of application since there're going to be several algorithms which F# allows you to express in a very concise and elegant way, you should consider the difference between functional, OO, and logic programming. In fact, porting from F# will most likely require you to use a solver (or implement your own) and that might take you some time to get used to. Otherwise you should consider making a library with your prolog code and access it from .NET (see more about interop at this page and remember that everything you can access from C# you can also access from F#).
F# does not support logic programming as Prolog does. you might want to check out the P# compiler.