C# 2.0 - ФЯП?

agaaaa

Никогда раньше не пользовался yield, даже не смотрел, что это такое. А вот сегодня пришлось по долгу службы. Насколько я понял из Вики, yield реализует в до-диезе ленивые вычисления. Тут же прочитал статью о ФП. Вот теперь возник вопрос, чего не хватает второму C# до ФЯП?
Идеальным ответом была бы конструкция, на нём не реализуемая средствами языка.

Dasar

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

agaaaa

class yield
{
static void Main(string[] args)
{
foreach (byte value in EnumerateByteValues
Console.WriteLine(value);
#if DEBUG
Console.ReadKey;
#endif
}

static IEnumerable<byte> EnumerateByteValues
{
byte initial = 0;
while (true)
{
yield return initial++;
}
}
}

Попробуй этот код.

Dasar

и где ленивость?
тогда уж в делегатах и то больше ленивости

agaaaa

Мб я не правильно понял, что такое ленивые вычисления.
И всё же:
Идеальным ответом была бы конструкция, на нём не реализуемая средствами языка.

Dasar

вообще-то ленивость можно хоть на asm-е реализовать.
основная фишка компилятора с поддержкой ленивости - это не просто поддержка ленивости, а агрессивная оптимизация этой самой ленивости.
компилятор C# ни про какую ленивость не знает, и никакой агрессивной оптимизации ленивости не проводит.

agaaaa

Ты в этом уверен?
В смысле, что значит "агрессивная оптимизация ленивости"?

timefim

Идеальным ответом была бы конструкция, на нём не реализуемая средствами языка.
Что значит не реализуемая средствами языка? Все можно написать и на ассемблере, другое дело сколько это займет времени и сил.

agaaaa

могу ответить на твой вопрос относительно конкретного примера
пример - реализация ооп в стандартном паскале

Helga87

напомни, в стандартном паскале указатели есть?

agaaaa

есть
я знаю, что можно реализовать, но это потребует слишком много кода

Helga87

разница между "много кода" и "невозможно" для теоретического спора все же есть. А на практике — да, стандартный Паскаль ни фига не ООП, да и С#-у еще далеко до ФЯП.

timefim

А я что написал?
Думаю из того что было бы полезно в 3.0, но чего нет это
Pattern Matching и Enumeration type
Почитай http://www.rsdn.ru/article/nemerle/NemerleIntro.xml
Нам вначале идет сравнение C# и Nemerle
А так, хочеш ФЯП, используй F#. (стих)

Papazyan

Ленивый язык - это язык, где все вычисления идут через вызовы by name (или почти все).
yield - это скорее сильно урезанные по функциональности Continuations.

agaaaa

Enumeration type
это что?

agaaaa

Ленивые вычисления (англ. lazy evaluation) — концепция в некоторых языках программирования, согласно которой вычисления следует откладывать до тех пор, пока не понадобится их результат.

(C) Вика
И почему это не ленивые вычисления?

timefim

это что?
Это апгрейженый enum
Классический пример, бинарное дерево
F#
type 'a Tree =
| Branch of 'a Tree * 'a Tree
| Leaf of 'a
Haskell
data Tree a = Leaf a | Branch (Tree a) (Tree a)

pitrik2

чего не хватает второму C# до ФЯП
имхо, бредовый вопрос
вот аналогия:
красим корову в зеленый цвет
чего не хватает новой корове до яблока?

slonishka

сковородки!

myrka68

а что такое F#?
конструкция уж больно на ML похожа

timefim

а что такое F#?
конструкция уж больно на ML похожа
Родственник, можно сказать NETовский OCaml.

agaaaa

Ну и где у коровы будет черенок?

myrka68

Родственник, можно сказать NETовский OCaml.
жуть!
чем же микрософту нормальные языки типа haskell и ocaml не нравятся, опять велосипед изобретают =)
хотя haskell вроде к микрософту ща имеет непосредственное отношение

timefim

ocaml не нравятся
Им то как раз нравится, поэтому они его и реализуют, с небольшими дополнениями учитывая специфику.

Marinavo_0507

Им то как раз нравится, поэтому они его и реализуют, с небольшими дополнениями учитывая специфику.
Не с дополнениями, а наоборот: в F# нет ML-ных модулей и ещё нескольких вкусностей меньшего масштаба.

timefim

Не с дополнениями, а наоборот: в F# нет ML-ных модулей и ещё нескольких вкусностей меньшего масштаба.
Думаю это вопрос времени.
А модули есть
module Stack = begin
type 'a stack = Stack of 'a list
let pop (Stack(a::b = Stack(b)
...
end

Или там что то хитрее?

apl13

Насколько я понял из Вики, yield реализует в до-диезе ленивые вычисления. Тут же прочитал статью о ФП. Вот теперь возник вопрос, чего не хватает второму C# до ФЯП?
Поправьте меня, если я ошибаюсь, но лень и функциональность, вроде, друг с другом никак не связаны?..

Ivan8209

Не ошибаешься.
---
"Аллах не ведёт людей неверных."

Marinavo_0507

функторов нет, а без них нах нужны такие модули, в .net есть же уже свои

timefim

А можно пример, чего в этих функторах хорошего?

bleyman

Скачай .нет рефлектор и посмотри на генерируемый йелдом код. Очень поучительно.
Никакой мистики там нет, просто вместо йелдов оказываются обычные ретурны, за которыми стоят метки, на которые в следующем вызове MoveNext делается джамп.

pitrik2

Никакой мистики там нет
ну я не думаю что если посмотреть генерируемый хаскелем ассемблер там будет мистика

Landstreicher

> ну я не думаю что если посмотреть генерируемый хаскелем ассемблер там будет мистика
Я читал несколько раз. Мистики нет. Но в то же время достаточно креативно. Если не знать теории как он компилится, то ничего не понять. Читал http://citeseer.ist.psu.edu/peytonjones92implementing.html ?

bleyman

Там будет нечто, не имеющее практически никакого отношения к исходному коду, и полученное в результате хардкорных математических трансформаций.
Я вообще что сказать-то хотел: что йелд нифига не является примером ленивых вычислений, это, как справедливо заметили уже, просто читерское запоминание позиции внутри кода. Поскольку рекурсию в енумераторе фиг запустишь, оно работает.
Видел когда-то недавно пример essentially ленивых вычислений, на хаскелле. Там был небольшой интерпретатор чего-то ассемблероподобного, с как бы однопроходным расставлением jump destinations (рядом валялся аналогичный код, проставлявший прямые и обратные ссылки в документе с цитатами). На вид всё было вполне процедурненько: идём по тексту, при виде "somelabel:" записываем имя метки и текущий адрес в словарег, при виде "goto somelabel" достаём из словарега адрес метки с таким именем и записываем его в результат. То, что на самом деле совы вовсе не то, чем они кажутся, а эта штука не имеет никакого отношения к последовательному выполнению команд, так что в результате прекрасно обрабатывает и ссылки вперёд (которых нет в словареге "на момент" появления соответствующего goto иначе как мистикой не назовёшь. То есть понятно, конечно, что она не святой молитвой это всё делает, но всё же.
Оставить комментарий
Имя или ник:
Комментарий: