Методы-расширения и UFCS
От: x-code  
Дата: 08.02.21 08:16
Оценка:
Что вы об этом думаете?
Есть подход в C#, когда в функции (обычно статический метод другого класса) явно добавляют к параметру модификатор this, и после этого эту функцию можно вызывать как метод того объекта, для которого добавили this.
Есть предложение C++ n4474, в котором Саттер и Страуструп объединили свои размышления и пришли к выводу, что хорошо бы разрешать вызывать x.f(y) вместо f(x,y) и наоборот безо всяких модификаторов this. В документе рассмотрены преимущества такого подхода (шаблоны, концепты, интеллисенс).
Вроде бы нечто подобное сделано в D.
А вот если проектировать язык программирования с нуля, то какой подход предпочтительнее?
Какие преимущества и недостатки у явно определенных методов-расширений и унифицированного синтаксиса вызова функций вы видите?
Отредактировано 08.02.2021 8:18 x-code . Предыдущая версия .
Re: Extensions in Kotlin
От: Qbit86 Кипр
Дата: 08.02.21 08:30
Оценка:
Здравствуйте, x-code, Вы писали:

XC>А вот если проектировать язык программирования с нуля, то какой подход предпочтительнее?


В Kotlin тоже отдельный синтаксис: https://kotlinlang.org/docs/reference/extensions.html
fun MutableList<Int>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // 'this' corresponds to the list
    this[index1] = this[index2]
    this[index2] = tmp
}
Глаза у меня добрые, но рубашка — смирительная!
Re: Методы-расширения и UFCS
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.02.21 08:44
Оценка:
Здравствуйте, x-code, Вы писали:
XC>Какие преимущества и недостатки у явно определенных методов-расширений и унифицированного синтаксиса вызова функций вы видите?
Я вообще вижу много вариантов синтаксиса вызова. Например, что вместо f(a, b, c) можно писать a.f(b) c или f(a, b) c.
Это мега удобно для фич типа
public void using(IDisposable e, Action a)
{
  try
  {
    a;
  }
  finally
  {
    if(e!=null)
      e.Dispose();
  }
}

Вообще, надо смотреть на реальные примеры использования.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Методы-расширения и UFCS
От: Ночной Смотрящий Россия  
Дата: 08.02.21 09:13
Оценка: 3 (1) +1
Здравствуйте, x-code, Вы писали:

XC>А вот если проектировать язык программирования с нуля, то какой подход предпочтительнее?


Подход шарпа. Потому что иначе в интеллисенсе при нажатии точки будет сраная куча стаффа, который не нужно звать через точку. Даже в шарпе регулярно натыкаюсь на такую проблему, когда люди использованием this увлекаются. Особенно эротично смотрится this к параметру типа object.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Методы-расширения и UFCS
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 08.02.21 19:33
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Какие преимущества и недостатки у явно определенных методов-расширений и унифицированного синтаксиса вызова функций вы видите?


Если я все правильно путаю, у расширений проблема в том, что они привязаны к одному типу. Если я хочу сделать довольно универсальную функцию, которую можно было бы применять к разным типам, придется делать много расширений, и потом к новым типам ее явно добавлять.
С UFCS в D я могу один раз написать генерик функцию, которая даже не знает заранее всех типов, с которыми она будет работать, и потом применять ее спокойно. Вот, например, функция, которая работает с любыми структурами и суммирует все интовые поля в них, рекурсивно.

import std.stdio, std.traits;

struct A { bool b; int x; string name; int y; }
struct B { int re, im; char c; }
struct C { int x; A ma; B mb; }

void main() {
    auto a = A(true, 1, "Bob", 2);
    auto b = B(3, 4, 'x');
    auto c = C(5, a, b);
    writeln(a.nah + b.nah + c.nah); // outputs 25
}

int nah(T)(T o) {
    int sum = 0;
    foreach(name; FieldNameTuple!T) {
        alias F = typeof(__traits(getMember, o, name));
        static if (is(F == int))
            sum += __traits(getMember, o, name);
        static if (is(F == struct))
            sum += nah(__traits(getMember, o, name));
    }
    return sum;
}
Re[2]: Методы-расширения и UFCS
От: Ночной Смотрящий Россия  
Дата: 08.02.21 20:38
Оценка: 8 (1) +1
Здравствуйте, D. Mon, Вы писали:

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


Ты сейчас про что? Про шарповский вариант? Таки нет, такое тоже работает:
static void Foo<T>(this T source) ...

static void Bar<T>(this IBarArg<T> source) ...
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Методы-расширения и UFCS
От: AlexRK  
Дата: 08.02.21 20:39
Оценка: +1
Здравствуйте, x-code, Вы писали:

XC>А вот если проектировать язык программирования с нуля, то какой подход предпочтительнее?


Невозможно грамотно ответить на этот вопрос в отрыве от всего остального. Это зависит от системы типов языка, выразительности и набора его синтаксических конструкций, семантики, идеологии. Этот вопрос идет уже после всего этого.

XC>Какие преимущества и недостатки у явно определенных методов-расширений и унифицированного синтаксиса вызова функций вы видите?


Методы-расширения: преимущество — невозможно случайно сделать функцию расширением; недостаток — лишний синтаксический и семантический мусор в языке.
Универсальный вызов: преимущество — можно использовать в качестве метода функцию, которая не проектировалась как таковая; недостаток — можно использовать в качестве метода функцию, которая не проектировалась как таковая.
Re: Методы-расширения и UFCS
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.02.21 01:36
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Какие преимущества и недостатки у явно определенных методов-расширений и унифицированного синтаксиса вызова функций вы видите?


В принципе идея интересная.

Но может быть много неоднозначностей и проблемы с именами. Например:
var x = @"C:\temp";
var y = 1;
var z = x.Crete(y);

Вот это будет File.Create() или Tuple.Create()? Ну, предположим, сейчас открыта только System и это Tuple. А завтра мы открываем еще и System.IO и нарываемся неоднозначности. Как их разрешать? Не превратится ли это в геморрой?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Методы-расширения и UFCS
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.02.21 01:40
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Подход шарпа. Потому что иначе в интеллисенсе при нажатии точки будет сраная куча стаффа, который не нужно звать через точку. Даже в шарпе регулярно натыкаюсь на такую проблему, когда люди использованием this увлекаются. Особенно эротично смотрится this к параметру типа object.


Она и сейчас есть из-за методов-расширений. Сделают по удобнее фильтрацию в ИДЕ и все. Типа три опции: все, только расширения, только реальные члены.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Методы-расширения и UFCS
От: varenikAA  
Дата: 11.02.21 03:33
Оценка:
Здравствуйте, x-code, Вы писали:

XC>А вот если проектировать язык программирования с нуля, то какой подход предпочтительнее?


Предпочтительнее всего:
(f x y)
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Методы-расширения и UFCS
От: Ночной Смотрящий Россия  
Дата: 11.02.21 07:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Она и сейчас есть из-за методов-расширений.


Если аккуратно подходить у проектированию, то проблемы особой нет.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Методы-расширения и UFCS
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 11.02.21 15:48
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Предпочтительнее всего:

AA> (f x y)

C UFCS можно удобно цепочки преобразований записывать линейно слева-направо:
10.iota.retro.filter!even.map!text.writeln; // ["8", "6", "4", "2", "0"]

В стиле обычного лиспа это будет
(println (map str (filter even? (reverse (range 10)))))

Что не все сочтут удобно читаемым. Недаром в кложу добавили ->> чтобы записывать это как
(->> 10 range reverse (filter even?) (map str) println)
Re: Методы-расширения и UFCS
От: Шахтер Интернет  
Дата: 11.02.21 17:28
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Что вы об этом думаете?

XC>Есть подход в C#, когда в функции (обычно статический метод другого класса) явно добавляют к параметру модификатор this, и после этого эту функцию можно вызывать как метод того объекта, для которого добавили this.
XC>Есть предложение C++ n4474, в котором Саттер и Страуструп объединили свои размышления и пришли к выводу, что хорошо бы разрешать вызывать x.f(y) вместо f(x,y) и наоборот безо всяких модификаторов this. В документе рассмотрены преимущества такого подхода (шаблоны, концепты, интеллисенс).
XC>Вроде бы нечто подобное сделано в D.
XC>А вот если проектировать язык программирования с нуля, то какой подход предпочтительнее?
XC>Какие преимущества и недостатки у явно определенных методов-расширений и унифицированного синтаксиса вызова функций вы видите?

Модификатор this нужен.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Методы-расширения и UFCS
От: varenikAA  
Дата: 12.02.21 01:36
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Что не все сочтут удобно читаемым. Недаром в кложу добавили ->> чтобы записывать это как


При желании в лиспе можно любой макр`Ос написать )))
по первому не скажу, а вот стрелка такая уже реализована(пару дней назад видел, название проекта не запомнил).
для точечной нотации думаю можно тоже макрос написать, разбор в принципе простой. с интелисенсом конеш заморочно наверно.
А чтобы читаемо было, там делают также как и 50 лет назад:
(println 
    (map str 
        (filter even? 
            (reverse (range 10))))
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: Методы-расширения и UFCS
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 12.02.21 12:19
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>по первому не скажу, а вот стрелка такая уже реализована(пару дней назад видел, название проекта не запомнил).


Я говорю, в clojure это уже есть из коробки.
Re[5]: Методы-расширения и UFCS
От: varenikAA  
Дата: 15.02.21 09:36
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Я говорю, в clojure это уже есть из коробки.


я просто не уверен, что спец символы лучше воспринимаются чем английские термины.
Именно в этом сила лиспа — в однообразии, как только в стандарт примут эти стрелки, так считай убьют язык.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[6]: Методы-расширения и UFCS
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 16.02.21 00:39
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>я просто не уверен, что спец символы лучше воспринимаются чем английские термины.

AA>Именно в этом сила лиспа — в однообразии, как только в стандарт примут эти стрелки, так считай убьют язык.

Какой стандарт, какое однообразие? Лиспов много самых разных — Common Lisp, Scheme, Racket, Clojure, Emacs Lisp, Arc, Shen и пр. На стандарт коммон лиспа всем насрать. И всяких спецсимволов там уже сейчас очень много.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.