You are on page 1of 16

The F# programming language is part of Microsoft's family of .

NET languages, which


include C#, Visual Basic.NET, JScript.NET, and others. As a .NET language, F# code
compiles down to Common Language Infrastructure (CLI) byte code which runs on
top of the Common Language Runtime (CLR). All .NET languages share this
common intermediate state which allows them to easily interoperate with one
another and use the .NET Framework's Base Class Library (BCL).

F# is a mixed-paradigm language: it supports imperative, object-oriented, and functional styles of


writing code, with heaviest emphasis on the latter.

F# is valuable to programmers at any skill level; it combines best features of functional and object
oriented programming styles into a uniquely productive language.

Programming languages are becoming more functional every year. For example, features such
as generic programming, type inference, list comprehensions, functions as values, and
anonymous types have traditionally existed as staples of functional programming, have quickly
become mainstream features of Java, C#, Delphi and even Fortran. In the future, next generation
programming languages will continue to evolve as hybrid functional / imperative programming
languages.

Functional programming is often regarded as the best-kept secret of scientific modelers,


mathematicians, artificial intelligence researchers, financial institutions, graphic designers, CPU
designers, compiler programmers, and telecommunications engineers. Understandably,
functional programming languages tend to be used in settings that perform heavy number
crunching, abstract symbolic processing, or theorem proving. Of course, while F# is abstract
enough to satisfy the needs of some highly technical niches, its simple and expressive syntax
makes it suitable for CRUD apps, web pages, GUIs, games, and general-purpose programming.

Unlike many other strongly typed languages, F# often does not require programmers to use type
annotations when declaring functions and variables. Instead, F# attempts to work out the types
for you, based on the way that variables are used on code.

What is Functional Programming?


Structure of F# Programs
open System

(* This is a
multi-line comment *)

// This is a single-line comment

#light
open System
let rec fib n =
if n < 2 then 1 else fib (n-2) + fib(n-1)

printfn "upisite broj"


let n=Console.ReadLine().Trim()
|> Convert.ToInt32
Console.WriteLine("fib : {0}", (fib n))
printfn "the end"

let _ = Console.ReadKey()

Most F# code files contain the #light directive at the top. This keyword makes
whitespace significant and allows programmers to omit certain redundant tokens such
as in, ;, begin, and end.

Afterwards, a number of open statements import namespaces, allowing programmers to


reference classes in namespaces without having to write fully qualified type declarations. This
keyword is functionally equivalent to the using directive in C# and Imports directive in VB.Net.
For example, the Console class is found under the System namespace; without importing the
namespace, a programmer would need to access the Console class through its fully qualified
name, System.Console.

The body of the F# file usually contains functions to implement the business logic in an
application.

Finally, many F# application exhibit this pattern:


let main() =
(*
...
This is the main loop.
...
*)

main()
(*
This is a top-level statement because it's
not nested in any other functions. This calls
into the main method to run the main loop.
*)

F# : Classes and Objects

In the real world, an object is a "real" thing. A cat, person, computer, and a roll of duct tape are
all "real" things in the tangible sense. When we think about these things, we can broadly describe
them in terms of a number of attributes:

 Properties: a person has a name, a cat has four legs, computers have a pricetag, duct
tape is sticky.
 Behaviors: a person reads the newspaper, cats sleep all day, computers crunch
numbers, duct tape attaches things to other things.
 Types/group membership: an employee is a type of person, a cat is a pet, a Dell and Mac
are types are computers, duct tape is part of the broader family of adhesives.

Object-oriented programming (OOP) exists because it allows programmers to model


real-world entities and simulate their interactions in code. Just like their real-world
counterparts, objects in computer programming have properties, behaviors, and be
classified according to their type.

Before you create an object, you have to identify the properties of your object and
describe what it does. You define properties and methods of an object in a class. There
are actually two different syntaxes for defining a class: an implicit syntax and an
explicit syntax.

type TypeName optional-type-arguments arguments [ as ident ] =


[ inherit type { as base } ]
[ let-binding | let-rec bindings ] *
[ do-statement ] *
[ abstract-binding | member-binding | interface-implementation ] *
Elements in brackets are optional, elements followed by a * may appear zero or more
times.

This syntax above is not as daunting as it looks. Here's a simple class written in implicit
style:
type Account(number : int, holder : string) = class
let mutable amount = 0m
member x.Number = number
member x.Holder = holder
member x.Amount = amount

member x.Deposit(value) = amount <- amount + value


member x.Withdraw(value) = amount <- amount - value
end

