А почему нет вызова функций с именованными аргументами?
От: enji  
Дата: 11.09.14 09:20
Оценка: +5 -1
Тут недавно холиварчик был С vs С++, там как одно из преимуществ С была запись
struct T { int a, b; };
T t = {.a = 1, .b=42};


Если с таким разбирается компилятор С, то что мешает компилятору С++ разобраться с
void f(int a, int b);

f(.a = 1, .b=42);


Понятно, что в некоторых редких случаях в разных единицах трансляции названия аргументов f могут быть разными (или вообще отсутствовать). Но если аргументы разные и используется такой вызов, то это можно просто трактовать как нарушение ODR (очередное недиагностируемое ).

Понятно, что есть буст, но имхо, то, что там предлагается, выглядит уродливо, порождает нечитаемые сообщения об ошибках, засоряет пространство имен (или на ровном месте вводит новое), замедляет компиляцию, подозреваю также, у него есть проблемы с перегрузкой и неявными преобразованиями. Кроме того, оно требует правки хидеров или написания врапперов. Такие вещи все ж должны быть на уровне языка.

Ваше мнение?
Re: А почему нет вызова функций с именованными аргументами?
От: PM  
Дата: 11.09.14 09:43
Оценка: 4 (1)
Здравствуйте, enji, Вы писали:

E>Если с таким разбирается компилятор С, то что мешает компилятору С++ разобраться с

E>
E>void f(int a, int b);

E>f(.a = 1, .b=42);
E>

...
E>Ваше мнение?

Мое скромное мнение — это синтаксический оверхед Для 2-4 аргументов можно запомнить, что из них какой означает. Если аргументов больше, значит нужно менять функцию (вносить в класс, разбивать на несколько, передавать в конце концов структуру с параметрами). И да, функции Win32 API — это неизлечимая клиника.
Re: А почему нет вызова функций с именованными аргументами?
От: Abyx Россия  
Дата: 11.09.14 09:47
Оценка:
Здравствуйте, enji, Вы писали:

E>что мешает компилятору С++ разобраться с

E>
E>void f(int a, int b);

E>f(.a = 1, .b=42);
E>


E>Понятно, что в некоторых редких случаях в разных единицах трансляции названия аргументов f могут быть разными (или вообще отсутствовать). Но если аргументы разные и используется такой вызов, то это можно просто трактовать как нарушение ODR (очередное недиагностируемое ).


это сломает обратную совместимость.
In Zen We Trust
Re[2]: А почему нет вызова функций с именованными аргументами?
От: enji  
Дата: 11.09.14 10:00
Оценка: +1
Здравствуйте, Abyx, Вы писали:

A>это сломает обратную совместимость.


гм. Это каким же образом?
Re[2]: А почему нет вызова функций с именованными аргументами?
От: enji  
Дата: 11.09.14 10:09
Оценка:
Здравствуйте, PM, Вы писали:

PM>Мое скромное мнение — это синтаксический оверхед

В синтаксическом оверхеде нет ничего плохого, если он упрощает жизнь +=, ++, лямбды — все это синтаксический оверхед...

PM>Для 2-4 аргументов можно запомнить, что из них какой означает.

да как сказать. Вот к примеру я стараюсь не использовать булевых аргументов
void addElement(T, bool replace);

enum ReplaceOrNot {
  Replace, DontReplace
};
void addElement2(T, ReplaceOrNot replace);

addElement(1, false);
addElement2(1, Replace);

addElement(1, .replace=true); // также понятно, как и addElement2, но нет оверхеда с созданием enum

// да, можно сделать два метода - addElement(T), addOrReplaceElement(T) - но если булевых аргументов два - то делать четыре?
// да, можно аргументы метода передавать в виде структуры. Можно даже изобрести объект-метод addElement(1).replace(false)()
// но все это обход недостатка языка...


И опять же, пока я работаю над каким-то кодом, я помню. Но когда через год приходится в нем снова ковыряться, то я уже не помню
Re: А почему нет вызова функций с именованными аргументами?
От: DiZSl  
Дата: 11.09.14 10:22
Оценка: +1
Здравствуйте, enji, Вы писали:

E>Ваше мнение?


Мне нравиться. От себя еще добавлю, чтоб можно было вот так:

void f(int a, int b);
f(.b=42, .a = 1);
Re[2]: А почему нет вызова функций с именованными аргументами?
От: DiZSl  
Дата: 11.09.14 10:27
Оценка: +2 -1
Здравствуйте, PM, Вы писали:

PM>Мое скромное мнение — это синтаксический оверхед Для 2-4 аргументов можно запомнить, что из них какой означает. Если аргументов больше, значит нужно менять функцию (вносить в класс, разбивать на несколько, передавать в конце концов структуру с параметрами). И да, функции Win32 API — это неизлечимая клиника.


Ну это лично ваше мнение, я считаю наоборот, что не надо использовать лишний раз структуры и классы, если для этого нет предпосылок. Win API вполне себе нормальное API (если не считать анахронизмов), а такие библиотеки как boost — вот это вот клиника.
Re: А почему нет вызова функций с именованными аргументами?
От: NeoCode  
Дата: 11.09.14 10:38
Оценка:
Здравствуйте, enji, Вы писали:

E>Ваше мнение?


Язык C++ кривой, а его все развивают, да еще и с сохранением дурацкой "обратной совместимости". Если перечислять чего в нем нету то можно составить список из сотен пунктов.
Идея хорошая, я к ней пришел независимо и достаточно давно, но ввиду огромного количества древних костылей типа системы инклудов и прочего вряд ли это можно сделать.
Re: А почему нет вызова функций с именованными аргументами?
От: lithium4356  
Дата: 11.09.14 11:10
Оценка: -2
Здравствуйте, enji, Вы писали:

E>Ваше мнение?


Наше мнение — надо двигаться от усложнизма к упростизму(простигосподи), всё гениальное просто(с), вызов функции вида "f(.a = 1, .b=42)" эээ, явный перебор
Re: А почему нет вызова функций с именованными аргументами?
От: Alexander G Украина  
Дата: 11.09.14 11:25
Оценка: +1
Здравствуйте, enji, Вы писали:

E>Ваше мнение?


Задачка Саттера "какая функция вызовется" (с шаблонными функциями, специализациями, не-шаблонными перегрузками, дефолтными параметрами) могла бы выйти на новый уровень сложности.
Русский военный корабль идёт ко дну!
Re: А почему нет вызова функций с именованными аргументами?
От: uzhas Ниоткуда  
Дата: 11.09.14 11:37
Оценка: 5 (1)
Здравствуйте, enji, Вы писали:

E>Ваше мнение?


такие предложения уже были, даже либы какие-то накропали как proof of concept
https://groups.google.com/forum/#!topic/mozilla.dev.platform/2kLnr-ZPlzU
http://ehsan.github.io/namedargs/namedargs.html
http://comments.gmane.org/gmane.comp.lang.c%2B%2B.isocpp.proposals/4122
Re[3]: А почему нет вызова функций с именованными аргументами?
От: Abyx Россия  
Дата: 11.09.14 11:40
Оценка:
Здравствуйте, enji, Вы писали:

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


A>>это сломает обратную совместимость.


E>гм. Это каким же образом?


ну возможно я погорячился насчет "обратной совместимости",
но тем не менее твоя идея требует чтобы имена параметров были одинаковые в пределах единицы трансляции.
а в тоннах легаси кода это не так.
In Zen We Trust
Re: А почему нет вызова функций с именованными аргументами?
От: Tilir Россия http://tilir.livejournal.com
Дата: 11.09.14 11:45
Оценка: +2
Здравствуйте, enji, Вы писали:

