sobota, 30 stycznia 2016

Programowanie funkcyjne z wykorzystaniem języka F#

Pierwszy raz styczność z językiem F# miałem około półtora roku temu, kiedy to Michał Łusiak zaprezentował nam ten język podczas spotkania WG.NET. To był mój pierwszy kontakt z tym językiem. Pewne elementy wydawały się być całkiem fajne, inne nieco dziwne, ale ogólne wrażenie nt. tego języka jakie odniosłem po tej prezentacji było takie, że Microsoft traktuje ten język jako swego rodzaju "piaskownicę" oraz "miejsce treningowe" podczas wprowadzania rozszerzeń do języka C#. Że to jednak C# ma pozostać głównym językiem, bądź co bądź korporacyjnej platformy, natomiast F# to ma być takie laboratorium stworzone dla tzw. "szalonych naukowców" oraz innych eksperymentatorów, którzy będą tworzyć nowe rozszerzenia języka oraz platformy. Jeżeli stworzą coś nowego i uda im się to skompilować do MSIL, a przy okazji nic nie wybuchnie, to wtedy wszelkie nowości będzie można zaadaptować do C#.

W międzyczasie, możliwe że nawet wcześniej, podczas jednego ze szkoleń nt. C# prowadzonego przez Comarch, autor szkolenia wyjawił, że osobiście jest fanem języków funkcyjnych, oraz że obecnie, bardzo dużo, albo niemal wszystko co znamy z języków funkcyjnych da się zrobić w Linq, tyle tylko, że zapis jest wtedy nieco dłuższy i bardziej pokręcony.

Wracając jednak do właściwego F#, kolejnym takim momentem, przemawiającym na jego korzyść był fakt, iż podczas konferencji Wroc# 2015 ten język, obok Angular.JS dostał jedną z sesji prezentacyjnych (wszystkich sesji było 6). To oznaczało, że coś się dzieje.

Prawdziwym przełomem w moim postrzeganiu tego języka, była jednak konferencja devday 2015, podczas której nie tylko były sesje z jezyka F#, a na korytarzach można było osobiście porozmawiać z samym Tomasem Petrickiem, który nomenomen zrobił z jednego z niewielu dostepnych stolików swoisty "F# Corner" ;-) Prawdziwym przełomowym momentem, to był fragment prezentacji Chada Fawlera, która stanowiła keynote tej konferencji:

Chad mówi tam m.in., aby w obecnych czasach zainteresować się 3 tematami:
- linux (z którego aktualnie tworze tego posta)
- mobile development (jesienią tego roku przerobiłem kurs na courserze z programowania na platformę Android)
- programowanie funkcyjne, o którym tutaj właśnie się rozpisuje.

Więc czym tak naprawdę jest język F# i jak się do niego zabrałem?
F# jest to język o funkcyjnym paradygmacie programowania, w odróżnieniu np. od C#, Javy, Pythona lub C++, które są językami o obiektowym paradygmacie programowania. F# jest też integralnym językiem platformy .NET, co oznacza, że jego kod źródłowy kompilowany jest do języka MSIL, a dopiero później przerabiany na kod maszynowy. Język ten ma też kilka innych ciekawostek, które postaram się wylistować:
  • język funkcyjny (funkcyjny paradygmat programowania)
  • język kodu pośredniego platformy .NET
  • dopuszcza mix z kodem źródłowym innego języka .NET (przez co dopuszczalne jest korzystanie z bibliotek standardowych platformy .NET lub tworzenie projketów będących swoistymi mieszańcami C# oraz F#).
  • brak dynamicznego mapowania typów, co czasami bywa irytujące
  • wszystkie zmienne z definicji są stałe i niezmienne, ale możliwe jest tworzenie klasycznych zmiennych (poprzed dodanie słowa kluczowego "mutable"). Ma to na celu tworzenie ułatwienie rozwiązań pracujących w trybie zrównoleglonym (wielowątkowym)
  • "model aktorów", zwany tutaj "mailbox agent", znany m.in. z biblioteki "Akka" oraz "Akka.net" jest tutaj wbudowany jako naturalny element składowy jezyka 
  • open source - język jest w pełni otwarty i oficjalnie tworzony przez społeczność, choć część jego twórców dostaje za pracę nad projektem wypłatę z Microsoftu
  • hierarchia plików w solucji ma znaczenie (w odróżnieniu np. od C#, gdzie nie ma to znaczenia)
To co wypunktowałem, to są główne, charakterystyczne cechy tego języka, ale co one oznaczają w praktyce? Czym np. jest ten funkcyjny paradygmat programowania?
Funkcyjny paradygmat programowania, to w porównaniu do obiektowego paradygmatu programowania nieco inne spojrzenie na te same problemy.
   W przypadku programowania obiektowego, tworzymy klasy, jako definicję obiektów, w oparciu o które tworzymy obiekty. W tych obiektach "zamykamy" pewne dane, a nast. wykonujemy na nich pewne obiczenia. Mamy więc zbiory obiektów, każdy z nich wewnątrz ma swoje specyficzne dane, na których wykonuje obliczenia, często w sposób mniej lub bardziej tajny (tzw. enkapsulacja), a nast. operujemy na danych wynikowych wychodzących z tych obiektów.
   W przypadku programowania funkcyjnego mamy do czynienia z innym podejściem. Tutaj nie mamy typowych klas przedstawiających obiekty. Mamy za to funkcje, które przyjmują pewne wartości i które zwracają wyniki. Do tego mamy kilka typów kolekcji i... operujemy na danych z tych kolekcji za pomocą tworzonych funkcji. Jeżeli trzeba, to w naszych funkcjach, wykorzystujemy inne funkcje, w których możemy wykorzystywać kolejne funkcje itd. Oczywiście istnieje kilka typów kolekcji, różniących się od siebie właściwościami (np. sekwencje z definicji obsługują "lazy loading", natomiast Sety bazują na drzewie binarnym), jak i kilka typów kluczowych (np. rec sprawiających, że dana funkcja jest funkcją rekurencyjną).

Skąd czerpałem wiedzę?
Postanowiłem połączyć teorię z praktyką czyli:
  • Jako teorię czytałem książkę "F# for Quantitative Finance (Johan Astborg)", która ma raczej średnie opinie w necie, ale z uwagi, że wpadła w moje ręce za darmo podczas jednej z promocji na "Pact Publishing" to postanowiłem ja przeczytać i czegoś się z niej nauczyć.
  • Jako praktykę, postanowiłem wykonać przynajmniej 10 zadań z Project Euler. Jak mi poszło, można sprawdzić na w odp. projekcie, na moim koncie na githubie.
  • Połączenie jednego z drugim, czyli forum stackoverflow

Po tym nieco przydługim wstępnie, teraz czas na to, co tygryski lubią najbardziej, czyli konkluzje, czyli wnioski.
  • czytając opis języka w książce myślałem sobie, niby spoko
  • do czasu, aż zacząłem to programować samemu, wtedy co rusz napotykałem na dziwne błędy oraz zmuszenie mnie do zmiany sposobu myślenia
  • o ile pierwsze zadania z projektu euler były stosunkowo proste (przydała się praktyka w stos. linq oraz przykłady z książki, to im dalej w las tym trudniej)
  • sporo problemów i frustracji, szczególnie podczas pracy z pętlami przytrafił mi typ danych unit. Ponieważ jest on bardzo podobny do uint, na początku te typy mi się myliły, szczególnie, że F# nie pozwala na dynamiczną zmianę typów. Tworzyłem więc pętle, które z jakiegoś powodu w którymś momencie zwracały unit (brak wartości), natomiast mi się wydawało, że wraz z którąć iterecją, z nieznanego mi powodu zwracają one typ uint i mam problem z mapowaniem i porównywaniem typów. 
  • pętle w F# nie są typowymi "pętlami" tylko "wyrażeniami" lub "wyrażeniami wyższego rzędu", co oznacza, że nie posiadają typowego "break-a". Nie możemy w dowolnym momencie, ot tak sobie wyjść z pętli przerywając jej działanie, tylko musimy ją ładnie "zamknąć", tudzieź pozwolić aby wszystko się wykonało tak jak należy
  • sposobem, aby pętle nie trwały nieskończenie wiele, albo nie robiły zbyt dużo "pustych przelotów", jest zastosowanie sekwencji z ich "lazy loading", oraz słowa kluczowego "yield". Bardzo ładnie obrazuje to przykład rozwiązania problemu nr.9 https://github.com/zchpit/ProjectEuler/blob/master/F%23/ProjectEulerInF%23/ProjectEulerInF%23/Problem9.fs
  • kod napisany w F# zazwyczaj jest krótszy i bardziej "elegancki" niż w porównaniu do tradycjnej wersji C#
  • kod przynajmniej w teorii dużo łatwiej powinno się dać skalować (wielowątkowość)
  • choć nie wiem, jak wygląda kwestia jego wydajności względem C#
  • Chad Fowler zachęcał do nauki języków funkcyjnych, widząc w tym przyszłość
  • jednak ilość obecnych ogłoszeń o pracę na popularnych portalach z pracą (w PL) na chwilę obecną jakoś specjalnie do tego nie zachęca
  •  rozmawiając nt. temat z managerem jednej z firm deweloperskich, usłyszałem odp., że na razie to jest raczej nowość i nie ma na rynku zbyt dużo os., więc ewentualna zasępowalność jest niewielka i co za tym idzie na chwilę obecna bardziej ceniona jest dla nich chęć uniknięcia tzw. "Bus factor" niż "innowacyjność".
  • z drugiej strony, to natywne wsparcie dla programowania rozproszonego oraz wielowątkowego kusi, oj kusi :D

Reasumując, temat warty uwagi śledzenia. O ile obecnie jest zauważalny "hype" na konferencjach oraz grupach programistycznych, jednak jak na razie nie przekłada się to na ilość ofert pracy dla ludzi umiejących F#. W sumie najbardziej popularnym obecnie jezykiem funkcyjnym jest w polsce Scala, jednak tak naprawdę, ten język to takie "niewiadomo co", a z całą pewnością nie można go nazwać językiem typowo funkcyjnym. Z drugiej strony, od czasu rozpropagowania modelu aktorów do języków obiektowych, częściowo otwarta została pewna "nisza" wykorzystywana wcześniej jedynie przez języki funkcyjne.

Jak to się wszystko potoczy? Myślę, że bardzo dużo zależy od tego, czy będą się pojawiały ogłoszenia o pracę w tym konkretnym języku, zarówno pod względem ich ilości jak i jakości. W każdym bądź razie zamierzam temat bacznie obserwować, przynajmniej jeszcze przez jakiś czas :-)


piątek, 1 stycznia 2016

e-learning, pluralsight.com vs coursera.org

W tym wpisie postaram się opisać moje przemyślenia, nt. dwóch platform elearningowych, z których miałem okazję korzystać ost. jesieni.

Pierwszą platformą, z której skorzystałem jest to pluralsight.com.
Platforma dostarcza dwie opcje dostępu, tj. "standard" ograniczoną do oglądania filmów video, oraz "plus", w którórej dostępne są również ćwiczenia, sprawdzenia wiedzy oraz certyfikaty.

Standardowo, każdy może skorzystać z "free trail", dzięki któremu, możemy skorzystać z 10dni/200min darmowego dostępu. Dzięki uprzejmości Pawła Klimczyka miałem dostęp miesięczny dostęp do platformy za pomocą kodu promocyjnego.

Podczas mojej obecności na platformie, korzystałem z dostępu standard i obejrzałem dwa materiały szkoleniowe, jeden związany z Angular.js, oraz drugi, z językiem Scala. To na co zwróciłem uwagę, to spora ilość materiałów szkoleniowych, oraz wysoki poziom prezentowanych materiałów. Podczas kursu angular.js autor wykorzystywał plunkera, natomiast w prezentacji nt. języka scala autor pierwsze co zrobił, to postawił sobie środowisko z automatycznym testowaniem testów jednostkowych podczas pisania kodu oprogramowania. W środkowisku .net za podobną funkcjonalność odpowiada płatny plug-in do VS o nazwie NCrunch.

Kursy mi się podobały, można się było sporo nauczyć od profesionalistów, jednak wesja standard to jest jednak zdecydowanie za mało. Cały materiał pojedyńczego kursu podzielony jest na kilka półgodzinnych części. Nie wiem jak inni, ale u mnie, podczas oglądania półgodzinnego materiału z czasem spadało skupienie. Samo oglądanie, to jednak za mało. Zapewne dużo lepiej sprawdziła by sie wersja "plus", w której jest więcej ćwiczeń do samodzielnego opracowania tematu.

Warto też wspomnieć, że plularsight się rozwija i zakupił inne, podobne serwisy, takie jak np. codeschool.com ,który bardzo polubiłem swego czasu, jednak w momencie, kiedy testowałem ten serwis, to konta oraz płatności pomiędzy tymi serwisami nie były zintegrowane.


Drugą platformą do elearningu, którą miałem okazję ost. przetestować jest www.coursera.org.
Coursera, to platforma oparta o uczelnie wyższe, tj. renomowane uczelnie na codzień zajmujące się kształceniem studentów. Warto wspomnieć, ze w projekcie coursery można znaleźć takie uczelnie jak m.in. słynne MIT.
Coursera oferuje ścieżki nauki, w których znajdują się kursy, z różnymi dziedzinami danego zagadnienia prowadzone przez różne uczelnie. Każdy kurs składa się z 4 tygodni nauki. W każdym tyg. mamy część video z teorią, test wiedzy oraz kilka zadań praktycznych, które musimy wykonać samodzielnie, a nast. przesłać na uczelnię. Na każdym tyg. mamy deadline, w którym musimy się zmieścić z wykonaniem swoich zadań. Deadliny są dwa. Jeżeli wyrobimy się w pierwszym to ok, jeżeli jednak się z nim nie wyrobimy, to za każdy dzień zwłoki tracimy 5% punktów za odp. Nieryrobienie się w drugim deadline oznacza niezaliczenie zadania. W wersji płatnej możliwe są oficjalne certyfikaty wydawane przez uczelnie.

W moim przypadku był to kurs programowania urządzeń mobilnych w języku java na platformę Andrid prowadzony przez University of Maryland, College Park.  To co warte jest wspomnienia, to fakt, że podczas oglądania materiałow wideo, średnio co 3-5 min. była pauza z 1-3 pytań nt. omawianego materiału (pomaga w skupieniu się na omawianym materiale), oraz fakt, iż prowadzący od samego początku pokazuje, w których miejscach należy szukać informacji (linki do dokumentacji platformy, lokalnych grup użytkoników, forum stackoverflow.com, itp.). 
Bardzo fajny sposób nauki, który wymaga od ucznia, zarówno poznania teorii, samodzielnej pracy z kodem, jak i pracy na dokumentacji.
Główną wadą, jaką zauważyłem odnośnie coursery jest stosunkowo mała ilość dostępnych kursów / ścieżek. Np. szukałem ścieżki z programowania funkcyjnego i niestety niemogłem nic znaleźć.


Podsumowanie:
Obie platformy są bardzo fajne. 
W plularsight podobała mi się ilość dostępnych materiałów oraz profesionalne podejście prowadzących. Widać, że mamy do czynienia z zawodowcami, którzy od samego początku uczą "dobrych praktyk". Główną wadą tej wersji, z której korzystałem była zaby mała interakcja pomiędzy prowadzącym a prowadzonym. W wersji standard brakowało tego "learn by doing".  Możliwe, że w wersji "plus" te mankamenty zostały poprawione, jednak nie wiem czy stoją ona na tak wysokim poziomie, jak w courserze.

W courserze podobało mi się połączenie wykładów (materiały wideo), pracy na dokumentacji (testy na zaliczenie) oraz prac domowych z kodem (przygotowane wcześniej aplikacje, które trzeba nieco przerobić, aby zaczęły pracować tak jak chcemy). Główną wadą coursery jest dostępna ilość materiałów, oraz ich aktualność. Kurs, który ja przechodziłem miał już dobre 1.5 roku, więc zdąćył się już nieco zestarzeć poprawny kod programu działał tylko na emulatorach (maszynach wirtualnych) tylko niektórych androidów.

Co bym polecił?
Gdybym samemu miał wydawać własne pieniądze, to:
a) jeżeli ktoś nie ma żadnego doświadczenia, lub jest dopiero początkujący w jakiejś technologii, to dla takiej osoby polecił bym zacząć od wykonania pełnej ścieżki (6 kursów) na courserze. Zostanie ładnie oprowadzony po danej technologii, pozna jej różne aspekty, dzięki czemu będzie posiadał solidne podstawy.

b) jeżeli jednak ktoś ma podstawy i miał już okazję pracować w danej technologii, a chciałby jedynie podnieść swój poziom, tudzież się "doszkolić" w najnowszych trendach, to dla takich osób polecił bym plularsight.