ou create an instance of Account by using the new keyword and passing the appropriate
parameters into the constructor as follows:
let bob = new Account(123456, "Bob's Saving")

After we can create an instance of our Account, we can access its properties

using .propertyName notation

let printAccount (x : Account) =


printfn "x.Number: %i, x.Holder: %s, x.Amount: %M" x.Number x.Holder
x.Amount;;
Class Members
There are two types of members you can add to an object:

 Instance members, which can only be called from an object instance created using
the new keyword.

 Static members, which are not associated with any object instance.

type SomeClass(prop : int) = class


member x.Prop = prop
static member SomeStaticMethod = "This is a static method"
end
> let instance = new SomeClass(5);;

val instance : SomeClass

> instance.Prop;; (* now we have an instance, we can call our instance


method *)
val it : int = 5

Getters and Setters


member alias.PropertyName
with get() = some-value
and set(value) = some-assignment
type IntWrapper() = class
let mutable num = 0

member x.Num
with get() = num
and set(value) =
if value > 10 || value < 0 then
raise (new Exception("Values must be between 0 and 10"))
else
num <- value
end

Comments

Types

On those occasions where F# cannot work out the types correctly, the programmer can provide
explicit annotations to guide F# in the right direction. For example, as mentioned above, math
operators default to operations on integers
> let add (x : float) (y : float) = x + y;;
val add : float -> float -> float

Primitive types
nit , bool , char , int and float , as well as several compound types such
as string > ();;

val it : unit = ()
> true;;
val it : bool = true
> 'a';;
val it : char = 'a'
> 3;;
val it : int = 3
> 2.4;;
val it : float = 2.4
> "foobar";;
val it : string = "foobar"

Arithmetic
The numeric types, such as int and float , provide various arithmetic operations:
> 1 + 2 * 3;;
val it : int = 7
> 3.4 + 2.3 * 7.7;;
val it : float = 21.11

the + operator can be used to concatenate strings:

> "foo" + "bar";;


val it : string = "foobar"

Tuples tuple is an ordered list of elements.


> 2, 3;;
val it : int * int = (2, 3)

Records struktura struct- In computer science, a record (also


called tuple or struct) is one of the simplest data structures, consisting of two or

more values or variables stored in consecutive memory positions; so that each

component (called a field or member of the record) can be accessed by applying


different offsets to the starting address.

> type rational = { num: int; denom: int };;


type rational = { num : int; denom : int; }
let add p q =
{ num = p.num * q.denom + q.num * p.denom;
denom = p.denom * q.denom };;
val add_ratio : ratio -> ratio -> ratio = <fun>

Variants
> type expr =
| Int of int
| Var of string
| Plus of expr * expr
| Times of expr * expr;;
type expr =
| Int of int
| Var of string
| Plus of expr * expr
| Times of expr * expr;;

The match ... with construct evaluates the given expression and then
compares the result with a sequence of pattern matches:

match expression with


| pattern -> ...
| pattern -> ...
| pattern -> ...
match e with
| Int _ | Var _ -> true
| Plus _ | Times _ -> false

Functions and Variables


> fun n -> 2 * n;;
val it : int -> int
Variables are bound using the syntax let x = 3
Krace
> let double n = 2 * n;;
val double : int -> int
> let x = 2;;
val x : int = 2
> let x = 3 * x;;
val x : int = 6
> let x = x - 1;;
val x : int = 5

> let rec factorial n =


if n=0 then 1 else n * factorial(n - 1);;
val factorial : int -> int
> let rec factorial = function
| 0 -> 1
| n -> n * factorial(n - 1);;
val factorial : int -> int

Immutable Values vs Variables


