F#

Aug. 19th, 2010 05:00 pm
109: (Default)
[personal profile] 109
начал изучать F# сегодня после обеда. похоже, что к концу дня уже и закончил. никакой дополнительной гибкости по сравнению с C# не наблюдается. взять tuples. ок, я могу сматчить первый элемент как (x, _), аналогично head в списке. а как мне сматчить остаток (e.g. tail)? или как итерировать по тупелу заранее неизвестного типа? или как динамически создать тупел, имея, скажем, список типов элементов? а ведь без перечисленного мной ничего осмысленно реляционного не написать. вот у них ничего не пошевелилось в душе, когда они хуярили эти конструкторы?

Tuple(T1)
Tuple(T1, T2)
Tuple(T1, T2, T3)
Tuple(T1, T2, T3, T4)
Tuple(T1, T2, T3, T4, T5)
Tuple(T1, T2, T3, T4, T5, T6)
Tuple(T1, T2, T3, T4, T5, T6, T7)
Tuple(T1, T2, T3, T4, T5, T6, T7, T8)


bonus: Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)

видимо, Билл Гейтс сказал, что 16 параметров должно быть достаточно для любого метода.

(no subject)

Date: 2010-08-20 01:19 am (UTC)
From: [identity profile] sasha-gil.livejournal.com
а как мне сматчить остаток (e.g. tail)?

Вроде паттерны типа first::second::_ (сосиска может быть произвольной длины) должны работать.

По поводу енумирирования по произвольной tuple - это тебе, наверно, захотелось compile-time вычислений ("метапрограммирования" в стиле C++-темплейтов?), такого в F# нет.

(no subject)

Date: 2010-08-20 05:47 am (UTC)
From: [identity profile] thedeemon.livejournal.com
> first::second::_

Это для списков, не для туплов.
109 хочет использовать туплы как гетерогенные списки, а это без выкрутасов не типизируется. Есть ли в F# достаточные выкрутасы - не в курсе.

(no subject)

Date: 2010-08-20 06:46 am (UTC)
From: [identity profile] metaclass.livejournal.com
Отправить его читать Олега про HList и возрадоваться очередной душе, попавшей в цепкие лапы инфернального ФП :)

(no subject)

Date: 2010-08-20 07:36 am (UTC)
From: [identity profile] 109.livejournal.com
> 109 хочет использовать туплы как гетерогенные списки

нет. мне нужна удобная языковая поддержка датабазных кортежей. а туплами их назовут, или хрюплами, пофиг. собственно, самим словом tuple их так позиционировали, но использовать их для этой цели, как выяснилось, невозможно.

(no subject)

