Musím se tu přiznat, že neznám C# a nevím, co přesně znamená že "některé implementace nedokáží např. přeložit skládání funkcí", takže možná nemluvím úplně k věci...
Parametr
Selectu má typ
Expression<Func<TSource, TResult>>, což není typ funkce
TSource -> TResult, ale typ jejího AST. Když se pak dělá dotaz do databáze, tak se vezme tento AST a přeloží se do SQL, když se dělá dotaz jinam, tak se to přeloží do příslušného dotazovacího jazyka. Pokud se překlad nepodaří (třeba
Compose), je vyhozena výjimka.
U kolekcí se překlad podaří vždy, protože tam se ten AST jen kompiluje do IL kódu. Nicméně u některých dotazovacích jazyků to nemusí jít.
Osobne to vidim podobne jako ava. Vubec by me nenapadlo, ze nekdy muze nastat situace, ze x.Select(Compose(g, f)) nevrati stejny vysledek jako x.Select(f).Select(g) . IMO takova implementace je dost nesikovna a zaslouzila by prepsani nebo odebrani.
Když se to podaří přeložit, tak se ty výsledky mohou lišit pořadím - např. se oboje přeloží na trochu jiný dotaz a služba, co vrací výsledky, to vrátí v jiném pořadí (tohle by mohlo nastat i u někerých kolekcí - např. u hašovacích tabulek, když to vracíte v pořadí, v němž to je uloženo v té tabulce).