Информация об изменениях

Сообщение Re[34]: «Собаку съел» от 12.01.2017 11:57

Изменено 12.01.2017 12:00 vdimas

Re[34]: «Собаку съел»
Здравствуйте, Serginio1, Вы писали:

V>>Это всё к тому, что твой пример с copy&paste вот этого:

V>>
V>>where(x => x > q)
V>>

V>>в общем случае является плохой практикой.
V>>Но язык позволяет только такую.
S> Чем это плохо?

Тем, вестимо, что в каждом конкретном месте можно допустить ошибку.
По сей причине и рождается "матрица специализаций", типа этой.
По ссылке автогенерённый код. В этом смысле С++ позволяет выполнять такую кодогенерацию прямо в исходниках.


S>В С++ зря штоли ввели Лямбды?


Моя рука потихоньку тянется к лицу. ))

Давай сделаем паузу и посмотрим на это всё повнимательней. Лямбды хороши исключительно и только для уникальных случаев, в этом и состоит их ЦЕЛЕВАЯ фишка — они же захватывают текущий контекст! Т.е., твоё x => x > q — это ж вовсе не лямбда (вот почему рука дрогнула в направлении лица), это ж у тебя просто некая "маленькая процедура", которая использует возможность локального объявления процедур (лямбд), не используя при этом их основной механизм. Вполне же можно было объявить такой предикат вне контекста использования, верно? Т.е., получилась лишь некая экономия сугубо на "оформлении" такого предиката в виде отдельной ф-ии.

Т.е., речь о том, что неуникальный случай в C# описать не так-то просто (тем паче с должной эффективностью).


S>Нет язык позволяет использовать

S>
S>public static IEnumerable<TSource> Where<TSource>(
S>    this IEnumerable<TSource> source,
S>    Func<TSource, bool> predicate
S>)
S>

S>То есть я могу использовать любой дженерик делегат .

Не можешь. В теле дотнетной лямбды происходит автовывод типов, поэтому ты вызываешь методы конкретных типов. Для реализации предиката в виде генерика исходные типы должны поддерживать некие данные ЗАРАНЕЕ ограничения на шаблонах или использовать т.н. "объекты-словари операций", навроде IComparer<T>, который в свою очередь может оперировать лишь типами, над которыми ПРЕДВАРИТЕЛЬНО заданы некие ограничения в виде опять и снова интерфейсов.


S>Просто лямбды удобнее как для написания так и для чтения, а так же для оптимизации компиляции


Конечно удобны. Но я на это тоже уже отвечал заранее:

Понятно, что x => x.Y выглядит тривиально, это был лишь пример. В общем случае "оно" может быть не тривиальным, т.к. именно под нетривиальные объемы кода пишут те самые шаблоны "многоразового применения" — в этом их фишка.

С++ позволяет комбинировать технику шаблонов и лямбд, используя каждую из техник по прямому назначению, т.е. заставляя их выполнять исключительно "свою" часть работы.
Re[34]: «Собаку съел»
Здравствуйте, Serginio1, Вы писали:

V>>Это всё к тому, что твой пример с copy&paste вот этого:

V>>
V>>where(x => x > q)
V>>

V>>в общем случае является плохой практикой.
V>>Но язык позволяет только такую.
S> Чем это плохо?

Тем, вестимо, что в каждом конкретном месте можно допустить ошибку.
По сей причине и рождается "матрица специализаций", типа этой.
По ссылке автогенерённый код. В этом смысле С++ позволяет выполнять такую кодогенерацию прямо в исходниках.


S>В С++ зря штоли ввели Лямбды?


Моя рука потихоньку тянется к лицу. ))

Давай сделаем паузу и посмотрим на это всё повнимательней. Лямбды хороши исключительно и только для уникальных случаев, в этом и состоит их ЦЕЛЕВАЯ фишка — они же захватывают текущий контекст! Т.е., твоё x => x > q — это ж вовсе не лямбда (вот почему рука дрогнула в направлении лица), это ж у тебя просто некая "маленькая процедура", которая использует возможность локального объявления процедур (лямбд), не используя при этом их основной механизм. Вполне же можно было объявить такой предикат вне контекста использования, верно? Т.е., получилась лишь некая экономия сугубо на "оформлении" такого предиката в виде отдельной ф-ии.

Т.е., речь о том, что неуникальный случай в C# описать не так-то просто (тем паче с должной эффективностью).


S>Нет язык позволяет использовать

S>
S>public static IEnumerable<TSource> Where<TSource>(
S>    this IEnumerable<TSource> source,
S>    Func<TSource, bool> predicate
S>)
S>

S>То есть я могу использовать любой дженерик делегат .

Не можешь. В теле дотнетной лямбды происходит автовывод типов, поэтому ты вызываешь методы конкретных типов. А для реализации предиката в виде генерика исходные типы должны поддерживать некие данные ЗАРАНЕЕ ограничения на шаблонах или использовать т.н. "объекты-словари операций", навроде IComparer<T>, который в свою очередь может оперировать лишь типами, над которыми ПРЕДВАРИТЕЛЬНО заданы некие ограничения в виде опять и снова интерфейсов.


S>Просто лямбды удобнее как для написания так и для чтения, а так же для оптимизации компиляции


Конечно удобны. Но я на это тоже уже отвечал заранее:

Понятно, что x => x.Y выглядит тривиально, это был лишь пример. В общем случае "оно" может быть не тривиальным, т.к. именно под нетривиальные объемы кода пишут те самые шаблоны "многоразового применения" — в этом их фишка.

С++ позволяет комбинировать технику шаблонов и лямбд, используя каждую из техник по прямому назначению, т.е. заставляя их выполнять исключительно "свою" часть работы.