From: [identity profile] 184467440737095.livejournal.com - Date: 2010-08-20 09:39 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:31 am (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 10:24 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:42 am (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-21 07:10 am (UTC) - Expand

(no subject)

Date: 2010-08-20 07:33 am (UTC)
From: [identity profile] 109.livejournal.com
ну напиши мне функцию, которая принимает i и возвращает i-й по счёту элемент кортежа.

ну то есть если мы говорим, что F#-ские кортежи хороши для представления датабазных кортежей, то я прошу написать мне SqlDataReader.GetValue(i)

> тебе, наверно, захотелось compile-time вычислений

нет, мне как раз в рантайме надо это делать.

(no subject)

Date: 2010-08-20 07:47 am (UTC)
From: [identity profile] metaclass.livejournal.com
Нет, это как раз compile-time вычисления, т.к. подобная функция стандартными средствами не типизируется.
Собственно говоря, нет проблемы сделать это через Reflection, но это же натягивание совы на глобус и добровольный отказ от преимуществ статической типизации.
SqlDataReader.GetValue(i) и прочий ADO.NET, JDBC, итд - это динамическая типизация.

Чтобы одновременно было и это и статическая типизация - нужна очень хитрая система типов, с инкрементальной типизацией. Она все равно валится будет в рунтайме, если будут ошибки типов, т.е. гарантии валидности будут более слабые, но в отличие от теперешней чисто динамической типизации - валится будет раньше, на этапе prepare запроса (или еще раньше, при подключении к БД), а не на этапе выполнения с обращением к кривому типу и то если результат запроса не пустой.

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-20 07:54 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 08:09 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-20 11:28 pm (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 06:07 am (UTC) - Expand

(no subject)

From: [identity profile] vshabanov.livejournal.com - Date: 2010-08-20 09:39 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:34 am (UTC) - Expand

(no subject)

From: [identity profile] vshabanov.livejournal.com - Date: 2010-08-20 10:03 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:40 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2011-07-10 09:43 pm (UTC) - Expand

(no subject)

From: [identity profile] alexey-rom.livejournal.com - Date: 2010-08-20 05:44 pm (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:44 am (UTC) - Expand

(no subject)

Date: 2010-08-20 09:33 am (UTC)
From: [identity profile] 184467440737095.livejournal.com
есть у вас Tuple(T1, T2): (a, b)
вы хотите функцию, (T1, T2)->int -> ??? : f, такую что f(a,b)(1) = T1:a, f(a,b)(2) = T2:b
подозреваю что проверить при компиляции отсутствие ошибок типизации в выражении, содержащем такую функцию, нельзя, поэтому есть две отдельных функции (T1,T2)->T1: f(1) и (T1,T2)->T2: f(2), .Item1 и .Item2 соответвенно.

поскольку в момент компиляции метаданные отношения, для которого нужно создавать кортежи, вам не известны, то в любом случае с туплами или без них, придется динамически по описанию тупла генерить его тип и потом сами туплы.

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:26 am (UTC) - Expand

(no subject)

Date: 2010-08-20 06:45 am (UTC)
From: [identity profile] metaclass.livejournal.com
Вы с Хаскелем, замудреными системами типов и тому подобным оккультизмом хорошо знакомы?
"Динамически создать tuple, имя список типов" - во первых, не tuple а его тип, во вторых, это уже метапрограммирование или программирование на типах, кому что нравится.

В статически типизированных языках, действительно, часто не хватает таких возможностей и кажется, что они бы были серебряной пулей. Но это все до первой попытки реализовать их самостоятельно - в итоге оказывается, что получается что-то похоже или на Template Haskell с его адским вуду, или на Common Lisp с скобочками и макросами. Это если встраивать метапрограммирование в язык таким образом, чтобы его хоть как-то можно было использовать, не сломав мозг.

Альтернатива этому делу - кодогенерация, которая тоже не панацея. К широкому использованию непригодна, т.к. код кодогенератора при хоть сколько нибудь нетривиальной задаче превращается в жуткий ад.

Я сейчас как раз на F# пишу кодогенератор для model-driven design, накушался всего этого по полной программе :)

(no subject)

Date: 2010-08-20 07:17 am (UTC)
From: [identity profile] 109.livejournal.com
> "Динамически создать tuple, имея список типов" - во первых, не tuple а его тип

и тип, и сам кортеж. у меня есть метаданные, например [int; string; DateTime], а теперь мне надо создать инстанс и вставить в таблицу, ну или другую коллекцию по моему усмотрению.

всё это уже делалось разными фреймворками много раз, но за отсутствием языковой поддержки всегда выходило коряво. а тут, казалось бы, наконец можно сделать хорошо, ан нет, получилось как всегда.

(no subject)

Date: 2010-08-20 07:20 am (UTC)
From: [identity profile] metaclass.livejournal.com
вот, языковая поддержка:
> open System;;
> let tupleInstance = (1,"zhopej",DateTime.Now);;

val tupleInstance : int * string * DateTime =
(1, "zhopej", 20.08.2010 10:20:30)

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-20 07:47 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 08:00 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-20 08:19 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 08:36 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-20 09:49 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 10:12 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-20 10:48 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 11:00 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 02:12 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 06:19 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 02:09 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 06:18 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:52 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-21 07:11 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 07:40 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-21 08:01 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-20 11:29 pm (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 06:09 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-20 09:35 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 10:02 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-20 10:47 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:28 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-21 06:55 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 07:06 am (UTC) - Expand

(no subject)

From: [identity profile] zamotivator.livejournal.com - Date: 2010-08-21 07:11 am (UTC) - Expand

(no subject)

Date: 2010-08-20 08:48 am (UTC)
From: [identity profile] thedeemon.livejournal.com
Функция создания инстанса будет возвращать нечто, тип чего при компиляции неизвестен, т.к. определяется содержимым входного списка. Т.е. в рамках обычной статической типизации (а в F# она) это невозможно. Возможно в динамической (привет тонны тестов) и в зависимой (привет катаморфизмы, эндофункторы и санитары).

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 10:04 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:56 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:23 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 06:13 am (UTC) - Expand

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-22 10:39 pm (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2010-08-21 08:12 am (UTC) - Expand

(no subject)

Date: 2010-08-20 06:51 am (UTC)
From: [identity profile] metaclass.livejournal.com
А насчет гибкости F# - у меня пока на F# код получается сильно проще и читабельнее, чем аналогичный на C#, благодаря ADT, композиции функций, частичному применению функции, синтаксису с отступами и иммутабельности. Основная фича, которая делает F# гораздо более перспективнее других функциональных языков - интеграция с C# и прочим дотнетом, т.к. в других языках интеграция с внешним миром - исключительно через зад, то бишь чистый C, ручной маршалинг типов, указатели на указатели на указатели и прочий трэш.

(no subject)

Date: 2010-08-20 07:32 am (UTC)
From: [identity profile] 109.livejournal.com
у меня создалось впечатление, что пока код можно писать в рамках tuples, lists, sequences, dict и прочих родных структур, то да. но шаг вправо или влево - расстрел.

(no subject)

Date: 2010-08-20 07:39 am (UTC)
From: [identity profile] metaclass.livejournal.com
Еще там есть ADT, записи ну и классы с интерфейсами, как положено.

А что еще нужно, все остальное из этого комбинируется.

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-20 07:59 am (UTC) - Expand

(no subject)

Date: 2010-08-20 08:53 am (UTC)
From: [identity profile] volodymir-k.livejournal.com
ОК, реальный пример. Программа должна:
* спрашивать у юзера коннект к БД, таблицу, логиниться
* показать список полей
* показать первых 30 строк таблицы.
Юзер может ввести БД и таблицу, какие угодно (созданные после компиляции программы).

Ява, Бейсик, паскакаль, писон -- без проблем. Ф#?

(no subject)

Date: 2010-08-20 09:04 am (UTC)
From: [identity profile] metaclass.livejournal.com
Точно так же как в C# - ADO.NET, отражение информации о типах в рунтайме в виде данных(динамическая типизация) и вперед.

Статическая система типов F# в данном случае не поможет ничем и никак.

Хотя у меня есть идея реализовать именно для этого use case собственный фреймворк с инкрементальной типизацией и кодогенерацией-компиляцией в рунтайме. Пока отложено в долгий ящик, т.к. решение задачи требует сначала реализовать то же самое в более простом варианте, с предварительной кодогенерацией.
Ну и единственное место в продакшене где у меня динамическая и статическая типизации пересекаются - это когда из такого грида нужно отобразить написанный руками конкретно под данную таблицу редактор или выполнить какой-нибудь расчет, тоже исходя из данных таблицы. Приходится заниматься приведениями типов, обращениями по имени к полям, итд :)

(no subject)

From: [identity profile] 109.livejournal.com - Date: 2010-08-21 01:48 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-21 06:16 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2010-08-21 03:11 pm (UTC) - Expand
From: [identity profile] plumqqz.livejournal.com
Я так понимаю, тупль этот существует исключительно в виде платоновской идеи, да и то лишь в момент компиляции, так что попытки в рантайме получить что-то от него абсолютно бессмысленны - невозможно получить пятый элемент того, чего нет.
From: [identity profile] metaclass.livejournal.com
В рантайме он существует, т.е. можно от объекта вызвать GetType() и получить ссылку на рунтайм-описание типа.
From: [identity profile] plumqqz.livejournal.com
Ну, поди, вот во время компиляции и прописывается то, что должно вернуть GetType(). Эдакий перекормленный макропроцессор.

(no subject)

Date: 2010-08-20 11:22 pm (UTC)
From: [identity profile] 109.livejournal.com
> невозможно получить пятый элемент того, чего нет

это глубокая мысль, ничуть не уступающая другим глубоким мыслям типа "невозможно читать из потока после того, как он кончился", или "невозможно читать из массива по индексу, который out of bounds".

(no subject)

From: [identity profile] plumqqz.livejournal.com - Date: 2010-08-20 11:27 pm (UTC) - Expand

(no subject)

Date: 2010-08-20 10:29 am (UTC)
From: [identity profile] permea-kra.livejournal.com
Никто не мешает обходиться парами.
(a, (b, ( c, ..... )))
В этом случае не проблема проитерировать по элементам тапла, если в языке есть нормальный полиморфизм (как у недо-ML у F# должно хватить мозгов, но надо проверять). Однако в шарповом синтесисе это выглядит достаточно убого.

(no subject)

Date: 2010-08-20 10:46 am (UTC)
From: [identity profile] metaclass.livejournal.com
Вроде подходящего полиморфизма с ходу я там не вижу.

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 10:51 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 11:03 am (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 11:06 am (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 11:00 am (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 11:11 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2010-08-20 11:12 am (UTC) - Expand

(no subject)

From: [identity profile] vshabanov.livejournal.com - Date: 2010-08-20 12:14 pm (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 12:16 pm (UTC) - Expand

(no subject)

From: [identity profile] vshabanov.livejournal.com - Date: 2010-08-20 07:21 pm (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 07:30 pm (UTC) - Expand

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-20 07:31 pm (UTC) - Expand

(no subject)

From: [identity profile] vshabanov.livejournal.com - Date: 2010-08-20 08:08 pm (UTC) - Expand

(no subject)

Date: 2010-08-20 11:19 pm (UTC)
From: [identity profile] 109.livejournal.com
это интересное предложение. но это хак и оверхед, даже хуже чем теперешний object[] в ado.net

(no subject)

From: [identity profile] permea-kra.livejournal.com - Date: 2010-08-21 07:02 am (UTC) - Expand

(no subject)

Date: 2010-08-21 04:42 am (UTC)
From: [identity profile] selfmade.livejournal.com
Вы там в Майкрософте усыновили бы уже Немерле, а? Всего делов осталось - компилятор переписать. И будет счастье и с тупелями и с матчингом.

(no subject)

Date: 2010-08-21 07:07 am (UTC)
From: [identity profile] metaclass.livejournal.com
Да, было бы неплохо, идея языка весьма позитивная.

Profile

109: (Default)
109

March 2019

S M T W T F S
     12
3456789
101112131415 16
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags