VD>Такой подход к тому же еще и полезен так как дает возможность контролировать что можно, а что нельзя использвоать как метод расширения.
Да, прикольно. (Подозреваю, должно быть TreatAsExtentionMethod?)
Но всё-таки мне непонятно, почему чтобы составить выражение из уже существующих символов, программист должен сказать одному из символов: "Улыбнитесь, вас снимает ... вернее, вам лепят extension method. Автоматически!"
Да, и как там насчёт разруливания конфликтов имён? Просто возникает подозрение, что раскладываются грабли на пустом месте.
Здравствуйте, VladD2, Вы писали:
LCR>>Если же сделать, чтобы эти операции генерировались автоматом, то возникает опасность возникновения коллизий (когда у A() уже есть метод B(), но надо сделать конвейер с какой-то другой функцией B()).
VD>Если у текого объекта уже есть нужный метод то они и вызовется не вызвав никаких проблем. И вообще, челоек будет понимать что приосходит в отличии от этих конвейров котоые поймут только несколько эстетов прочитавших введение в Хаскель до этого.
А на самом деле еще не ясно, где понимания больше будет. Когда метод-расширения называется IsNullOrEmpty, я еще интуитивно пойму почему он не кидает NullReference для такого кода:
def s : string = null;
when (s.IsNullOrEmpty())
...
Но если он будет называться, например, ProcessString...
В общем, еще не ясно, что разработчикам будет проще понять и принять: еще одну фишечку функционального стиля или каверканье объектно-ориентированного.
В целом, я не против идеи extension методов, но все больше складывается ощущение, что Хейлсберг побоялся вводить конвейер, но что-то похожее хотелось, вот extension'ы и появились.
Здравствуйте, ie, Вы писали:
ie>А мне никогда не хотелось. Какого спрашивается этот метод вместо NullReferenceException вернет true?! Ладно у него хоть название говорящее...
Ну я же пишу
Здравствуйте, Блудов Павел, Вы писали:
БП>В случае с конвеером можно записать в виде БП>
sb.Append ("T:") |> appendTypeName(_, m :> TypeInfo);
БП>что гораздо читабельней.
БП>С другой стороны, БП>
БП>def foo = sb.Append ("T:");
БП>appendTypeName(foo, m :> TypeInfo);
БП>
БП>Ничем не хуже. Только нужно немного напрягать мозги — придумывать имена для ...дцати переменных.
Ну да, тут минус есть — приходится придумывать специальные названия для почти разбитого яйца, разбитого яйца, содержимого яйца в свободном полете и содержимого яйца упавшего на сковороду.
Тут проблема даже не в том, что нужно придумать столько названий для промежуточных этапов — есть где фантазии разуляться, а в том, что для того, кто будет потом их читать — такие названия могут показаться совсем не такими очевидными, какими они казались автору.
... << RSDN@Home 1.2.0 alpha rev. 655>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Да, и как там насчёт разруливания конфликтов имён? Просто возникает подозрение, что раскладываются грабли на пустом месте.
Тут много разных ваниаций можно подумать. Например, возоможно переименование.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, ie, Вы писали:
ie>А на самом деле еще не ясно, где понимания больше будет. Когда метод-расширения называется IsNullOrEmpty, я еще интуитивно пойму почему он не кидает NullReference ie>Но если он будет называться, например, ProcessString...
Если метод не поддерживает null, то исключение ты и так получишь, а если поддерживает, то и так будет все понятно. В общем, тут и сранвинвать нечего. Ты попробуй дать оба варианта прочесть C#-программисту и погляди на реакцию.
ie>В общем, еще не ясно, что разработчикам будет проще понять и принять: еще одну фишечку функционального стиля или каверканье объектно-ориентированного.
Методы расширения уже есть и ты единственный кто против них выступил (ну, не считая мало вменяемх товаришей). По сотальным поводам я уже все сказал. Подобные "улучшения" будут сильно поднимать порог вхождения и при некой критической массе они просто убьют язык превратив его в еще один Хаскель или Лисп (языки достойные, но мало кому нужные).
ie>В целом, я не против идеи extension методов, но все больше складывается ощущение, что Хейлсберг побоялся вводить конвейер, но что-то похожее хотелось, вот extension'ы и появились.
Они появились из совершенно других соображений. Из соображений внешнего расширения типов.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ie>>А на самом деле еще не ясно, где понимания больше будет. Когда метод-расширения называется IsNullOrEmpty, я еще интуитивно пойму почему он не кидает NullReference ie>>Но если он будет называться, например, ProcessString...
VD>Если метод не поддерживает null, то исключение ты и так получишь, а если поддерживает, то и так будет все понятно. В общем, тут и сранвинвать нечего. Ты попробуй дать оба варианта прочесть C#-программисту и погляди на реакцию.
def ProcessString(this st : string) : void
{
....
def l = st.Length; // исключение будет брошено тут, а не в (***)
...
}
def s : string = null;
s.ProcessString(); // (***)
s |> ProcessString; // тут сразу ясно, что s - параметр ProcessString, а не тип определяющий ProcessString
Эксперементируемый — коллега-разработчик, далеко не глупый, с глубокими познаниями в C# (в т.ч. в курсе нововведений таких как методы-расширения) и ООП, немного знакомый с Немерлом по моим рассказам:
кусок кода №1.
(мой вопрос: вот 2 записи, что можешь про них сказать)
— ээээ.... ну судя по всему они обе эквивалентны WriteLine(sq(sum(3.2, 4.3))) —
(я: первый вариант — это методы-расширения, второй — это конвейер, какой вариант больше нравится)
— первый привычней, а так — пофигу... а на хрена у WriteLine операнд явно указан, а у sq нет —
(иначе не компилится, особенности системы вывода типов, возможно, поправят в будущем)
— а как использовать, если у sq 2 параметра, второй пусть будет степень —
(я: sum(3.2, 4.3).sq(2).WriteLine() & sum(3.2, 4.3) |> sq(_, 2) |> WriteLine(_))
— ясно... а если результат надо заюзать как второй параметр, ну типа результат суммы будет степенью или если надо вывод форматированный сделать? —
(я: в первом варианте никак, во втором sum(3.2, 4.3) |> sq(2, _) |> WriteLine("result: {0}.", _))
— круто —
(я: но проще форматированный вывод делать через сплайсы)
— че таке? —
....(дальше идет разговор не по теме)...
кусок кода №2.
(я: что тут скажешь?)
— ну тут сразу ясно, что ProcessString метод-расширения и всего делов —
(я: а если тип не string будет)
— да все равно пофигу, ну упадет исключение, я все-равно сразу пойду смотреть строчку, где исключение брошено... в дебаге можно сходу не сообразить, а так — пофиг.
ie>>В общем, еще не ясно, что разработчикам будет проще понять и принять: еще одну фишечку функционального стиля или каверканье объектно-ориентированного.
VD>Методы расширения уже есть и ты единственный кто против них выступил (ну, не считая мало вменяемх товаришей).
Я не против них выступаю. Просто решение с конвейером мне кажется более элегантным.
Ладно, хватит ломать копья ..
ie>def ProcessString(this st : string) : void
ie>{
ie> ....
ie> def l = st.Length; // исключение будет брошено тут, а не в (***)
ie> ...
ie>}
ie>def s : string = null;
ie>s.ProcessString(); // (***)
ie>s |> ProcessString; // тут сразу ясно, что s - параметр ProcessString, а не тип определяющий ProcessString
ie>
По этим кускам кода — второй вариант выглядит явно приятнее