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”

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# – наразі вже купа статей, книг, блогів..

Помічено як: , ,
 

Коментарі

# Vitalii Symon said:

давно хочу почати, навіть проги прості писав, а так і не почав :(

а як f# в порівнянні з немерле? з чого краще почати?

18 January 09 at 9:09 AM
# Mike Chaliy said:

>> а як f# в порівнянні з немерле?

Незнаю, судячи по опису немерле значно крутіший.

>> з чого краще почати?

Як бачете я почав з F#

Про немерле, тут проблема з затратами потрібними на вивчення, моє ІМХО для немерле вони значно більші. Хоча це все з описів. Принаймні, немерле стоїть у мене в черзі на глибше ознайомлення. Що мені сподобалось з опису, це макроси. Бо макросами можна вирішити поблеми, анприклад з нуллесс рядками.

18 January 09 at 9:36 AM
# rimonabantexcellence site title said:

Пінгбек від http://www.rimonabantexcellence.com/t.php?aHR0cDovL2Rldi5uZXQudWEvYmxvZ3MvbWlrZWNoYWxpeS9hcmNoaXZlLzIwMDkvMDEvMTgvNzUyMy5hc3B4

29 May 13 at 7:22 PM
Анонімні коментарі деактивовані. Увійдіть або Зареєструйтесь щоб мати доступ до ресурсів Спільноти.

About Mike Chaliy

Цікавлюсь DDD. Більшість часу витрачаю на доньку. А ще вел!