18 January 2009
Чому мені сподобався F#...
В мене відпустка, і я вирішив зблизька подивитись на функціональні та динамічні мови. Отже далі про функціональну мову від Microsoft – F#.
Що мені сподобалось
1) Референс типи без null.
1: type Person{FullName:string}
2:
3: let AcceptPerson p
4: pringfn p.FullName // А тут не потрібно первіряти p на null
5:
6: AcceptPerson(null) // Таке не можливо
Тобто якщо викликати AcceptPerson з C# то туди можна закинути null. Але в середовищі F# все чудово, компілятор почне лаятись.
Нажаль тут є проблема. F# використовує System.String. А тому FullName таки може бути null.
2) “Безпомилкова” обрабока “enum-ів”. Насамперед це не енуми, це прості класи, але з чіткою ієрархією – це я про “union type”
1: type Content =
2: | Html
3: | Text
4: | Binary
Цей запис означає що у типу Content може бути тільки три значення. Якщо спробувати обробити його за допомогою аналога (в цьому випадку) switch-а, то отримаємо таке попередження:
“Incomplete pattern matches on this expression. For example, the value 'Binnary' will not be matched”
3) А як вам таке?
1: type Content =
2: | Html of string
3: | Text of string
4: | Binnary of byte[]
Це означає що кожен зі значень може приймати те ще написано після of…
1: let ToString c =
2: match c with
3: | Html s -> StripTags(s)
4: | Text s -> s
5: | Binnary b -> BytesToString(b)
А це як воно може оброблятися.
4) А як мінімалістично можна задавати типи…
1: type Person = {
2: FullName: string
3: Email: string
4: }
З точки зору CLR це повний тип, з проперятями, з конструктором, з компаратором і незмінний. Майже ані, крапки зайвого коду!
5) Вивід типів…
1: let BuildMe() = {
2: FullName = "Mike Chaliy";
3: Email = "mike@chaliy.name"
4: }
Зауважте що тут жодного типу. Але ж F# повністю(маніакально) типізована мова. Компілер все робить самотужки.
1: public static Person BuildMe()
2: {
3: return new Person("Mike Chaliy", "mike@chaliy.name");
4: }
Це щось на кшталт var в C#, але значно потужніший, наприклад по коду він зрозумів що мені потрібен Person.
6) Матчінг. В порівнянні C# switch, конструкція match в F# може робити дива. По-перше, як я вже і казав, match перевіряє правильність. По-друге, переходи можна робити за складними матчінгом.
1: let ToString2 c =
2: match c with
3: | Html s when s.StartsWith("<html>") -> StripTags(s)
4: | Html s -> StripTags(s)
5: | _
Тобто перша гілка піде для тих Html які починаються з “<html>”, а друга для всіх інших.
7) Функції, вони тут об’єкти першого класу, а отже можуть бути аргументами, полями, тощо..
Ну і в інший бік, що мені не сподобалось
1) Як я вже казав рядки. Вони можуть бути null. Я для цього просто написав свою реалізацію рядка.
1: JustString s1 = "test"; // JustString не може бути null
2: string s2 = s1;
3: Console.WriteLine(s2 == s1);
Я вже зробив проект на CodePlex за декілька днів пробалішу.
2) Компіляція залежить від порядку файлів. Тут два рішення, або в файлі проекту руками сортувати, або використовувати файли дефенішени (щось на кшталт h файлів в С++) – fsi.
3) Нема підтримки папок в студії.
4) Дуже слабка підтримка студії. Тут і відсутність темплейтів, і рефакторінгів, і дизайнерів.
5) В угоду сумісності з OCaml залишаються артефакти які нікому не потрібні, наприклад директива light#.
6) Поки що проблеми з іменами базової бібліотеки. Так тут можна знайти zero_create, exists2, FromList – тобто в бібліотеці можна знайти і камл, і паскаль, і підкремелння, і нові версії функцій з номерами… Певне більшість такого зроблено для сумісності, але ж!
7) Немає неявного кастінгу інтерфейсів. Тобто якщо у вас є функція яка повертає інтерфейс, і клас який цей інтерфейс реалізовує, то вам все одно потрібно зробити кастінг в інтерфейс.
1: let Create() =
2: new Implemenation.DefaultBlogManager() :> IBlogManager
3: // тут ми DefaultBlogManager закастили к IBlogManager
8) Поки що мало прикладів. З цим можна жити, але тяжко ;).
Висновок
Класний мінімалістичний язик, для того щоб він став читабельним потрібно тренуватися. Перше враження – місиво незрозумілих команд, потім - лаконічний струмок. Дозволяє дуже сильно спростити валідацю коду.
Ресурси
The F# 1.9.6 Draft Language Specification – добре написана спека, я не знаю чи складно її використовувати для того щоб написати F#, а ось для щоб вивчати вона просто супер.
hubFS: THE place for F# – F# комуніті, дуже жвавий форм, відповідають одразу, там же тусуються і розробники.
Пошук по F# – наразі вже купа статей, книг, блогів..
Цікавлюсь DDD. Більшість часу витрачаю на доньку. А ще вел!