slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Czyli funkcyjny .NET Jakub Rusiłko PowerPoint Presentation
Download Presentation
Czyli funkcyjny .NET Jakub Rusiłko

Loading in 2 Seconds...

play fullscreen
1 / 37

Czyli funkcyjny .NET Jakub Rusiłko - PowerPoint PPT Presentation


  • 125 Views
  • Uploaded on

F#. Czyli funkcyjny .NET Jakub Rusiłko. Plan prezentacji. Wstęp Co to jest programowanie funkcyjne C# vs F# Cechy języka F# Typy Currying i Partial Function Application OOP w F# Asynchroniczność w F#. Wstęp. Kim jestem? Dlaczego F# i co fajnego jest w programowaniu funkcyjnym?.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Czyli funkcyjny .NET Jakub Rusiłko' - velika


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1

F#

Czyli funkcyjny .NET

Jakub Rusiłko

plan prezentacji
Plan prezentacji
  • Wstęp
  • Co to jest programowanie funkcyjne
  • C# vs F#
  • Cechy języka F#
  • Typy
  • Currying i PartialFunction Application
  • OOP w F#
  • Asynchroniczność w F#
wst p
Wstęp
  • Kim jestem?
  • Dlaczego F# i co fajnego jest w programowaniu funkcyjnym?
zniech caj cy kod funkcyjny
Zniechęcający kod funkcyjny

((n.lisp_token_pos_guessis to)

((year))

((p.lisp_token_pos_guessissym)

((pp.lisp_token_pos_guessissym)

((cardinal))

((lisp_num_digits<4.6)((year))((digits))))

((lisp_num_digits<4.8)

((name<2880)

((name<1633.2)

((name<1306.4)((cardinal))((year)))

((year)))

((cardinal)))

((cardinal)))))))))

pogramowanie funkcyjne kilka definicji
Pogramowanie funkcyjne – kilka definicji
  • Programowanie funkcyjne (z wikipedii) – filozofia i metodyka programowania będąca odmianą programowania deklaratywnego, w której funkcje należą do wartości podstawowych, a nacisk kładzie się na wartościowanie (często rekurencyjnych) funkcji, a nie na wykonywanie poleceń.
  • Programowanie funkcyjne jest jak opisywanie twojego zadania matematykowi. Programowanie imperatywne jest jak wydawanie instrukcji idiocie.
  • Programowanie funkcyjne traktuje wykonanie programu jak ewaluację funkcji matematycznej i stara się unikać stanu oraz zmiennych.
podzia j zyk w funkcyjnych
Podział języków funkcyjnych
  • języki czysto funkcyjne - nie ma zmiennych, nie ma efektów ubocznych, leniwe wartościowanie, we/wy musi się odbywać alternatywnym sposobem, jak na przykład monady (np. Haskell)
  • języki mieszane - można stosować zmienne, tworzyć efekty uboczne, tradycyjne we/wy, mieszać styl funkcyjny z imperatywnym lub obiektowym, wartościowanie przeważnie zachłanne (np. Lisp, Clojure, Scheme, Erlang, Scala, F#)
kiedy programowanie funkcyjne mo e okaza ci si pomocne
Kiedy programowanie funkcyjne może okazać ci się pomocne
  • Gdy masz trudności z przewidzeniem rezultatu zmian w swoim kodzie z powodu ukrytych zależności i subtelności
  • Gdy zdajesz sobie sprawę, że ciągle tworzysz te same wzorce i szablony poświęcając mało czasu na kluczowe i interesujące aspekty problemu
  • Masz trudności z analizą swojego kodu i martwisz się tym, czy dany fragment zostanie wykonany we właściwej kolejności i przy odpowiednich warunkach
  • Masz trudności z wyrażaniem abstrakcji, która ukrywa JAK kod ma się wykonać, a wyraża tylko CO chcesz osiągnąć
  • Masz problemy z ogarnięciem kontroli nad kodem asynchronicznym
  • Gdy kod zachowuje się inaczej na produkcji i inaczej podczas testów jednostkowych
f historia
F# - Historia
  • Początki programowania funkcyjnego to Information Processing Language z 1956, a potem Lisp w 1958
  • Języki funkcyjne szybko zostały wyparte przez języki imperatywne jak Fortran (1957) czy COBOL (1959)
  • W 1973 powstaje język ML. Jest on na tyle dobry, że powstaje wiele języków pochodnych jak Standard ML, Caml i OCaml, który łączy styl funkcyjny z obiektowo zorientowanym stylem imperatywnym
  • W 2005 powstaje F#, który w dużej mierze jest .NETowąimplemantacjąOCamla.
cechy j zyka f
Cechy języka F#
  • Statycznie typowany – kompilator zna typy zmiennych i funkcji w momencie kompilacji
  • Silnie typowany – zmienne nie zmieniają swojego typu
  • F# nie przeprowadza automatycznego rzutowania typów (tak jak C# czy VB), trzeba rzutować explicite
  • Zachęca do tworzenia kodu z użyciem zmiennych niemutowalnych, ale pozwala używać zmiennych mutowalnych, jeśli jest to konieczne
  • Pozwala na korzystanie z bibliotek napisanych w innych językach rodziny .NET i bez problemu się z nimi łączy
  • Łączy zalety języka funkcyjnego z obiektowym
  • Zamiast nawiasów klamrowych { i } stosuje wcięcia linii
  • Wnioskowanie typów (TypeInference) – analogicznie do var w C#
cechy j zyka f1
Cechy języka F#
  • Nie używamy słowa return – zwrot wartości z funkcji jest automatyczny
  • Unit zamiast void
  • Automatyczna generalizacja
  • Kolejność plików w projekcie ma znaczenie
prosty program w f
Prosty program w F#

openSystem

let a =2

Console.WriteLine a

prosty program w c
Prosty program w C#

using System;

namespace ConsoleApplication1

{

classProgram

{

staticint a()

{

return2;

}

staticvoidMain(string[] args)

{

Console.WriteLine(a);

}

}

}

f interactive
F# Interactive
  • Interaktywna konsola wspomagająca programowanie
  • DEMO
typy w f
Typy w F#
  • Typy proste (int, char, float, …)
  • Typy z bibliotek .NET
  • Typy właściwe dla F#
tuples krotki
Tuples (Krotki)
  • let t1 = (2,3)
  • lett2 = ("hello",42)
  • lett3 = (42,true,"hello")
  • let z =1,true,"hello",3.14// "construct"
  • let z1,z2,z3,z4 = z // "deconstruct"
  • let _,z5,_,z6 = z // ignore 1st and 3rd elements
  • letfirst=fst t1
  • letsecond=snd t1
prosta zamiana miejscami w krotce tuple w f vs c
Prosta zamiana miejscami w Krotce (Tuple) w F# vs C#

F#

C#

Tuple<U, T> Swap<T, U>(Tuple<T, U> t)

{

returnnewTuple<U, T>(t.Item2, t.Item1);

}

letswap (x,y) = (y,x)

records rekordy
Records (rekordy)
  • typeComplexNumber= { real: float; imaginary: float }
  • typeGeoCoord= { lat: float; long: float }
  • letmyGeoCoord= { lat=1.1; long =2.2 } // "construct"
  • let { lat=myLat; long=myLong } =myGeoCoord// "deconstruct”
  • let x =myGeoCoord.lat
  • let g1 = {lat=1.1; long=2.2}
  • let g2 = {g1 withlat=99.9} // create a new one
discriminated union type
Discriminated Union Type
  • Typ będący sumą kilku typów

typeIntOrBool=

| I ofint

| B ofbool

type Person = {first:string; last:string} // define a record type

typeIntOrBool= I ofint | B ofbool

typeMixedType=

| Tupofint*int// a tuple

| P of Person // use the record type defined above

| L ofint list // a list of ints

| U ofIntOrBool// use the union type defined above

discriminated union vs enum oraz pattern matching
Discriminated Union vs enum oraz PatternMatching
  • typeSizeUnion= Small | Medium | Large // union
  • typeColorEnum= Red=0 | Yellow=1 | Blue=2// enum
  • DEMO
null i option type
Null i Option type
  • W czystym F# nie ma pojęcia nulla (istnieje tylko w celu kompatybilności z .net)
  • Aby oznaczyć brak wartości stosujemy Option Type
  • Podobne do Nullable w C# z tą różnicą, że Option można użyć z dowolnym typem (również na typach referencyjnych, klasach, itp.)

type Option<'a>=

| Someof'a

| None

  • DEMO
units of measure
Units of measure
  • [<Measure>] type m
  • [<Measure>] type sec
  • [<Measure>] type kg
  • letdistance=1.0<m>
  • lettime=2.0<sec>
  • letspeed=2.0<m/sec>
  • letacceleration=2.0<m/sec^2>
  • letforce=5.0<kg m/sec^2>
  • [<Measure>] type N = m/sec^2
kolekcje listy
Kolekcje - Listy

letnumbers = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

letnumbers2=1::2::3::4:: []

letnumbers3 = [1..5]

letnumbers4= [1..2..10]

letnumbers5 =List.init10 (fun i -> i)

  • DEMO
kolekcje sekwencje
Kolekcje - Sekwencje
  • Są podobne do list z tą różnicą, że ich wartości są wyliczane na bieżąco, gdy są potrzebne (leniwie - LAZY)

let sequence1 =seq { 1..10}

let sequence2 =seq {10..-1..0}

let sequence3 =seq { for a in1..10doyield a, a*a, a*a*a }

  • DEMO
niezmienno immutability
Niezmienność (Immutability)
  • Słowo kluczowe letdefiniuje wartość
  • Value Binding – (wiązanie wartości) pozwala powiązać wartość z symbolem
  • Niezmienność wymusza inne spojrzenie na problemy
  • Każda kolejna operacja na zadeklarowanej wartości tworzy nową wartość (nie zmienia starej) – analogia do typu string z C#
  • Rekurencja zamiast pętli
  • Niezmienność zachęca do używania pojedynczych wyrażeń zamiast sekwencji poleceń sprawiając, że program jest bardziej deklaratywny

Przykład w C#:

varres =ImmutableList.Empty<int>().Add(1).Add(3).Add(5).Add(7); //Sytem.Collections.Immutable (.NET 4.5)

funkcje jako warto ci
Funkcje jako Wartości
  • Funkcja jest wartością i może być użyta w każdej sytuacji, w której możemy użyć zwykłego int’a czy string’a (First-classfunctions), każda funkcja ma typ (w C# używamy do tego delegatów, w F# typ jest właściwością samej funkcji)
  • W szczególności funkcja może być parametrem do innej funkcji lub wynikiem wyjściowym funkcji – funkcje wyższego rzędu (Higher-order functions)
  • DEMO (agregacja)
sygnatura funkcji
Sygnatura FUnkcji
  • int -> int -> int
  • int -> unit
  • unit -> string
  • int -> (unit -> string)
  • 'a list -> 'a
  • ('a -> bool) -> 'a list -> 'a list
  • DEMO
currying
Currying
  • Ale dlaczego sygnatury funkcji nie rozróżniają między parametrami a typem wyjściowym?
  • CURRYING– rozbijanie wieloargumentowych funkcji na mniejsze jedno-parametrowe funkcje
  • HaskellCurry – matematyk, który przyczynił się do rozwoju programowania funkcyjnego
  • int -> int -> int jest tak naprawdę połączeniem więcej niż jednej funkcji
  • Nie musimy się tym martwić, kompilator robi to za nas automatycznie
  • DEMO
partial function application
Partialfunctionapplication
  • Dzięki curryingowiwywołanie funkcji z mniejszą ilością parametrów, niż to wynika z definicji funkcji, jest dozwolonym działaniem
  • Wywołanie funkcji z n-początkowymi parametrami zwróci nową funkcję przyjmującą pozostałe (z oryginalnej funkcji) parametry
  • Właściwość ta jest jednym z najważniejszych narzędzi programowania funkcyjnego
  • DEMO
kilka ciekawych operator w
Kilka ciekawych operatorów
  • |> - forwardpipe operator – przekazuje rezultat operacji po lewej stronie do funkcji po prawej stronie
  • <| - backwardpipe operator
  • >> - forwardcomposition operator - złożenie funkcji
  • << - backwardcomposition operator - złożenie funkcji (w odwrotnej kolejności)
  • DEMO
obiektowy f
Obiektowy F#
  • Pozwala zaimplementować algorytmy obiektowe 1 do 1
  • Ułatwia integrację z .NETem
  • Dla początkujących może przysłonić korzyści płynące z programowania czysto funkcyjnego
  • Nie współpracuje dobrze z funkcjami wyższego poziomu oraz z wnioskowaniem typów
  • DEMO
object expressions
Object expressions
  • Pozwala implementować interfejs w locie bez potrzeby tworzenia klasy

letmakeResourcename=

{ newSystem.IDisposable

withmemberthis.Dispose() =printfn"%s disposed" name }

messages and agents
Messages and Agents
  • MailboxProcessorimplementuje podejście bazujące na agentach i wiadomościach (kolejki wiadomości)
  • Działa w osobnym wątku
  • Pozwala łatwo zarządzać dzielonymi zasobami bez zakleszczeń
  • Umożliwia łatwe rozdzielenie odpowiedzialności poprzez tworzenie osobnych agentów obsługujących różne rzeczy
  • DEMO
quicksort c
Quicksort C#

publicclassQuickSortHelper

{

publicstaticList<T> QuickSort<T>(List<T> values) whereT : IComparable

{

if (values.Count==0) { returnnewList<T>(); }

T firstElement=values[0];

varsmallerElements=newList<T>();

varlargerElements=newList<T>();

for (int i =1; i < values.Count; i++)

{

varelem=values[i];

if (elem.CompareTo(firstElement) <0) { smallerElements.Add(elem); }

else {largerElements.Add(elem);}

}

varresult=newList<T>();

result.AddRange(QuickSort(smallerElements.ToList()));

result.Add(firstElement);

result.AddRange(QuickSort(largerElements.ToList()));

returnresult;

}

}

quicksort f w stylu funkcyjnym
Quicksort F# - w stylu funkcyjnym

letrecquicksort list =

match list with

| [] -> []

| firstElem::otherElements->

letsmallerElements=otherElements|>List.filter (fun e -> e <firstElem) |>quicksort

letlargerElements=otherElements|>List.filter (fun e -> e >=firstElem) |> quicksort

List.concat [smallerElements; [firstElem]; largerElements]

letrec quicksort2 =function

| [] -> []

| first::rest->

letsmaller,larger=List.partition ((>=) first) rest

List.concat [quicksort2 smaller; [first]; quicksort2 larger]

r d a
Źródła
  • http://pl.wikipedia.org/wiki/Programowanie_funkcyjne
  • http://fsharpforfunandprofit.com/
  • http://en.wikibooks.org/wiki/F_Sharp_Programming
  • Real-World Functional Programming, TomasPetricek i Jon Skeet, Manning Publications, 2010