#1,217 in Computers & technology books
Use arrows to jump to the previous/next product
Reddit mentions of F# for Scientists
Sentiment score: 2
Reddit mentions: 3
We found 3 Reddit mentions of F# for Scientists. Here are the top ones.
Buying options
View on Amazon.comor
- Throw/Pole Spst
- Color Chrome Plated
- Package Dimensions: 4.597 L X 15.798 H X 7.010 W Centimeters
- Product Type:Electronic Switch
- Fit type: Vehicle Specific
Features:
Specs:
Height | 9.598406 inches |
Length | 6.401562 inches |
Number of items | 1 |
Weight | 1.4991433816 Pounds |
Width | 0.901573 inches |
\> Would it transpile ALL of my code into JS? Wouldn’t that degrade performance?
​
If you implemented your numerical computations in the Fable app, yes, most likely. Although JavaScript can be used to write performant desktop applications - for instance, Visual Studio Code - I don't think it would be a good fit for scientific computing. The use case for Fable is in having behaviorally-sophisticated UIs without having to run through the dynamically/weakly-typed mess that is JavaScript. That said, JavaScript is not a terribly slow language - the Node.js JavaScript runtime is typically faster than Python. And Fable has Electron bindings for creating desktop apps. It could be worth trying. But I imagine a transpiled F# program would be noticeably slower than having one run in the .NET Framework or .NET Core runtime.
​
You really want to think of this as a UI layer on top of a computation layer. For a web application, the UI is typically run client-side in JavaScript (the browser sends .JS code to its JavaScript runtime, or in the very simplest case is only an HTML renderer), while the server code is some other language (F#, C++, PHP, etc) that sends user-facing data to the JavaScript. For a .NET desktop application, it'll all be bundled and run in the same place, but typically with a separate frontend project and a backend project. Unfortunately, either way it'll be a bit of work. And I think we'd need a bit more information about your code to give a good answer - for starters, is this Windows, or Linux? .NET Framework or .NET Core?
> My other question is if F# good for some scientific applications?
Yes. I started out using F# for such things. I ended up writing the book on it.
F#'s ML core is extremely simple. I think you would find it very easy to learn. Let me get you started:
There is a type called
unit
that has a single value in it called()
that can be used to convey no information, a bit likevoid
in other languages but you can use the value()
of the typeunit
anywhere.The
bool
type has valuestrue
andfalse
.Integers are written
1
,2
,3
and so on. Integer arithmetic is1+2*3
. Theint
function converts a value (e.g.float
orstring
) into anint
.Floating point numbers are written
1.2
,2.3
,3.4
and so on. Floating point arithmetic is written1.2+2.3*3.4
. Thefloat
function converts a value (e.g.int
orstring
) to afloat
.Characters are of the type
char
and are written'a'
. Strings are of the typestring
and are written"foo"
. You can append strings with"foo"+"bar"
. Thestring
function tries to convert a value of another type (e.g.int
orfloat
) into a string.Lists are written
[1;2;3]
. You can prepend onto the front in constant time with1::[2;3]
.Arrays are written
[|1;2;3|]
. You can read and write elements with random access in constant time witharr.[i]
andarr.[i] <- 3
.ML has sum types and product types. The simplest product type is the tuple. Tuples are written
(2, 3)
and(2, 3, 4)
. The types of those tuples are writtenint * int
andint * int * int
. Tuples can have as many elements as you like (greater than one, of course). Note F# uses OCaml-style syntax which lets you drop many brackets when dealing with tuples, so you can often just write1, 2
.F# also has record types which are product types where the fields have names. Record types are defined as
type MyRecord = {FirstName: string; LastName: string}
. Values of record types are written{FirstName="Jon"; LastName="Harrop"}
. Given a valuer
you can get a field with the syntaxr.FirstName
. As a product type, a value of typeMyRecord
must have aFirstName
and aLastName
.Algebraic datatypes (ADTs) are a combination of sum types and product types. A sum type allows a value to be one of several different options. The simplest example is to define your own boolean:
type MyBoolean = True | False
The values
True
andFalse
are then values of the typeMyBoolean
. Like an enum in other languages. But the really cool thing about ADTs in MLs is that those union cases can have an argument of any type you want. For example, we can define an ADT:type Glyph =
| Digit of int
| Letter of char
The values
Digit 3
andLetter 'x'
are values of this typeGlyph
.The value
()
of typeunit
was a minor diversion from other programming languages. Now comes the first major diversion: pattern matching is the only way to destructure ADTs. So the only way to extract those values3
and'x'
from the value of typeGlyph
is using pattern matching. In ML there are patterns all over the place. The most obvious place you see patterns in on the left hand side of the->
in each match case of amatch
expression. Here is a pattern match that will keep digits the same but redact all letters to'x'
:match Digit 3 with
| Digit n -> Digit n
| Letter c -> Letter 'x'
In this case the
Digit n
andLetter c
are patterns. In particular, these have the effect of binding the variablen
to the value conveyed in theDigit
case (so it can be used on the right hand side of that match expression) orc
to the value conveyed in theLetter
case.You can match
int
,float
,char
,string
and other types such as tuples, records and ADTs using the same literal syntax that you do in expressions.When you need to match a value but you don't care about its value you can use
_
to match any value of any type and not bind it to any variable name.If you want your pattern to match either something or something else you can write an or-pattern:
patt1 | patt2
.If you want to name part of a value that you're matching you can use
patt as myVar
to call itmyVar
. For example, we could have written:match Digit 3 with
| Digit as glyph -> glyph
| Letter c -> Letter 'x'
You can define variables with
let
:let x = 3
This looks mundane but that
x
is actually a pattern so you can also do:let (x, (y, z)) = (1, (2, 3))
to destructure the
int * (int * int)
pair on the right and definex
,y
andz
.You can also define functions with
let
:let redact glyph =
match glyph with
| Digit -> glyph
| Letter c -> Letter 'x'
In ML, function application is written
f x
rather thanf(x)
, e.g.redact (Digit 3)
.Here we come to our second massive departure from conventional languages: when you have tuples you don't need multi-argument functions so every function in ML accepts one argument and returns one value! Furthermore, like OCaml, F# typically writes functions in Curried form. So a function to add two numbers is written
let add x y = x+y
which has the typeint -> int -> int
rather thanint * int -> int
so this is a function that takesx
and returns another function that takesy
and returnsx+y
.Oh look, you've learned enough F# to understand this computer algebra system that can differentiate any symbolic mathematical expression composed of integers, variables, addition, multiplication, power and logarithm:
type Expr =
| Int of int
| Var of string
| Add of Expr Expr
| Mul of Expr Expr
| Pow of Expr * Expr
| Ln of Expr
let rec d x e =
match e with
| Var y when x=y -> Int 1
| Int | Var -> Int 0
| Add(f, g) -> Add(d x f, d x g)
| Mul(f, g) -> Add(Mul(f, d x g), Mul(g, d x f))
| Pow(f, g) -> Mul(Pow(f, g), Add(Mul(Mul(g, d x f), Pow(f, Int -1)), Mul(Ln f, d x g)))
| Ln f -> Mul(d x f, Pow(f, Int -1))
For example, the symbolic derivative of
x^x
computed in F# Interactive (e.g. in Visual Studio) is given as:> d "x" (Pow(Var "x", Var "x"));;
val it : expr =
Mul
(Pow (Var "x",Var "x"),
Add
(Mul (Mul (Var "x",Int 1),Pow (Var "x",Int -1)),
Mul (Ln (Var "x"),Int 1)))
Probably the next thing to understand is that
map f [a;b;c;...] = [f a; f b; f c; ...]
andfold f a [b;c;d;...] = f (f (f a b) c) d) ...
. For example, if you represent 2D coordinates as a pair you can write:let translate (x0, y0) ps = Array.map (fun (x1, y1) -> x0+x1, y0+y1) ps
To sum a list of integers you can write:
let sum xs = Array.fold (fun x a -> x+a) 0 xs
So given a file containing a list of integers on separate lines you can add them all up with:
Seq.fold (fun total line -> int line + total) 0 (System.IO.File.ReadAllLines @"Data/Numbers.txt")
F# has a handy pipeline operator
|>
so you can writef x
asx |> f
instead. For example:System.IO.File.ReadAllLines @"Data/Numbers.txt"
|> Seq.fold (fun total line -> int line + total) 0
Another mind-blowing thing you'll come to love is purely functional data structures. When you add an element to a list, set or map (dictionary) in F# you get a new collection in O(log n) time but the old collection is still perfectly valid and can be reused.
Since you're studying Mathematics, you might be better off looking at functional programming,rather then OOP. F# from Microsoft offers both functional and OOP. A good introduction is F# for Scientists . As for performance, there are a number of benchmarks showing F# matching or beating equivalent C++ programs.