Мне не хватает вывода типов из использованния члена класса т.е. чтоб работал вот такой абстрактный пример:

open System.Windows.Forms
let GetText x = x.Text
let f=new Form(Text="Test")
....
GetText f
В данном случае компилятору (теоритически) для вывода типа информации достаточно, однако не сработает - попросит явно тип указать.

By on 9/23/2011 5:22 AM ()

Мне не хватает более хорошой поддержки Linq2sql
и C-like case синтаксиса или чего-то похожего.

By on 3/4/2011 5:19 AM ()

и C-like case синтаксиса или чего-то похожего.

Это то на что сдалось?

By on 3/4/2011 7:40 PM ()

Это то на что сдалось?

1
2
3
4
5
6
7
let selecNworlds() = 
  switch N
  | N > 0 -> "oneword"
  | N > 1 -> "second word"
  ............
  | _ -> "lastword"
  :: toSomeList

Хотя да, такое уже есть в match, не нужно.
Но вот Linq2sql синтаксис как я понимаю пока работает лишь конвертирую seq , и ругается на ошибки только в процессе исполнения программы, точно хотелось бы чего-то большего )

By on 3/16/2011 4:04 AM ()

Лично мне больше всего не хватает лямбда экспрессий (что также позволит использовать ORM, реализующие Linq)

А цитирование разве их не заменяет? В PowerPack есть реализация Linq.

By on 12/21/2010 3:33 AM ()

Цитирование не позволяет описывать функции. Им можно описывать только полные выражения (let f x = x + 10).

А реализация в PowerPack - это описание sql запроса итеративными методами (через for), т.е. полная противоположность функциональному linq в итеративном c#. Все с ног на голову.

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

By on 12/21/2010 2:06 PM ()

Нам не хватает match! в workflow.

Скажем чтобы в асиках можно было писать вместо

1
2
3
4
...
let! res = execSomeAsync 
match res with
| ....

Такое:

1
2
match! execSomeAsync with
| ....
By on 12/20/2010 1:23 AM ()

Лично мне больше всего не хватает лямбда экспрессий

А что это такое? И можно пример, как это по идее должно выглядеть?

By on 12/20/2010 1:21 AM ()

А что это такое? И можно пример, как это по идее должно выглядеть?

Я имею в виду выражения, которые в runtime можно разложить на составляющие (expression tree).
Хорошо бы, если бы выглядело аналогично linq из c#.

1
2
3
stockProvider.Query
|> Linq.OrderBy (fun x -> x.Price)
|> Linq.Select (fun x -> { x.Name, x.Price } )

К тому же на PDC обещали Linq to everything, жаль, если F# останется за бортом.

By on 12/21/2010 2:29 PM ()

Я имею в виду выражения, которые в runtime можно разложить на составляющие (expression tree).
Хорошо бы, если бы выглядело аналогично linq из c#.

К тому же на PDC обещали Linq to everything, жаль, если F# останется за бортом.

Я не сильно юзал Linq. Но думаю что за бортом никто не останется.

Вот посмотри следующие ссылки:

[link:cs.hubfs.net]
[link:www.atrevido.net]
[link:strangelights.com]

Очень похоже на то что ты хочешь.

Ну и [<ReflectedDefinition>], как уже сказали, тоже вроде из этой же оперы.

By on 12/21/2010 11:44 PM ()

По этим ссылкам одни костыли. Приведу примеры.

1) Узнаем есть ли клиенты с адресом длиннее 10 символов.

1
2
3
4
c#:

db.Customers.Any(_ => _.Address.Length > 10);
1
2
3
4
5
6
7
8
F#:

query {(@ Seq.exists

           (fun (c:Customers) -> c.Address.Length > 10) 

           (seq { for c in db.Customers do yield c }) @)}

2) Считаем количество единиц товара с подгрузкой категории и поставщика.

1
2
3
4
5
6
7
8
9
10
11
C#:

db.Products.

           .Include("Category")

           .Include("Suplier")

           .Select(_ => new {_.Category.CategoryName, _.ProductName, _.Suplier.CompanyName })

           .Count();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
F#:

// Using Nullable via reflected definitions

[{(ReflectedDefinition)}]

let (=?!) (x : System.Nullable<'a>) (y: 'a) = 

    x.HasValue && x.Value = y

query {(@ seq { for p in db.Products do

                 for c in db.Categories do

                  for s in db.Suppliers  do

                    if p.CategoryID =?! c.CategoryID &&

                       p.SupplierID =?! s.SupplierID then 

                      yield c.CategoryName, p.ProductName, s.CompanyName } 

         |> Seq.length @})

C# лаконичен и читается гораздо лучше.

Сейчас использовать Linq в F# невозможно. Как минимум это крайне не эффективно.

By on 12/23/2010 8:10 AM ()
1
2
3
4
5
6
7
8
F#:

query {(@ Seq.exists

           (fun (c:Customers) -> c.Address.Length > 10) 

           (seq { for c in db.Customers do yield c }) @)}

а почему не пользоваться тем же что и в С#?

1
2
3
4
F#:

db.Customers.Any(fun (c:Customers) -> c.Address.Length > 10)
By on 12/24/2010 5:17 AM ()

а почему не пользоваться тем же что и в С#?

Потому что это выражение не будет распознано как экспрессия, а будет применена как обычная функция. Это значит, что не будет построен нужный sql запрос с выборкой, а будут подгружены все записи и уже к ним будет применена данная функция.

Во-вторых, как было объявлено на PDC, linq провайдеры будут строятся не как имплиментация интерфейсов из BCL, а как набор обычных методов, возвращающих IQueryable.

Т.е. уже не будет привязки к стандартным методам типа Enumerable.Where(Expression ...). А это значит, что все костыли, типа Seq.exist нельзя будет применять в Linq to everything.

Нужно сразу делать как положено. С заменой функций на соответствующие экспрессии там, где это нужно (автоматически при интерпретации в CIL и никак иначе).

Если этого не сделать область применения F# никогда не выйдет за рамки математических вычислений.

By on 12/25/2010 1:10 AM ()

[link:cultivatingcode.com]

после этого можно писать уже чтото вроде

db.Customers.Any(expr <@ fun (c : Customers) -> c.Address.Length > 10 @>)

By on 12/25/2010 11:31 AM ()

Из мелочей, которые вполне могли бы быть в языке и стандартной библиотеке, но по каким-то причинам отсутствуют:

1.) Абстрактные индексированные свойства.

Да, можно писать явно set_Foo / get_Foo, но выглядит это как фарш, и явно связано с некоторой "черной магией", поскольку определение вида

1
abstract Foo : int -> int with get, set

формально не отличается от свойства со значением типа int -> int.

2.) DelegateEvent со строгой типизацией.

То, что есть сейчас, оборачивает параметры в obj[] и использует DynamicInvoke.
Что явно не в духе языка с упором на статическую типизацию и к тому же работает медленнее, чем могло бы.
В принципе, можно сделать свои "правильные event-ы", согласованные с .NET-овской моделью, но этому явно место в стандартной библиотеке, а не в новоизобретённых пользовательских велосипедах.

By on 1/17/2011 11:48 AM ()

[<ReflectedDefinition>] спасет отца русской демократии

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[<ReflectedDefinition>]
let f x = x + 1

open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

let (Lambda (_, Call(_, m, _))) = <@ f @>

let expr = Expr.TryGetReflectedDefinition(m)
printfn "%A" expr

(*
Some
  Lambda (x,
        Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
              [x, Value (1)]))
*)
By on 12/21/2010 3:10 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper