¿Cuál es el razonamiento detrás de la denominación de .NETs Select (Map) y Aggregate (Reduce)?

17

En otros lenguajes de programación, he visto Map and Reduce, y esos son los pilares de la programación funcional. No pude encontrar ningún razonamiento o historial por qué LINQ tiene Aggregate(igual que Reduce) y Select(igual que Map).

Lo que pregunto es que me tomó un tiempo entender que es lo mismo y tengo curiosidad por saber cuál es el razonamiento.

Tx3
fuente
Yo, por otro lado, me encantaría saber el razonamiento detrás de la selección de nombres "Mapa" y la agregación "Reducir" para empezar.
Den

Respuestas:

32

Esto se reduce principalmente a la historia de LINQ.

Originalmente, LINQ tenía la intención de ser similar a SQL, y se usó (en gran medida, aunque no exclusivamente) para conectarse a bases de datos SQL. Esto lleva a que gran parte de su terminología se base en SQL.

Por lo tanto, "seleccionar" vinieron del SQL selectdeclaración, y "agregado" vinieron de las funciones agregadas de SQL (por ejemplo, count, sum, avg, min, max).

Para aquellos que cuestionan el grado en que LINQ se relacionó originalmente con SQL, me referiría (por ejemplo) a los artículos de Microsoft sobre Cω, que fue un lenguaje diseñado por Microsoft Research, y parece ser donde se trabajó la mayoría de los conceptos básicos de LINQ antes de agregarlos a C # y .NET.

Por ejemplo, considere un artículo de MSDN sobre Cω , que dice:

Operadores de consultas en Cω

Cω agrega dos clases amplias de operadores de consulta al lenguaje C #:
- Operadores basados ​​en XPath para consultar las variables miembro de un objeto por nombre o por tipo.
- Operadores basados ​​en SQL para realizar consultas sofisticadas que involucran proyección, agrupación y unión de datos de uno o más objetos.

Al menos hasta donde sé, los operadores basados ​​en XPath nunca se agregaron a C #, dejando solo los operadores que estaban documentados (antes de que existiera LINQ) como basados ​​directamente en SQL.

Ahora, es cierto que LINQ no es idéntico a los operadores de consulta basados ​​en SQL en Cω. En particular, LINQ sigue los objetos básicos de C # y la sintaxis de llamadas de función mucho más de cerca que Cω. Las consultas Cω siguieron la sintaxis SQL aún más de cerca, por lo que podría escribir algo como esto (nuevamente, extraído directamente del artículo vinculado anteriormente):

 rows = select c.ContactName, o.ShippedDate
      from c in DB.Customers
      inner join o in DB.Orders
      on c.CustomerID == o.CustomerID;

Y sí, el mismo artículo habla específicamente sobre el uso de consultas basadas en SQL para consultar datos provenientes de bases de datos SQL reales:

Para conectarse a una base de datos SQL en Cω, debe exponerse como un ensamblado administrado (es decir, un archivo de biblioteca .NET), al que luego hace referencia la aplicación. Una base de datos relacional puede exponerse a un Cω como un ensamblado administrado mediante el uso de la herramienta de línea de comandos sql2comega.exe o el cuadro de diálogo Agregar esquema de base de datos ... desde Visual Studio. Cω utiliza los objetos de la base de datos para representar la base de datos relacional alojada por el servidor. Un objeto de base de datos tiene una propiedad pública para cada tabla o vista, y un método para cada función con valores de tabla que se encuentra en la base de datos. Para consultar una base de datos relacional, se debe especificar una tabla, vista o función con valores de tabla como entrada para uno o más de los operadores basados ​​en SQL.

El siguiente programa y salida de muestra muestra algunas de las capacidades de usar los operadores basados ​​en SQL para consultar una base de datos relacional en Cω. La base de datos utilizada en este ejemplo es la base de datos Northwind de muestra que viene con Microsoft SQL Server. El DB nombre usado en el ejemplo se refiere a una instancia global de un objeto de base de datos en el Northwind espacio de nombres del Northwind.dll ensamblado generado usando sql2comega.exe .

Entonces, sí, desde el principio (o incluso antes del principio, dependiendo de su punto de vista) LINQ se basó explícitamente en SQL y tenía la intención específica de permitir el acceso a datos en bases de datos SQL.

Jerry Coffin
fuente
55
No estoy de acuerdo con que LINQ se haya inventado para consultas SQL. LINQ se basa en las operaciones de consulta en , que a su vez las heredó de X♯, que se basa en un antiguo documento de Haskell. Tenga en cuenta que uno de los autores de dichos documentos Haskell es Erik Meijer, quien también participó en el diseño de X♯ y Cω después de eso, y por supuesto es el diseñador de LINQ. Y estaba claro desde el principio que LINQ podría usarse para consultar todo tipo de cosas, no solo SQL (se envió con LINQ-to-SQL, LINQ-to-XML y LINQ-to-Objects desde el primer día, en breve seguido de ...
Jörg W Mittag
44
LINQ-to-Entities), y de hecho por mucho más que consultar (es básicamente una sintaxis general de Monad Comprehension ). Fue diseñado para familiarizarse con los programadores de SQL (y XQuery), pero ciertamente no se limita a eso. En una línea similar, las Comprensiones de Mónada de Scala parecen forbucles, y Haskell parece bloques de código imperativo de estilo C, por lo que Scala llama a su operación monádica flatMap, y Haskell lo llama returnpor la misma razón: para encajar con la "ilusión" impidió (ex) programadores imperativos.
Jörg W Mittag
2
@ JörgWMittag: ver la respuesta editada. Creo que la documentación de Microsoft respalda mis declaraciones.
Jerry Coffin
3
+1 para justificar realmente la respuesta en lugar de adivinanzas. No puede obtener una fuente mucho más autorizada que Microsoft.
milleniumbug
Gracias, bien señor! Este es exactamente el tipo de respuesta que esperaba recibir.
Tx3
8

Métodos LINQ en .Net

source.Where(x => condition)
      .Select(x => projection)

fueron nombrados para ser coherentes con la sintaxis de consulta LINQ en C # (y VB.NET)

from x in source
where condition
select projection

que fue diseñado para ser familiar para las personas que conocen SQL

SELECT projection
FROM source x
WHERE condition
svick
fuente
2

Para mí, Seleccionar y agregar tiene más sentido. A medida que la entidad se convierte en el método dominante para consultar y manipular datos en .Net, Linq está siendo utilizado cada vez más por desarrolladores que probablemente están acostumbrados a trabajar con datos a través de SQL. Entonces, usar palabras como "Seleccionar" tiene más sentido para esos desarrolladores, porque esas son las palabras clave a las que están acostumbrados.

Christine
fuente
44
"cada vez más por desarrolladores que probablemente están acostumbrados a trabajar con datos a través de SQL" Lo dudo. El tipo con el que trabajo que canta las alabanzas de Entity Framework no pudo darse cuenta de que tenía que hacer un solo INNER JOINdía cuando Entity Framework no era una opción. Probablemente todo lo contrario. Cada vez más personas usan LINQ todos los días que evitan activamente escribir SQL. Las personas que se sienten cómodas en SQL probablemente solo hagan más en SQL.
jpmc26
1
Eso no es lo que he visto. Principalmente, lo que estoy encontrando (a través de mi búsqueda de trabajo reciente) es que los desarrolladores que alguna vez trabajaron con datos usando Procedimientos almacenados están comenzando a hacer todos sus scripts en el controlador. Para mí, ayuda que Linq use expresiones familiares. No dudo que ese sea el caso del "chico con el que trabajas", pero esa no es mi experiencia.
Christine