The first mistake a newcomer to functional programming makes is thinking that the let construct is
equivalent to assignment. Consider the following code:
let a = 1
(* a is now 1 *)
let a = a + 1
(* in F# this throws an error: Duplicate definition of value 'a' *)
Pa mora
let a = 1 in
((* a stands for 1 here *);
(let a = (* a still stands for 1 here *) a + 1 in (* a stands for 2
here *));
(* a stands for 1 here, again *))

ndeed the code


let a = 1 in
(printfn "%i" a;
(let a = a + 1 in printfn "%i" a);
printfn "%i" a)

prints out

1
2
1

Once symbols are bound to values, they cannot be assigned a new value
Immutability allows programmers to pass values to functions without worrying that the
function will change the value's state in unpredictable ways. Additionally, since value can't
be mutated, programmers can process data shared across many threads without fear that
the data will be mutated by another process; as a result, programmers can write
multithreaded code without locks, and a whole class of errors related to race conditions and
dead locking can be eliminated.
Functional programmers generally simulate state by passing extra parameters to functions;
objects are "mutated" by creating an entirely new instance of an object with the desired
changes and letting the garbage collector throw away the old instances if they are not
needed.

Recursion or Loops petlje?

let processItems (items : Item []) =


for i in 0 .. items.Length do
let item = items.[i] in
proc item

Example
> let rec pow n x =
match n with
| 0 -> 1.
| n -> x * pow (n - 1) x;;
val pow : int -> float -> float

> let square = pow 2;;


val square : float -> float
> let cube = pow 3;;
val square : float -> float

let average a b = (a + b) / 2.0

open System

type Account(number : int, holder : string) = class


let mutable amount = 0m

member x.Number = number


member x.Holder = holder
member x.Amount = amount

member x.Deposit(value) = amount <- amount + value


member x.Withdraw(value) = amount <- amount - value
end

let homer = new Account(12345, "Homer")


let marge = new Account(67890, "Marge")

let transfer amount (source : Account) (target : Account) =


source.Withdraw amount
target.Deposit amount

let printAccount (x : Account) =


printfn "x.Number: %i, x.Holder: %s, x.Amount: %M" x.Number x.Holder
x.Amount

let main() =
let printAccounts() =
[homer; marge] |> Seq.iter printAccount
printfn "\nInializing account"
homer.Deposit 50M
marge.Deposit 100M
printAccounts()

printfn "\nTransferring $30 from Marge to Homer"


transfer 30M marge homer
printAccounts()

printfn "\nTransferring $75 from Homer to Marge"


transfer 75M homer marge
printAccounts()

main()

type Account =
class
new : number:int * holder:string -> Account
member Deposit : value:decimal -> unit
member Withdraw : value:decimal -> unit
member Amount : decimal
member Holder : string
member Number : int
end
val homer : Account
val marge : Account
val transfer : decimal -> Account -> Account -> unit
val printAccount : Account -> unit

Car
open System
open System.Net

type Car = class


val used : bool
val owner : string
val mutable mileage : int

(* first constructor *)
new (owner) =
{ used = false;
owner = owner;
mileage = 0 }

(* another constructor *)
new (owner, mileage) =
{ used = true;
owner = owner;
mileage = mileage }
end

let main() =
let printCar (c : Car) =
printfn "c.used: %b, c.owner: %s, c.mileage: %i" c.used c.owner
c.mileage

let stevesNewCar = new Car("Steve")


let bobsUsedCar = new Car("Bob", 83000)
let printCars() =
[stevesNewCar; bobsUsedCar] |> Seq.iter printCar

printfn "\nCars created"


printCars()

printfn "\nSteve drives all over the state"


stevesNewCar.mileage <- stevesNewCar.mileage + 780
printCars()

printfn "\nBob commits odometer fraud"


bobsUsedCar.mileage <- 0
printCars()

main()

F# Represe
.NET Type Size Range Example
Type nts
Integral Types

8-bit
1 42y
sbyte System.SByte -128 to 127 signed
byte -11y
integer

42uy 8-bit
byte System.Byte 1
0 to 255 200uy unsigned
byte
integer

16-bit
2 42s
int16 System.Int16 -32768 to 32767 signed
bytes -11s
integer

uint1 42us 16-bit


System.UInt16 2
6 0 to 65,535 200us unsigned
bytes
integer

32-bit
int/in 4 -2,147,483,648 to 42
System.Int32 signed
t32 bytes 2,147,483,647 -11
integer

uint3 42u 32-bit


System.UInt32 4
2 0 to 4,294,967,295 200u unsigned
bytes
integer

-
9,223,372,036,854, 42L 64-bit
int64 System.Int64 8
775,808 to -11L signed
bytes
9,223,372,036,854, integer
775,807

uint6 0 to 42UL 64-bit


System.UInt64 8
4 18,446,744,073,709 200UL unsigned
bytes
,551,615 integer

42I arbitrary
bigin System.Numerics.Bi ??
any integer 14999999999999999999999 precisio
t gInteger bytes 999999999I n integer
Floating Point Types

32-bit
signed
floating
float 4 42.0F point
System.Single ±1.5e-45 to ±3.4e38 -11.0F
32 bytes number
(7
significa
nt digits)

64-bit
signed
floating
8 ±5.0e-324 to 42.0 point
float System.Double
bytes ±1.7e308 -11.0 number
(15-16
significa
nt digits)

128-bit
signed
floating
decim 16 ±1.0e−28 to 42.0M point
System.Decimal
al bytes ±7.9e28 -11.0M number
(28-29
significa
nt digits)

Text Types

Single
2 'x' unicode
char System.Char U+0000 to U+ffff
bytes '\t' characte
rs

20 +
(2 *
strin string
System.String 0 to about 2 billion "Hello" Unicode
g 's "World"
characters text
lengt
h)
bytes
Other Types

Only two possible Stores


1 true
bool System.Boolean values, true orfa false boolean
byte
lse values

 Unit, the datatype with only one value, equivalent to void in C-style languages.

 Tuple types, which are ad hoc data structures that programmers can use to group related
values into a single object.
 Record types, which are similar to tuples, but provide named fields to access data held
by the record object.
 Discriminated unions, which are used to create very well-defined type hierarchies and
hierarchical data structures.
 Lists, Maps, and Sets, which represent immutable versions of a stack, hashtable, and set
data structures, respectively.
 Sequences, which represent a lazy list of items computed on-demand.
 Computation expressions, which serve the same purpose as monads in Haskell, allowing
programmers to write continuation-style code in an imperative style.

F# is a statically typed language, meaning that compiler knows the datatype of variables and
functions at compile time. F# is also strongly typed, meaning that a variable bound to ints
cannot be rebound to strings at some later point; an int variable is forever tied to int data.

let Multiply args =


let prod a = function Number(b) -> a * b | _ -> failwith "Malformed multiplication
argument."
Number(List.fold prod 1I args)

let Subtract = function


| [] -> Number(0I) // (-) == 0
| [Number(n)] -> Number(-n) // (- a) == –a
| Number(n) :: ns -> // (- a b c) == a - b – c
let sub a = function Number(b) -> a - b | _ -> failwith "Malformed subtraction
argument."
Number(List.fold sub n ns)
| _ -> failwith "Malformed subtraction."
let rec If = function
| [condition; t; f] –>
match eval condition with
| List([]) | String("") -> eval f // empty list or empty string is false
| Number(n) when n = 0I -> eval f // zero is false
| _ -> eval t // everything else is true
| _ -> failwith "Malformed 'if'."

and environment =
Map.ofList [
"*", Function(Multiply)
"-", Function(Subtract)
"if", Special(If)]

#light
2:
3: let ToAddress = "MyToAddress@domain.com"
4: let FromAddress = "MyFromAddress@domain.com"
5: let Subject = "F# Email Example"
6: let SMTPServer = "127.0.0.1"
7:
8: open System.Net.Mail
9:
10: let mm = new MailMessage()
11: mm.To.Add(ToAddress)
12: mm.From <- new MailAddress(FromAddress)
13: mm.Subject <- Subject
14: mm.Body <- "Hello, F# Email"
15:
16: let filePath = @".\CommaDelimitedFile.txt"
17: let att = new Attachment(filePath)
18: mm.Attachments.Add(att)
19:
20: let client = new SmtpClient()
21: client.Host <- SMTPServer
22: client.Send(mm)

public class anagram{

public static boolean areAnagrams(String string1, String string2){


String workingCopy1 = removeunwanted(string1);
String workingCopy2 = removeunwanted(string2);
workingCopy1 = workingCopy1.toLowerCase();
workingCopy2 = workingCopy2.toLowerCase();
workingCopy1 = sort(workingCopy1);
workingCopy2 = sort(workingCopy2);
return workingCopy1.equals(workingCopy2);
}

protected static String removeunwanted(String string){


int i, len = string.length();
StringBuffer dest = new StringBuffer(len);
char c;
for (i = (len - 1); i >= 0; i--){
c = string.charAt(i);
if (Character.isLetterOrDigit(c)){
dest.append(c);
}
}
return dest.toString();
}

protected static String sort(String string){


int length = string.length();
char[] charArray = new char[length];
string.getChars(0, length, charArray, 0);
java.util.Arrays.sort(charArray);
return new String(charArray);
}

public static void main(String[] args){


String string1 = "Silent";
String string2 = "Listen";
System.out.println();
System.out.println("Testing whether the following strings are anagrams:");
System.out.println("String 1: " + string1);
System.out.println("String 2: " + string2);
System.out.println();
if (areAnagrams(string1, string2)){
System.out.println(" anagrams!");
}
else{
System.out.println(" not anagrams!");
}
System.out.println();
}
} #light
let areAnagrams words =
let charsIn (s : string) =
let sChars = List.of_array (s.ToCharArray())
List.sort Char.compare sChars
match words with
| w1 :: (w2 :: ws) as ws' ->
let charsInHd = charsIn w1
List.for_all (fun x -> charsIn x = charsInHd) ws'
| _ -> false

You might also like