Сколько стоит LINQ?

Я ищу LINQ, и язык запросов появляется (по крайней мере, на поверхности), чтобы быть не чем иным, как реализацией карт и/или списков, найденных в Haskell и других языках FP (в частности, обобщение "карты" 'и' for 'в Scala). Это верно? Есть ли больше синтаксиса, чем это? Из задыхающегося тома книги, которую я читаю ( "Essential LINQ" ), похоже, здесь есть что-то новое или инновационное.

Для реализации LINQ все внутренние, конвейерные, конвейерные деревья и типы выражений первого порядка и т.д., но мой вопрос касается самого языка запросов.

Приветствия

Джо

Ответ 1

Функционально говоря, LINQ - не что иное, как синтаксическое упрощение выражения монад. Linq to Objects (List-comprehensions - даже это уже было бы очень полезно), о котором вы говорили, это просто одно возможное приложение (похожее на List-Monad в Haskell).

Если вы пишете

from x in expr1
from y in expr2
select x + y

это ничего, кроме

do
    x <- expr1
    y <- expr2
    return $ x + y

в Haskell.

Конкретная вещь, которая выполняется, зависит от пользовательских Linq-провайдеров (Extension-Methods), из которых Linq.Enumerable - это всего лишь одна реализация с участием IEnumerable s.

Предоставляя один, вы можете создать совершенно новую LINQ-семантику для ваших типов.

Пример. Для типа Option для вычислений, которые могут быть сбой (значения с нулевым значением), можно было бы определить поставщика Linq для запроса по ним.

public static class MaybeExtensions
{
public static Option<T> ToMaybe<T>(this T value)
{
    return Option<T>.Some(value);
}

public static Option<U> SelectMany<T, U>(
    this Option<T> m, 
    Func<T, Option<U>> k)
{
    return !m.IsNone ? Option<U>.None : k(m.Value);
}

public static Option<V> SelectMany<T, U, V>(
    this Option<T> m, 
    Func<T, Option<U>> k, 
    Func<T, U, V> s)
{
    return m.SelectMany(x => k(x).SelectMany(y => s(x, y).ToMaybe()));
}
} 

Теперь это позволит нам написать такой код:

var sum = from x in ReadNumber("x")
          from y in ReadNumber("y")
          select x + y; 

Вычисление вернет значение только в том случае, если все вычисления будут выполнены успешно и в противном случае завершится сбой при первом сбое.

В сочетании с деревьями выражений Linq может быть чрезвычайно мощным и позволяет вам выражать -

  • Доступ к базе данных
  • Асинхронный программный поток
  • Может-монады
  • Список понятий
  • Анализаторы рекурсивного спуска
  • Продолжения
  • Мини-языки
  • Параллельные вычисления (PLinq)

Некоторые ссылки:

В сочетании с комбинаторами с фиксированной запятой Linq предоставляет полный функциональный мини-язык (Linq raytracer).

Обратите внимание, что Scala и F # имеют аналогичные понятия в выражениях-выражениях и вычислениях, которые являются монадическими абстракциями:

Scala:

for (x <- expr1
     y <- expr2) yield x + y

F #:

monad {
    let! x = expr1
    let! y = expr2
    return x + y
}

Ответ 2

Загадка, вероятно, предназначена для всего этого "очевидного" материала, некоторые из которых (например, деревья выражений) действительно превосходны. Язык - это просто средство доступа; вы возбуждаетесь по ключевому слову throw или по функциональности, которую он предоставляет?

Ответ 3

Помимо чтения книги об этом, вы уже использовали LINQ? Я обнаружил, что это огромная временная пауза в моей ежедневной работе по программированию. Для меня это следующий шаг абстракции, который можно использовать для объединения разных источников данных, таких как XML или SQL, и работы с ними на одном и том же языке.

Кроме того, я рекомендую этот интервью с Андерсом Хейлсбергом о функциональном программировании и LINQ.

Ответ 4

Ядро LINQ, синтаксиса запроса, на самом деле не имеет большого объема. Это просто несколько очень буквальных переводов, методов и лямбда - так

var qry = from x in src
          where x.Foo == "foo"
          select x.Bar;

буквально:

var qry = src.Where(x => x.Foo == "foo").Select(x => x.Bar);

Он ничего не знает о методах расширения (хотя они являются наиболее распространенной (но не только) реализацией), и ничего о Expression и т.д. Количество ключевых слов (и, следовательно, количество требуемых реализаций метода) не огромно, Jon, когда-то пытались реализовать их все за 1 час (в живой презентации). Он не делал слишком плохо; -p


Возможно, более впечатляющей частью LINQ является поддержка дерева выражений, которая должна была использоваться для LINQ для использования с базами данных - то есть выражение лямбда, которое может быть скомпилировано либо делегату, либо объекту модель, представляющая написанный код. Интересно, что эта же идея сияет в том, как DLR-разрешение работает в 4.0.

Ответ 5

LINQ был вдохновлен HaskellDB, поскольку Эрик Мейер неоднократно заявлял, например. в Исповедь используемого коммивояжера по программированию (получение массивов, подключенных к Haskell), поэтому сама по себе не является новой концепцией. Использование одного и того же языка для запросов по различным источникам в какой-то мере новаторски, хотя тот факт, что вложенная реляционная модель охватывает XML, объекты и реляционные базы данных, была показана исследователями ранее. Для меня очень круто то, что он был встроен в популярный, универсальный и, прежде всего, объектно-ориентированный язык, чего раньше не было.

Scala У ИМХО есть возможности включить что-то подобное. До сих пор для Scala мы имеем Stefan Zeiger ScalaQuery и Daniel Spiewak ScalaQL, которые следуют за шагами LINQ.