Uniform Function Call Syntax in C#
От: vaa  
Дата: 11.01.22 09:38
Оценка:
Возможно ли такое в C#, если нет почему?
https://tour.dlang.org/tour/de/gems/uniform-function-call-syntax-ufcs

24.01.22 22:05: Перенесено из 'Философия программирования'
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Uniform Function Call Syntax in C#
От: Хэлкар  
Дата: 11.01.22 10:05
Оценка: +2
Самое близкое это extension methods https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods
Re: Uniform Function Call Syntax in C#
От: Mr.Delphist  
Дата: 11.01.22 12:57
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>Возможно ли такое в C#, если нет почему?

vaa>https://tour.dlang.org/tour/de/gems/uniform-function-call-syntax-ufcs

Собственно, весь LINQ такой и есть, а также всякие автомэпперы-миграторы-etc

https://en.wikipedia.org/wiki/Fluent_interface
Re[2]: Uniform Function Call Syntax in C#
От: vaa  
Дата: 12.01.22 02:54
Оценка:
Здравствуйте, Хэлкар, Вы писали:

Х>Самое близкое это extension methods https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods


не то, глобально это не решает проблему f1(f2(f3(f4(f5(1))))) вместо 1.f5.f4.f3.f2.f1
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Uniform Function Call Syntax in C#
От: vaa  
Дата: 12.01.22 02:57
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:



MD>Собственно, весь LINQ такой и есть, а также всякие автомэпперы-миграторы-etc


Да, но реализация возлагается на программиста, хотя это легко было добавить в ядро языка.
как только линк или экстенш для операции не реализован, так сразу либо временные переменные либо матрешка функций.
UFCS и для чтения прост и для уменьшения лишних LOC
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Uniform Function Call Syntax in C#
От: Хэлкар  
Дата: 12.01.22 04:23
Оценка: +1
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, Хэлкар, Вы писали:


Х>>Самое близкое это extension methods https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods


vaa>не то, глобально это не решает проблему f1(f2(f3(f4(f5(1))))) вместо 1.f5.f4.f3.f2.f1


Нет, не решает. А должно? Если вы зайдете в список предложенных фич для C#, то увидите, что их там тысячи. Понятно, что все они никогда не будут реализованны. Данная фича хороша, но для большинства не критична.
Re[3]: Uniform Function Call Syntax in C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 12.01.22 08:36
Оценка: :)
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, Mr.Delphist, Вы писали:




MD>>Собственно, весь LINQ такой и есть, а также всякие автомэпперы-миграторы-etc


vaa>Да, но реализация возлагается на программиста, хотя это легко было добавить в ядро языка.

vaa>как только линк или экстенш для операции не реализован, так сразу либо временные переменные либо матрешка функций.
vaa>UFCS и для чтения прост и для уменьшения лишних LOC

Не методы расширения интереснее, так как можешь добавлять методы не изменяя класс. Главное ты можешь использовать различные методы с одним названием используя пространства имен.
Часто приходится использовать условную компиляцию, так как в Xamarin есть методы объекта, а для фреймворка нужно делать методы расширения.
Ну и раз есть методы расширения конфликтующие с обычным методом то какой должен вызваться?

Но можно отрефакторить f1(f2(f3(f4(f5(1))))) в класс расширения и вызывай 1.f5.f4.f3.f2.f1
Просто это оооочень редкая задача
и солнце б утром не вставало, когда бы не было меня
Отредактировано 12.01.2022 11:11 Serginio1 . Предыдущая версия . Еще …
Отредактировано 12.01.2022 10:43 Serginio1 . Предыдущая версия .
Re: Uniform Function Call Syntax in C#
От: Aquilaware  
Дата: 21.01.22 21:31
Оценка: 9 (2)
Здравствуйте, vaa, Вы писали:

vaa>Возможно ли такое в C#, если нет почему?

vaa>https://tour.dlang.org/tour/de/gems/uniform-function-call-syntax-ufcs

Если наконец-то допилят pipe операторы, то будет возможно.

А пока что можно прикрутить костыль: https://dev.to/winstonpuckett/introducing-c-pipe-extensions-5d0j
Re[4]: Uniform Function Call Syntax in C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.01.22 20:31
Оценка:
Здравствуйте, Хэлкар, Вы писали:

Х>Нет, не решает. А должно? Если вы зайдете в список предложенных фич для C#, то увидите, что их там тысячи. Понятно, что все они никогда не будут реализованны. Данная фича хороша, но для большинства не критична.


Надо реализовать 1+2 фичи позволяющие людям создавать свои синтаксические расширения, а остальное возложить на пистелей библиотек.

MS тратит десятки лет, чтобы потом изобрести то, что существует уже почти 20 лет.

Немерлу этот оператор перекрутили сразу же как о нем узнали.
https://github.com/rsdn/nemerle/blob/db4bc9078f1b6238da32df1519c1957e74b6834a/testsuite/positive/pipe.n
    def x(p : int)
      WriteLine(p)

    def y(p : int)
      p + 1

    1 |> x
    x <| 2

    3 |> fun(p)
      WriteLine(p)

    (fun(p) { WriteLine(p) }) <| 4

    4 |> y |> x
    x <| (y <| 5)

/* 
BEGIN-OUTPUT
1
2
3
4
5
6
END-OUTPUT
*/


Собственно определяется он как оператор в стандартной библиотеке:
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "|>",    false, 227, 228)]
...
namespace Nemerle.Builtins
{
  ...
  public static @|> (a : 'p1, fac : 'p1 -> 'r) : 'r
  {
    fac(a)
  }
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Uniform Function Call Syntax in C#
От: Sinclair Россия https://github.com/evilguest/
Дата: 25.01.22 05:35
Оценка:
Здравствуйте, vaa, Вы писали:
vaa>не то, глобально это не решает проблему f1(f2(f3(f4(f5(1))))) вместо 1.f5.f4.f3.f2.f1
А такая проблема есть?
В тех местах, где она может проявиться, используют именно extension methods.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Uniform Function Call Syntax in C#
От: vaa  
Дата: 25.01.22 05:43
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, vaa, Вы писали:

vaa>>не то, глобально это не решает проблему f1(f2(f3(f4(f5(1))))) вместо 1.f5.f4.f3.f2.f1
S>А такая проблема есть?
Скобки это препятствие на пути к чистому коду.
S>В тех местах, где она может проявиться, используют именно extension methods.
не универсально и увеличивает количества бойлерплэйта в проекте. По моему какой-то костыль.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: Uniform Function Call Syntax in C#
От: Sinclair Россия https://github.com/evilguest/
Дата: 25.01.22 06:00
Оценка: +2
Здравствуйте, vaa, Вы писали:
vaa>не универсально и увеличивает количества бойлерплэйта в проекте. По моему какой-то костыль.
Не, ничего не увеличивается.
Было бы интересно посмотреть на реальный пример кода, который страдает от nesting problem, и который можно было бы как-то существенно улучшить вот этим вот костылём, но нельзя при помощи extension methods.
Пока что выглядит так, что у вас тяжёлое поражение ФП, при котором кажется, что большинство функций являются безаргументными.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Uniform Function Call Syntax in C#
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 25.01.22 19:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Пока что выглядит так, что у вас тяжёлое поражение ФП, при котором кажется, что большинство функций являются безаргументными.


Зачем безаргументными? В общем случае там
a.f1(b,c).f2(d).f3(x,y,z)

преобразуется в
f3(f2(f1(a,b,c), d), x,y,z)

Порой весьма удобно.
Re[7]: Uniform Function Call Syntax in C#
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.01.22 03:08
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Зачем безаргументными? В общем случае там

DM>
DM>a.f1(b,c).f2(d).f3(x,y,z)
DM>

DM>преобразуется в
DM>
DM>f3(f2(f1(a,b,c), d), x,y,z)
DM>

DM>Порой весьма удобно.
Это как раз совпадает с синтаксисом extension methods.
ТС хочет избавиться от скобок, вместо a.f1().f2().f3() писать a.f1.f2.f3. Как в Паскале.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 26.01.2022 4:10 Sinclair . Предыдущая версия .
Re[8]: Uniform Function Call Syntax in C#
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 26.01.22 10:19
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>ТС хочет избавиться от скобок, вместо a.f1().f2().f3() писать a.f1.f2.f3. Как в Паскале.


Так это уже не UFCS, это просто дишное правило, что функции без параметров можно вызывать без скобок, если так хочется.
Re[5]: Uniform Function Call Syntax in C#
От: Воронков Василий Россия  
Дата: 15.05.22 11:42
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>
VD>    4 |> y |> x
VD>    x <| (y <| 5)
VD>


Но ассоциативность, как я понимаю, задать нельзя?
Re[5]: Uniform Function Call Syntax in C#
От: Leporidae  
Дата: 15.05.22 15:25
Оценка: :)
vaa>не универсально и увеличивает количества бойлерплэйта в проекте.

Пишет vaa и тут же предлагает увеличивать количество бойлерплейт кода в КСВ
Автор: vaa
Дата: 04.05.22
Re[6]: Uniform Function Call Syntax in C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.05.22 02:56
Оценка: 88 (2)
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Но ассоциативность, как я понимаю, задать нельзя?


Там ниже был пример:
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "|>",    false, 227, 228)]


false — значит, что оператор не унарный (т.е. бинарный)
цифры дальше это сила связывания слева и справа.

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

Вот таблица силы связывания для всех операторов из стандартной макро-библиотеки:
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "!",     true, 281, 280)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "~",     true, 281, 280)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "++",    true, 283, 284)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "?",     true, 283, 284)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "--",    true, 283, 284)]

[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "in",    false, 120, 121)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "when",  false, 130, 131)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "with",  false, 130, 131)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "=",     false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "*=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "/=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "%=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "+=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "-=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "<<=",   false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", ">>=",   false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "&=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "^=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "|=",    false, 141, 140)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "=>",    false, 145, 120)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "??",    false, 146, 145)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "||",    false, 150, 151)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "&&",    false, 160, 161)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "==",    false, 165, 166)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "!=",    false, 165, 166)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "|",     false, 170, 171)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "%|",    false, 170, 171)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "^",     false, 180, 181)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "%^",    false, 180, 181)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "&",     false, 190, 191)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "%&",    false, 190, 191)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "%&&",   false, 190, 191)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "is",    false, 210, 211)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "<",     false, 210, 211)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", ">",     false, 210, 211)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "<=",    false, 210, 211)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", ">=",    false, 210, 211)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "as",    false, 215, 301)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "::",    false, 221, 220)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "<|",    false, 226, 225)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "|>",    false, 227, 228)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "<<",    false, 230, 231)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", ">>",    false, 230, 231)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "..",    false, 230, 231)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "+",     false, 240, 241)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "-",     false, 240, 241)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "->",    false, 251, 250)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "/",     false, 260, 261)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "%",     false, 260, 261)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "*",     false, 261, 260)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", ":",     false, 270, 246)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", ":>",    false, 270, 246)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "where", false, 284, 300)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "?.",    false, 285, 285)]
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", ".",     false, 285, 301)]
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.