E>Ваше мнение?


Регулярно всплывает как оформленные пропозалы

Их регулярно заворачивают взад обратно. Первым их кажется завернул лично Страуструп из C++98 proposal, так с тех пор и повелось.

В языке и без того можно найти способ
(кстати автор по моей ссылке неявно цитирует метод, также предложенный ещё Страуструпом, но мне лень искать оригинальный)

Мне кажется, это harmful, хотя бы потому, что заставляет меня иметь имена параметров как часть сигнатуры функции. Отвратительно. В сигнатуру должны входить только типы, имена должны быть up-to-me. Захотел и переименовал, не разрушив существующего кода.

Для меня более забавно, что традиционно более консервативный комитет по стандартизации C пропустил инициализацию структур в таком виде.
Re[2]: А почему нет вызова функций с именованными аргументами?
От: uzhas Ниоткуда  
Дата: 11.09.14 12:04
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Мне кажется, это harmful, хотя бы потому, что заставляет меня иметь имена параметров как часть сигнатуры функции. Отвратительно. В сигнатуру должны входить только типы, имена должны быть up-to-me. Захотел и переименовал, не разрушив существующего кода.


соглашусь. у функций может быть много объявлений и одно определение. необходимость протаскивать одинаковые имена для параметров во всех объявлениях сильно напряжет и сломает обратную совместимость. по сути имена параметров станет частью сигнатуры. со структурами такой проблему нет: при определении структуры надо прописать один раз имена свойствам
Re[3]: А почему нет вызова функций с именованными аргументами?
От: PM  
Дата: 11.09.14 12:23
Оценка:
Здравствуйте, DiZSl, Вы писали:

DZS>Ну это лично ваше мнение, я считаю наоборот, что не надо использовать лишний раз структуры и классы, если для этого нет предпосылок. Win API вполне себе нормальное API (если не считать анахронизмов), а такие библиотеки как boost — вот это вот клиника.


Мне лень искать в WinAPI функцию кажется с 19-ю аргументами (емнип где-то в подсистеме безопасности), но вот всем известные CreateWindow и RegisterClass:
HWND WINAPI CreateWindow(
  _In_opt_  LPCTSTR lpClassName,
  _In_opt_  LPCTSTR lpWindowName,
  _In_      DWORD dwStyle,
  _In_      int x,
  _In_      int y,
  _In_      int nWidth,
  _In_      int nHeight,
  _In_opt_  HWND hWndParent,
  _In_opt_  HMENU hMenu,
  _In_opt_  HINSTANCE hInstance,
  _In_opt_  LPVOID lpParam
);


ATOM WINAPI RegisterClass(
  _In_  const WNDCLASS *lpWndClass
);

typedef struct tagWNDCLASS {
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
  LPCTSTR   lpszClassName;
} WNDCLASS, *PWNDCLASS;


Не знаю, чем руководствовались разработчики (может быть это были 2 разных команды), но я не вижу преимуществ в способе задания параметров для CreateWindow перед RegisterClass.

Про boost в моем сообщении ничего не было, так что оставлю без комментариев.
Re[4]: А почему нет вызова функций с именованными аргументами?
От: enji  
Дата: 11.09.14 12:35
Оценка:
Здравствуйте, Abyx, Вы писали:

A>ну возможно я погорячился насчет "обратной совместимости",

A>но тем не менее твоя идея требует чтобы имена параметров были одинаковые в пределах единицы трансляции.
A>а в тоннах легаси кода это не так.

Ну прям вот так уж и в тоннах? Разные имена параметров означают, что одна и таже функция определена по разному в двух разных хидерах. Насколько это частое явление?
Да даже если в какой-то либе оно частое — просто компилятор будет ругаться при попытке вызвать ее таким образом...

Или не будет, если это разные единицы трансляции И у нас будет еще одно не диагностируемое нарушение ODR

Собственно сейчас же как то живут с таким
/// a.cpp
struct T {
  std::string s;
} a;

/// b.cpp
struct T {
  int q;
  std::string s;
} b;
Re[2]: А почему нет вызова функций с именованными аргументами?
От: enji  
Дата: 11.09.14 12:38
Оценка:
Здравствуйте, Alexander G, Вы писали:


AG>Задачка Саттера "какая функция вызовется" (с шаблонными функциями, специализациями, не-шаблонными перегрузками, дефолтными параметрами) могла бы выйти на новый уровень сложности.


ну есть такое дело. И что? Да, будут какие-то новые темные углы. И можно будет прострелить себе ногу новым способом. Но в плюсах уже есть сотни таких способов, что добавит еще один?

Для начала его можно оградить, запретив такой вызов там, где с ним вероятны проблемы...
Re[2]: А почему нет вызова функций с именованными аргументам
От: enji  
Дата: 11.09.14 12:40
Оценка:
Здравствуйте, uzhas, Вы писали:


U>такие предложения уже были, даже либы какие-то накропали как proof of concept


я помню на рсдн что-то уже обсуждалось такое, не смог сходу найти тему.

Вроде как даже было предложение в стандарт 2011 внести, но почему-то откатили

Просто счас почитал холиварчик
Автор: ramar
Дата: 04.09.14
и чет снова задумался, почему нету в плюсах, если в си добавили...
Отредактировано 11.09.2014 12:42 enji . Предыдущая версия .
Re[2]: А почему нет вызова функций с именованными аргументам
От: enji  
Дата: 11.09.14 12:45
Оценка:
Здравствуйте, Tilir, Вы писали:

T>В языке и без того можно найти способ

T>(кстати автор по моей ссылке неявно цитирует метод, также предложенный ещё Страуструпом, но мне лень искать оригинальный)

Дык и лямбды не нужны, можно же найти способ

Про описанный способ я в курсе. И если бы имелся нормальный макропроцессор (который мог бы на основе функции сделать такой класс) — он бы вполне устроил. Но сейчас это все надо писать руками или городить что-то на BOOST_PREPROCESSOR — а это сильно захламляет объявление...

T>Мне кажется, это harmful, хотя бы потому, что заставляет меня иметь имена параметров как часть сигнатуры функции. Отвратительно. В сигнатуру должны входить только типы, имена должны быть up-to-me. Захотел и переименовал, не разрушив существующего кода.


А чем функция принципиально отличается от структуры/класса в этом смысле ? Если код твой — отрефакторил, если чужой — ну что ж, придется с этим жить.

Опять же, взять тот же питон, вба, скалу (вроде бы) — там это есть, и ничего, полет нормальный...

T>Для меня более забавно, что традиционно более консервативный комитет по стандартизации C пропустил инициализацию структур в таком виде.


удобно же
Отредактировано 11.09.2014 12:53 enji . Предыдущая версия .
Re[3]: А почему нет вызова функций с именованными аргументами?
От: PM  
Дата: 11.09.14 12:47
Оценка:
Здравствуйте, enji, Вы писали:

PM>>Для 2-4 аргументов можно запомнить, что из них какой означает.

E>да как сказать. Вот к примеру я стараюсь не использовать булевых аргументов
<здесь был код>

Рекомендацию про неиспользование булевых параметров встречал только от пишущих на Java, сам проблем с ними не испытываю
Наверно дело вкуса, для меня вариант с addElement(T), addOrReplaceElement(T) вполне приемлем. Меня больше настораживает странная структура данных которая позволяет добавлять и уникальные элементы, и дубликаты.

E>И опять же, пока я работаю над каким-то кодом, я помню. Но когда через год приходится в нем снова ковыряться, то я уже не помню


Думаю тут дело не только в коде, через год придется всё равно что-то вспоминать. Вот прямо сейчас я залез в свой же код годовалой давности, вспоминаю
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.