начал изучать 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 параметров должно быть достаточно для любого метода.
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)Вроде паттерны типа first::second::_ (сосиска может быть произвольной длины) должны работать.
По поводу енумирирования по произвольной tuple - это тебе, наверно, захотелось compile-time вычислений ("метапрограммирования" в стиле C++-темплейтов?), такого в F# нет.
(no subject)
Date: 2010-08-20 05:47 am (UTC)Это для списков, не для туплов.
109 хочет использовать туплы как гетерогенные списки, а это без выкрутасов не типизируется. Есть ли в F# достаточные выкрутасы - не в курсе.
(no subject)
Date: 2010-08-20 06:46 am (UTC)(no subject)
Date: 2010-08-20 07:36 am (UTC)нет. мне нужна удобная языковая поддержка датабазных кортежей. а туплами их назовут, или хрюплами, пофиг. собственно, самим словом tuple их так позиционировали, но использовать их для этой цели, как выяснилось, невозможно.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
Date: 2010-08-20 07:33 am (UTC)ну то есть если мы говорим, что F#-ские кортежи хороши для представления датабазных кортежей, то я прошу написать мне SqlDataReader.GetValue(i)
> тебе, наверно, захотелось compile-time вычислений
нет, мне как раз в рантайме надо это делать.
(no subject)
Date: 2010-08-20 07:47 am (UTC)Собственно говоря, нет проблемы сделать это через Reflection, но это же натягивание совы на глобус и добровольный отказ от преимуществ статической типизации.
SqlDataReader.GetValue(i) и прочий ADO.NET, JDBC, итд - это динамическая типизация.
Чтобы одновременно было и это и статическая типизация - нужна очень хитрая система типов, с инкрементальной типизацией. Она все равно валится будет в рунтайме, если будут ошибки типов, т.е. гарантии валидности будут более слабые, но в отличие от теперешней чисто динамической типизации - валится будет раньше, на этапе prepare запроса (или еще раньше, при подключении к БД), а не на этапе выполнения с обращением к кривому типу и то если результат запроса не пустой.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
Date: 2010-08-20 09:33 am (UTC)вы хотите функцию, (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:(no subject)
Date: 2010-08-20 06:45 am (UTC)"Динамически создать tuple, имя список типов" - во первых, не tuple а его тип, во вторых, это уже метапрограммирование или программирование на типах, кому что нравится.
В статически типизированных языках, действительно, часто не хватает таких возможностей и кажется, что они бы были серебряной пулей. Но это все до первой попытки реализовать их самостоятельно - в итоге оказывается, что получается что-то похоже или на Template Haskell с его адским вуду, или на Common Lisp с скобочками и макросами. Это если встраивать метапрограммирование в язык таким образом, чтобы его хоть как-то можно было использовать, не сломав мозг.
Альтернатива этому делу - кодогенерация, которая тоже не панацея. К широкому использованию непригодна, т.к. код кодогенератора при хоть сколько нибудь нетривиальной задаче превращается в жуткий ад.
Я сейчас как раз на F# пишу кодогенератор для model-driven design, накушался всего этого по полной программе :)
(no subject)
Date: 2010-08-20 07:17 am (UTC)и тип, и сам кортеж. у меня есть метаданные, например [int; string; DateTime], а теперь мне надо создать инстанс и вставить в таблицу, ну или другую коллекцию по моему усмотрению.
всё это уже делалось разными фреймворками много раз, но за отсутствием языковой поддержки всегда выходило коряво. а тут, казалось бы, наконец можно сделать хорошо, ан нет, получилось как всегда.
(no subject)
Date: 2010-08-20 07:20 am (UTC)> open System;;
> let tupleInstance = (1,"zhopej",DateTime.Now);;
val tupleInstance : int * string * DateTime =
(1, "zhopej", 20.08.2010 10:20:30)
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
Date: 2010-08-20 08:48 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
Date: 2010-08-20 06:51 am (UTC)(no subject)
Date: 2010-08-20 07:32 am (UTC)(no subject)
Date: 2010-08-20 07:39 am (UTC)А что еще нужно, все остальное из этого комбинируется.
(no subject)
From:(no subject)
Date: 2010-08-20 08:53 am (UTC)* спрашивать у юзера коннект к БД, таблицу, логиниться
* показать список полей
* показать первых 30 строк таблицы.
Юзер может ввести БД и таблицу, какие угодно (созданные после компиляции программы).
Ява, Бейсик, паскакаль, писон -- без проблем. Ф#?
(no subject)
Date: 2010-08-20 09:04 am (UTC)Статическая система типов F# в данном случае не поможет ничем и никак.
Хотя у меня есть идея реализовать именно для этого use case собственный фреймворк с инкрементальной типизацией и кодогенерацией-компиляцией в рунтайме. Пока отложено в долгий ящик, т.к. решение задачи требует сначала реализовать то же самое в более простом варианте, с предварительной кодогенерацией.
Ну и единственное место в продакшене где у меня динамическая и статическая типизации пересекаются - это когда из такого грида нужно отобразить написанный руками конкретно под данную таблицу редактор или выполнить какой-нибудь расчет, тоже исходя из данных таблицы. Приходится заниматься приведениями типов, обращениями по имени к полям, итд :)
(no subject)
From:(no subject)
From:(no subject)
From:И кой черт занес вас на эти галеры?
Date: 2010-08-20 10:24 am (UTC)Re: И кой черт занес вас на эти галеры?
Date: 2010-08-20 10:47 am (UTC)Re: И кой черт занес вас на эти галеры?
Date: 2010-08-20 10:48 am (UTC)Re: И кой черт занес вас на эти галеры?
From:(no subject)
Date: 2010-08-20 11:22 pm (UTC)это глубокая мысль, ничуть не уступающая другим глубоким мыслям типа "невозможно читать из потока после того, как он кончился", или "невозможно читать из массива по индексу, который out of bounds".
(no subject)
From:(no subject)
Date: 2010-08-20 10:29 am (UTC)(a, (b, ( c, ..... )))
В этом случае не проблема проитерировать по элементам тапла, если в языке есть нормальный полиморфизм (как у недо-ML у F# должно хватить мозгов, но надо проверять). Однако в шарповом синтесисе это выглядит достаточно убого.
(no subject)
Date: 2010-08-20 10:46 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
Date: 2010-08-20 11:19 pm (UTC)(no subject)
From:(no subject)
Date: 2010-08-21 04:42 am (UTC)(no subject)
Date: 2010-08-21 07:07 am (UTC)