Сколько стоит 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.