Powiem wam że rozpiera mnie duma. Moje szaleństwo zostało docenione. Wcięgneli moje repa (Asembler i Interpreter) do https://github.com/wspace/corpus czyli kolekcji projektów związanych z ezojęzykiem WhiteSpace. Chyba sobie to w CV wpiszę
Functional programming education
https://bitemyapp.com/blog/functional-education/
przecież autor poleca cis194 i NICTA
@Saalin Jeśli dobrze zrozumiałem to poleca do pracy z nauczycielem. Jak nie ma nauczyciela to jest trochę gorzej. Ja np jedynym nauczyciel na jakiego mogę liczyć w okolicy to jak mi ktoś na 4p odpisze. Dlatego z chęcią zapisałbym sie na jakiś bootcamp po polsku o Haskellu :P
@KamilAdam: jakbyś był we Wrocławiu to na UWr był kurs Haskella https://zapisy.ii.uni.wroc.pl/offer/728-kurs-jezyk-haskell/ Zawsze można przychodzić jako wolny słuchacz.
Przygody Hobby Haskellera na rozmowach kwalifikacyjnych - pytania techniczne o Haskella
Może komuś się przyda
Jako że od początku pandemi ucze się hobbystycznie Haskella postanowiłem sprawdzić czego musze się douczyć żeby zostać komercyjnym programistą Haskella i niezobowiązująco wysłać parę CV.
W rezultacie wylądowałem na rozmowie z drugim Kamilem o nieznanej mi twarzy i pochodzeniu, ale dobrym angielskim, chociaż bardzo cichym oraz biznesowym azjatą którego nie rozumiałem, bo mówił przez maskę XD (cóż wiadomo, biali to zaraza i zarażają nawet przez rozmowę online). Azjata szybko powiedział to co musiał i zostałem z technicznym Kamilem który miał sprawdzić moje umiejętności kodowania.
Pierwsze pytanie - napisz drzewo binarne:
To akutat proste, kopijemy z SO
data BTree a = Leaf | Node a (BTree a) (BTree a)
Putanie drugoe - napisz folda dla tego drzewa:
Dla niewtajemniczonych - fold
to niskopoziomowa funkcja do przechodzenia po strukturze, jak mamy fold
to można zdefiniować map
, filter
i inne potrzebne funkcje do pracy z kolekcją
Znów kopiujemy z SO
foldTree :: (a -> b -> b) -> b -> BTree a -> b
foldTree _ base Leaf = base
foldTree f base (Node a leftTree rightTree) = foldTree f base' leftTree
where
base' = f a base''
base'' = foldTree f base rightTree
Pytanie trzecie - to jest prawy fold czy lewy fold?
Pytanie czwarte - co to jest
go :: (a -> Either a b) -> a -> b
Sprawdzamy w Hoogle i wychodzi że to loop
(to w Haskellu jest loop
? Moje WTF, czyli w Haskellu nie trzeba używac rekurencji wprost skoro jest loop?)
Pytanie piąte - napisz implementacje do loopa
Wchodzimy w dokumentację loopa i przepisujamy swoimi słowami:
loop :: (a -> Either a b) -> a -> b
loop f a = check (f a) where
check (Right b) = b
check (Left a') = loop f a'
Pytanie szóste - przepisz foldTree tak żeby nie używało rekurencji, a używało loopa
Tu już wymiekłem i sie poddałem. Będę musiał to przećwiczyć loop
a, pewnie drzewa też (chociaż jeszcze nie wiem gdzie je wepchnąć do mojego projektu :D )
Dla chętnych chcących zobaczyć loop
a w akcji, normalna silnia rekurencyjna w Haskellu
main = print (factorial 6)
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n - 1)
Wersja używająca pętli:
main = print (factorial' 6)
factorial' :: Int -> Int
factorial' n = loop f (n , 1) where
f (0 , result) = Right result
f (n , result) = Left (n - 1 , n * result)
--Potrzebne jak chcesz uruchomić przykład w kompilatorze online, normalnie się importuje `Control.Monad.Extra`
loop :: (a -> Either a b) -> a -> b
loop f a = check (f a) where
check (Right b) = b
check (Left a') = loop f a'
Czy to jest czytelniejsze? Nie wiem, ale przetestuje :D
Komentarz do przykładu w Ruscie nt. Phantom types - PhantomData
w wektorach tam jest zupełnie bezsensowny, ale to jest test, więc w testach robi się bezsensowne rzeczy.
Co do loopa, to można to całkiem zgrabnie zrozumieć jak to ogarnąć poprzez zobaczenie jak to będzie wyglądało w imperatywnym języku:
fn loop<T, U, F>(mut val: T, f: F) -> U where F: Fn(T) -> Result<U, T> {
loop {
match f(val) {
Ok(ret) => return ret,
Err(next) => val = next
}
}
}
Problem z implementacją foldTree
używając loop
jest taki, że nagle nam się komplikuje, bo musimy implementować kolejkę, co powoduje, że kod staje się strasznie nieczytelny.
Coś pomiędzy Haskellem, a Rust, choć nie do końca język do pisania kodu
https://github.com/Kindelia/HVM
warto poczytać, jak kogoś ciekawią maszyny, kompilatory itp.
To taki język(platforma) w stylu LLVM, C-- czy nawet bardziej STG czyli nie do pisania, ale do wygenerowania przez front kompilatora i odpalenia.
Cel: możliwość pisania funkcyjnie z wydajnością zbliżoną do Rust, a to wszystko dzięki dup
ie (zobacz dokumentację).
Przy okazji dowiedziałem się, że istnieje język Kind (czyli kolejny Haskell, ale bez historycznych zwałek
).
A massively parallel, optimal functional runtime in Rust - GitHub - Kindelia/HVM: A massively parallel, optimal functional runtime in Rust
https://github.com/Kindelia/HVMSłyszeliście o Bosque i regularized programming?
Niedawno migneły na mikroblogu
Bo ja usłyszałem i powiem szczerze że rzygam. Może nie oczeliwaliście takiej szczerości, ale czułem że muszę się tym podzielić z wami.
Dlaczego rzygam, pewnie (nie) chcecie zapytać?
Bo marketing Bosque to marketing MicroShitu w najgorszym możliwym wydaniu. Na wikipedii Można przeczytać że
Marron believes we can do better by getting rid of sources of complexity like loops, mutable state, and reference equality. The result is Bosque, which represents a programming paradigm that Marron, in a paper he wrote, calls "regularized programming."
Może powinienem znaleźć lepsze źródło informacji, ale nie mogę, bo rzygam.
A teraz trochę historii:
Ale to inżynier MicroShitu wymyślił że języki nie powinny mieć pętli i mutowalnego stani i nazwał to "regularized programming" mimo że już wcześniej nazywało się to programowanie funkcyjne. Rzygam
UPDATE chociaż może nie będzie źle i będziemy mieć nowy funkcyjny język programowania którego użytkownicy nie będą wiedzieć że jest językiem funkcyjnym, tak jak użytkownicy C# nie wiedzą że C# ma dedykowaną składnię do przetwarzania monad :D
Na spotkaniu pesymistów i krytyków:
Nie wiem jak do tego doszło, ale na The Computer Language Benchmarks Game Haskell przegonił Javę :D
Chociaż różnice wydajności od OCamla po Lispa są tak małe że pewnie przy kazdej publikacji nowego raportu są totalne zmiany w miejscach (Kilka miesięcy temu Haskell był szybszy niż OCaml, a teraz OCaml jest szybszy niż Java i Haskell :D )
UPDATE
Chyba za mało śmiejących się buziek dałem w tym wpisie żeby ludzie się zorientowali że nie traktuję tego porównania całkowicie serio :D (Zwłaszcza jak różnica między niektórymi językami jest tak mała i w przeciągu roku jest przeskok OCamla o co 4 miejsca :D )
Więc doklejam tu kilka śmiejących się buziek :D :D :D :D :D :D :D
"Czy głównym celem tych benchmarków jest konfudowanie ludzi?" Można przeczytać w History jaki był cel pierwszego autora (porównanie języków skryptowych). Jaki jest aktualny cel teraz to ja nie wiem :D "może są one po to, żeby programistom nie było zbyt nudno i żeby mogli się spuszczać nad swoim ulubionym językiem." Jak ktoś się spuszcza nad językiem programowania to jego sprawa. Jakbym chciał spuszczać sie nad tym jaki mój ulubiony język jest szybki to zacząłbym pisać w Ruscie :D Ani Java, ani Haskell nie trafią pewnie nigdy na podium najszybszych języków programowania. A jeśli trafią to będzie to pewnie inna Java lub inny Haskell niż znamy dziś (Z o wiele większą ilością niskopoziomowego kodu) :D Chyba za mało śmiejących się buziek dałem wtym wpisie żeby ludzie się zorientowali że nie traktuję tego porównania całkowicie serio :D Zwłaszcza jak różnica między niektórymi językami jest tak mała i w przeciągu roku jest przeskok OCamla o co 4 miejsca :D
Free Pascal ma już lepszą efektywność niż C++ — i to mi odpowiada. ;)
Chociaż ciul wie, nie umiem czytać tego wykresu.
@lizme: Ale co byś chciał? Assembler do brainfucka? Ale takich projektów jest od cholery, np https://esolangs.org/wiki/Asm2bf . Dlatego (na razie) się tam nie pcham XD