Передача аргументов в функцию - позиционные vs именованные
От: Shmj Ниоткуда  
Дата: 18.03.25 14:09
Оценка:
Вот стандартная практика — как бы по порядку. Т.е. через запятую последовательно.

А ведь есть более умные решения: именованные аргументы функции. Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.

Какой вариант вам удобнее?
=сначала спроси у GPT=
Re: Передача аргументов в функцию - позиционные vs именованные
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.03.25 14:32
Оценка: +3
Здравствуйте, Shmj, Вы писали:

S>Какой вариант вам удобнее?

Если в функции — сорок параметров, из которых 38 необязательные, то именованные удобнее. Если в функции — два параметра, и оба обязательные, то удобнее позиционные.
Ваш К.О.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Передача аргументов в функцию - позиционные vs именованные
От: Shmj Ниоткуда  
Дата: 18.03.25 14:37
Оценка:
Здравствуйте, Sinclair, Вы писали:


S>>Какой вариант вам удобнее?

S>Если в функции — сорок параметров, из которых 38 необязательные, то именованные удобнее. Если в функции — два параметра, и оба обязательные, то удобнее позиционные.
S>Ваш К.О.

Тут еще момент. Если два параметра и оба одного типа — как то два int — то в случае позиционных нужно держать в голове порядок. А зачем держать, если можно не держать?
=сначала спроси у GPT=
Re[3]: Передача аргументов в функцию - позиционные vs именованные
От: Privalov  
Дата: 18.03.25 14:41
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Тут еще момент. Если два параметра и оба одного типа — как то два int — то в случае позиционных нужно держать в голове порядок. А зачем держать, если можно не держать?


Нормальные имена переменным задавать не пробовал?
Лично мне после передачи полутора десятков аргументов на фортране именованные параметры не очень и нужны.
Re[3]: Передача аргументов в функцию - позиционные vs именованные
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.03.25 15:26
Оценка: 3 (1) +2
Здравствуйте, Shmj, Вы писали:

S>Тут еще момент. Если два параметра и оба одного типа — как то два int — то в случае позиционных нужно держать в голове порядок. А зачем держать, если можно не держать?

Зачем заниматься умозрительными рассуждениями, когда можно просто попробовать написать код?
Практика — критерий истины:

var d = sub(sqr(b), mul(4, mul(a, c)));
if(d >= 0)
{
  var x1 = div(sub(neg(b), sqrt(d)), mul(2, a));
  var x2 = div(sum(neg(b), sqrt(d)), mul(2, a));
  Console.WriteLine("Solutions are {x1} and {x2}", x1, x2);
}


var d = sub(minuend = sqr(base = b), subtrahend = mul(multiplier=4, multiplicand = mul(multiplier = a, multiplicand = c)));
if(d >= 0)
{
  var x1 = div(dividend = sub(minuend = neg(subtrahend = b), subtrahend = sqrt(power = d)), divisor = mul(multiplier = 2, multiplicand = a));
  var x2 = div(dividend = sum(augend = neg(subtrahend = b), addend = sqrt(power = d)), divisor = mul(multiplier = 2, multiplicand = a));
  Console.WriteLine(formatString = "Solutions are {0} and {1}", zeroethArg = x1, firstArg = x2);
}


Какая из записей вам более понятна? Кстати, во втором варианте есть супербонус — можно же менять порядок аргументов. Как говорится, spot an error:
var d = sub(minuend = sqr(base = b), subtrahend = mul(multiplier=4, multiplicand = mul(multiplier = a, multiplicand = c)));
if(d >= 0)
{
  var x1 = div(dividend = sub(subtrahend = sqrt(power = d), minuend = neg(subtrahend = b)), divisor = mul(multiplier = 2, multiplicand = a));
  var x2 = div(divisor = mul(multiplier = 2, multiplicand = a), dividend = sum(augend = neg(subtrahend = b), addend = sqrt(power = d)));
  Console.WriteLine(formatString = "Solutions are {0} and {1}", firstArg = x1, zeroethArg = x2);
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Передача аргументов в функцию - позиционные vs именованные
От: wl. Россия  
Дата: 18.03.25 16:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


S>>Тут еще момент. Если два параметра и оба одного типа — как то два int — то в случае позиционных нужно держать в голове порядок. А зачем держать, если можно не держать?

S>Зачем заниматься умозрительными рассуждениями, когда можно просто попробовать написать код?

В принципе CLion показывает, как называются параметры. По мне так это даже лучше, чем вручную именованные параметры набивать:

Re[5]: Передача аргументов в функцию - позиционные vs именованные
От: Muxa  
Дата: 18.03.25 16:46
Оценка:
wl.>В принципе CLion показывает, как называются параметры. По мне так это даже лучше, чем вручную именованные параметры набивать:

wl.>[img]

wl.>https://files.rsdn.org/69309/clion.png
wl.>[/img]

тоже самое делает vscode c clangd плагином
Re: Передача аргументов в функцию - позиционные vs именованные
От: Muxa  
Дата: 18.03.25 16:47
Оценка:
S>Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.
а если изменилось имя аргумента?
Re: Передача аргументов в функцию - позиционные vs именованные
От: jamesq Россия  
Дата: 18.03.25 21:25
Оценка: +2 -2
Здравствуйте, Shmj, Вы писали:

S>Вот стандартная практика — как бы по порядку. Т.е. через запятую последовательно.


S>А ведь есть более умные решения: именованные аргументы функции. Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.


S>Какой вариант вам удобнее?


Обычные позиционные аргументы эффективнее. Они просто кидаются в стек по-порядку с минимум накладных расходов. Или в случае __fastcall, вообще передаются в регистрах.

В случае же именнованных, надо как-то хранить соответствие имен и значений. В питоне, как я подозреваю, там dictionary передается.
В общем, не так уж и умно выходит. Надеюсь, ты не будешь злоупотреблять ими.
Re: Передача аргументов в функцию - позиционные vs именованные
От: SkyDance Земля  
Дата: 18.03.25 23:27
Оценка:
S>Какой вариант вам удобнее?

Который меньше буков при прочих равных.
Re[2]: Передача аргументов в функцию - позиционные vs именованные
От: Константин Б. Россия  
Дата: 19.03.25 04:37
Оценка: 1 (1)
Здравствуйте, jamesq, Вы писали:

J>Обычные позиционные аргументы эффективнее. Они просто кидаются в стек по-порядку с минимум накладных расходов. Или в случае __fastcall, вообще передаются в регистрах.


J>В случае же именнованных, надо как-то хранить соответствие имен и значений. В питоне, как я подозреваю, там dictionary передается.

J>В общем, не так уж и умно выходит. Надеюсь, ты не будешь злоупотреблять ими.

Если речь про питон, то там и позиционные параметры в виде list передаются.
А если про какой-нибудь C# то там всякая разница пропадает во время компиляции.
А в каком-нибудь С используются структуры, которые тоже замечательно на стеке хранятся.

С точки зрения производительности вообще непринципиально что использовать.
Re[2]: Передача аргументов в функцию - позиционные vs именов
От: Doom100500 Израиль  
Дата: 19.03.25 06:23
Оценка:
Здравствуйте, Muxa, Вы писали:


S>>Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.

M>а если изменилось имя аргумента?

То проект не соберётся и заставит исправлять ошибки. Тогда как, если поменялись местами аргументы одинакового типа, всё будет молчать.
Спасибо за внимание
Отредактировано 19.03.2025 6:31 Doom100500 . Предыдущая версия .
Re[4]: Передача аргументов в функцию - позиционные vs именов
От: Doom100500 Израиль  
Дата: 19.03.25 06:27
Оценка:
Здравствуйте, Privalov, Вы писали:

P>Нормальные имена переменным задавать не пробовал?

P>Лично мне после передачи полутора десятков аргументов на фортране именованные параметры не очень и нужны.

И тут, вдруг, ты узнал, что твоим кодом пользуются люди, и делают ошибки. Не, нуачё, пусть внимательнее будут .
Спасибо за внимание
Отредактировано 19.03.2025 6:28 Doom100500 . Предыдущая версия .
Re[3]: Передача аргументов в функцию - позиционные vs именованные
От: Muxa  
Дата: 19.03.25 06:34
Оценка:
S>>>Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.
M>>а если изменилось имя аргумента?
D>То проект не соберётся и заставит исправлять ошибки.
Для ТС это минус, я так понял — то что нужно лазить по всему коду и чот там исправлять.
Re[4]: Передача аргументов в функцию - позиционные vs именованные
От: Doom100500 Израиль  
Дата: 19.03.25 06:34
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Какая из записей вам более понятна? Кстати, во втором варианте есть супербонус — можно же менять порядок аргументов. Как говорится, spot an error:

S>
S>var d = sub(minuend = sqr(base = b), subtrahend = mul(multiplier=4, multiplicand = mul(multiplier = a, multiplicand = c)));
S>if(d >= 0)
S>{
S>  var x1 = div(dividend = sub(subtrahend = sqrt(power = d), minuend = neg(subtrahend = b)), divisor = mul(multiplier = 2, multiplicand = a));
S>  var x2 = div(divisor = mul(multiplier = 2, multiplicand = a), dividend = sum(augend = neg(subtrahend = b), addend = sqrt(power = d)));
S>  Console.WriteLine(formatString = "Solutions are {0} and {1}", firstArg = x1, zeroethArg = x2);
S>}
S>


Чисто теоритически, язык может предоставить опции по совмещению подходов, как питон, например.
Спасибо за внимание
Re[5]: Передача аргументов в функцию - позиционные vs именованные
От: Sinclair Россия https://github.com/evilguest/
Дата: 19.03.25 07:11
Оценка:
Здравствуйте, Doom100500, Вы писали:

D>Чисто теоритически, язык может предоставить опции по совмещению подходов, как питон, например.

Чисто практически, C# такие опции тоже предоставляет.
Речь-то шла не о том, что есть в языке, а чего нету. А о том, что удобнее использовать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Передача аргументов в функцию - позиционные vs именованные
От: korvin_  
Дата: 19.03.25 08:31
Оценка:
Здравствуйте, Muxa, Вы писали:


S>>Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.

M>а если изменилось имя аргумента?

Как, например, в примере выше:

sqrt(power = d))


неправильное именование, аргумент для sqrt -- это не power (степень), а просто некое число. Теперь везде переименовывать. А учитывая, что это функция, наверняка, стандартнобиблиотечная, то весь код, который её использует, во всём мире придётся обновлять.
Re[5]: Передача аргументов в функцию - позиционные vs именов
От: Privalov  
Дата: 19.03.25 08:31
Оценка:
Здравствуйте, Doom100500, Вы писали:

D>И тут, вдруг, ты узнал, что твоим кодом пользуются люди, и делают ошибки. Не, нуачё, пусть внимательнее будут .


С Фортраном приходилось так или иначе быть внимательным. Материалов "Грабли в Фортране" было намного больше, чем "Как писать на Фортране". А "Фортран за 21 день" вообще не было.
Тогда было два способа передавать данные: либо через параметры, либо через COMMON-блоки. Именно тогда мы усвоили: за беспорядочное использование COMMON-блоков наду отрывать руки. Поэтому и передавали по десятку параметров. И за ними следили. Именно поэтому у меня не было проблем с использованием фортрановских библиотек, того же Графора.
Естественно, с переходом на Фортран-90 я и подпрограммы interface начал активно использовать, и implicit none. Но кода на старом добром Fortran IV было немало. И, по слухам, он всё ещё работает.
Позже мне этот опыт пригодился, когда я работал с Васиком на "Искре-226". У него вообще всё было очень сложно по части граблей. Но проект, в котором я участвовал, не содержал ни одной строчки говнокода. И был я как раз в роли тех людей, которые пользуются чужим кодом. Да, нужно было соблюдать правила гигиены, не писать как попало. Зато всё работало без сербёзных багов.
А на православной Java я и NPE мог пропустить, правда, всего один раз такое случилось.
В любом случае внимательным надо быть. IDE, конечно, здорово помогают. Но последнее слово всё равно за разработчиком. Потому как никакая IDE не предотвращает написание говнокода.
Re[4]: Передача аргументов в функцию - позиционные vs именованные
От: korvin_  
Дата: 19.03.25 08:40
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>Зачем заниматься умозрительными рассуждениями, когда можно просто попробовать написать код?

S>Практика — критерий истины:

S>
S>var d = sub(minuend = sqr(base = b), subtrahend = mul(multiplier=4, multiplicand = mul(multiplier = a, multiplicand = c)));
S>if(d >= 0)
S>{
S>  var x1 = div(dividend = sub(minuend = neg(subtrahend = b), subtrahend = sqrt(power = d)), divisor = mul(multiplier = 2, multiplicand = a));
S>  var x2 = div(dividend = sum(augend = neg(subtrahend = b), addend = sqrt(power = d)), divisor = mul(multiplier = 2, multiplicand = a));
S>  Console.WriteLine(formatString = "Solutions are {0} and {1}", zeroethArg = x1, firstArg = x2);
S>}
S>


S>Какая из записей вам более понятна?


Такой код нужно форматировать по-другому, выстраивая параметры в столбик:

    let d = sub ~minuend:    (sqr ~base: b)
                ~subtrahend: (mul ~multiplier:   4.
                                  ~multiplicand: (mul ~multiplier:   a
                                                      ~multiplicand: c))
    in
    if d >= 0. then
      let x1 = div ~dividend: (sub ~minuend:    (neg ~subtrahend: b)
                                   ~subtrahend: (sqrt ~number: d))
                   ~divisor:  (mul ~multiplier:   2.
                                   ~multiplicand: a)
      and x2 = div ~dividend: (add ~augend: (neg ~subtrahend: b)
                                   ~addend: (sqrt ~number: d))
                   ~divisor:  (mul ~multiplier:   2.
                                   ~multiplicand: a)
      in
      Printf.printf "Solutions are %.1f and %.1f\n" x1 x2


Не то что бы стало сопоставимо с обычными, позиционными функциями, но чуть проще понять структуру (вложенность).
Re[2]: Передача аргументов в функцию - позиционные vs именов
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.03.25 09:50
Оценка: 3 (1) +3
Здравствуйте, Sinclair, Вы писали:

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


S>>Какой вариант вам удобнее?

S>Если в функции — сорок параметров, из которых 38 необязательные, то именованные удобнее. Если в функции — два параметра, и оба обязательные, то удобнее позиционные.
S>Ваш К.О.

(голосом удава) А три — это куча?

Я в одном проекте нашёл три или четыре места, где у memset() перепутали длину и заполнитель, а так в C++ это параметры оба целые, никакого плача от компилятора не было.

В итоге я выдвинул правку — сделать хелпер типа

class MemsetCaller {
  void *mAddress;
  size_t mLength;
public:
  MemsetCaller(void *address, size_t length) : mAddress(address), mLength(length) {}
  void fillWith(char c) { ::memset(mAddress, c, mLength); // сам проверял по ману когда это сейчас писал
  }
};

и все вызовы перекинул на MemsetCaller(a, len).fillWith('\xA5') и в таком же духе.

Это отличный пример, где принудительно именованные аргументы точно пригодились бы.

UPD: Кто скажет, мол, IDE должна помочь — подставляйте лоб, метаю камень без раздумий. Полно случаев, когда IDE не справляется или вообще не может быть применена.
The God is real, unless declared integer.
Отредактировано 19.03.2025 9:51 netch80 . Предыдущая версия .
Re: Передача аргументов в функцию - позиционные vs именованн
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.03.25 10:00
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Вот стандартная практика — как бы по порядку. Т.е. через запятую последовательно.


S>А ведь есть более умные решения: именованные аргументы функции. Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.


S>Какой вариант вам удобнее?


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

Если я сподвигнусь на создание своего языка, такие возможности там будут обязательно присутствовать, вместе с полиморфизмом по таким именам (например, jump(meters: ) и jump(feet: ) могут быть разными функциями).
Тут самое сложное — как задавать уникальные сигнатуры на уровне линкера. Добавлять хэш от описания как-то не хочется.
The God is real, unless declared integer.
Отредактировано 19.03.2025 15:47 netch80 . Предыдущая версия .
Re: Передача аргументов в функцию - позиционные vs именованные
От: Буравчик Россия  
Дата: 19.03.25 10:18
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Какой вариант вам удобнее?


Посмотри как сделано в питон — удобно

Там есть и позиционные аргументы, и именованные, и дефолтные.
При это в вызове ты сам решаешь как их указывать — с именами или без.
Best regards, Буравчик
Re[2]: Передача аргументов в функцию - позиционные vs именованные
От: Enomay Россия  
Дата: 19.03.25 10:25
Оценка: +1 -1
Здравствуйте, Sinclair, Вы писали:

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


S>>Какой вариант вам удобнее?

S>Если в функции — сорок параметров, из которых 38 необязательные, то именованные удобнее. Если в функции — два параметра, и оба обязательные, то удобнее позиционные.
S>Ваш К.О.

Если в функции 40 параметров, то
во-первых, с функцией явные проблемы
во-вторых, для передачи параметров используют один объект с 40 полями
- Слава России!
— Героям СВО Слава!
Re[3]: Передача аргументов в функцию - позиционные vs именов
От: Sinclair Россия https://github.com/evilguest/
Дата: 19.03.25 10:35
Оценка:
Здравствуйте, netch80, Вы писали:
N>(голосом удава) А три — это куча?
Опять же, всё зависит от того, насколько очевидно их применение.

N>Я в одном проекте нашёл три или четыре места, где у memset() перепутали длину и заполнитель, а так в C++ это параметры оба целые, никакого плача от компилятора не было.

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

N>В итоге я выдвинул правку — сделать хелпер типа


N>
N>class MemsetCaller {
N>  void *mAddress;
N>  size_t mLength;
N>public:
N>  MemsetCaller(void *address, size_t length) : mAddress(address), mLength(length) {}
N>  void fillWith(char c) { ::memset(mAddress, c, mLength); // сам проверял по ману когда это сейчас писал
N>  }
N>};
N>

Да, отличное решение. Которое показывает, что и в языке с позиционными аргументами можно подстелить соломки в тех немногих местах, где хочется потребовать именованности.
N>Это отличный пример, где принудительно именованные аргументы точно пригодились бы.
Не факт, что принудительно именованные аргументы привели бы к такому хорошему решению.
Обратите внимание, что вы фактически изобрели структуру Span<sbyte>, которая сама по себе архитектурно в разы лучше голых указателей.
Пригодна она далеко не только для того, чтобы вызывать fill(). А, например, и для безопасных методов вроде .slice(offset, len).
Получилось бы у вас это в языке с "принудительно именованными аргументами"? Вряд ли: вы бы просто продолжали писать
a fill: len with: '\xA5'
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Передача аргументов в функцию - позиционные vs именов
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.03.25 16:07
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Пригодна она далеко не только для того, чтобы вызывать fill(). А, например, и для безопасных методов вроде .slice(offset, len).

S>Получилось бы у вас это в языке с "принудительно именованными аргументами"?

С локальным выводом я согласен, а вот общего не понимаю.
Если тут в конкретном случае сработало "чем хуже, тем лучше", то постоянно принуждать к этому мне как-то не нравится, польза от явного именования будет точно больше.
The God is real, unless declared integer.
Re[3]: Передача аргументов в функцию - позиционные vs именов
От: SkyDance Земля  
Дата: 19.03.25 16:58
Оценка: +1 :))
D>То проект не соберётся и заставит исправлять ошибки. Тогда как, если поменялись местами аргументы одинакового типа, всё будет молчать.

Что, и даже тесты не упадут?
Re[6]: Передача аргументов в функцию - позиционные vs именованные
От: SkyDance Земля  
Дата: 19.03.25 16:59
Оценка: +1
S>Речь-то шла не о том, что есть в языке, а чего нету. А о том, что удобнее использовать.

C# мне в этом плане больше всего нравится. И гибко, и кратко (если хочется).
Re[5]: Передача аргументов в функцию - позиционные vs именов
От: Sinclair Россия https://github.com/evilguest/
Дата: 19.03.25 17:33
Оценка: +1
Здравствуйте, netch80, Вы писали:

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


S>>Пригодна она далеко не только для того, чтобы вызывать fill(). А, например, и для безопасных методов вроде .slice(offset, len).

S>>Получилось бы у вас это в языке с "принудительно именованными аргументами"?

N>С локальным выводом я согласен, а вот общего не понимаю.

N>Если тут в конкретном случае сработало "чем хуже, тем лучше", то постоянно принуждать к этому мне как-то не нравится, польза от явного именования будет точно больше.
На 100000 мест, где позиционные параметры вполне Ок и не вызывают ошибок применения (например, потому что у нас вменяемая система типов, и указатель отличается от инта, инт — от енума, и енумы друг от друга тоже отличаются), находится 50 мест, где вызываются вредительские функции типа memset, из которых 4 или 5 содержат ошибку.
Заставлять писать код в стиле https://rsdn.org/forum/flame.comp/8912507.1
Автор: Sinclair
Дата: 18.03.25
только ради отлова этих 4 или 5 мест — оверкилл. Особенно когда это можно точечно исправить.
В шарпе, например, нет именованных параметров, есть только именованные аргументы. То есть тот, кто опасается не угадать с порядком, может написать подразумеваемые имена аргументов.
И тогда компилятор его предупредит, что порядок не соответствует ожидаемому. Но ошибки-то делают не те, кто сомневается, а кто фигачит ::memset(a, len, '\xA5').
В этом смысле свифт поступает лучше всех — он позволяет сомнения высказать на стороне разработчика функции, а не потребителя.
(А для шарпа остаётся делать стилистические правила в инспекторах кода — типа "давайте убедимся, что все вызовы memset оборудованы именами аргументов, потому что если нет — то пользователь мог ошибиться").
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Передача аргументов в функцию - позиционные vs именованные
От: Pzz Россия https://github.com/alexpevzner
Дата: 19.03.25 17:36
Оценка:
Здравствуйте, Shmj, Вы писали:

S>А ведь есть более умные решения: именованные аргументы функции. Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.


Ну и передай туда структуру с именованными полями.

S>Какой вариант вам удобнее?


Позиционный.
Re[2]: Передача аргументов в функцию - позиционные vs именованные
От: Pzz Россия https://github.com/alexpevzner
Дата: 19.03.25 17:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Если в функции — сорок параметров, из которых 38 необязательные, то именованные удобнее. Если в функции — два параметра, и оба обязательные, то удобнее позиционные.

S>Ваш К.О.

Если в функции — сорок параметров, то эту функцию надо бы порефакторить...
Re[5]: Передача аргументов в функцию - позиционные vs именов
От: Pzz Россия https://github.com/alexpevzner
Дата: 19.03.25 17:40
Оценка:
Здравствуйте, Doom100500, Вы писали:

P>>Лично мне после передачи полутора десятков аргументов на фортране именованные параметры не очень и нужны.


D>И тут, вдруг, ты узнал, что твоим кодом пользуются люди, и делают ошибки. Не, нуачё, пусть внимательнее будут .


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

Ну их, этих людей...
Re[3]: Передача аргументов в функцию - позиционные vs именованные
От: Sinclair Россия https://github.com/evilguest/
Дата: 19.03.25 17:55
Оценка: :)
Здравствуйте, Pzz, Вы писали:

Pzz>Если в функции — сорок параметров, то эту функцию надо бы порефакторить...


Удачи её порефакторить
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Передача аргументов в функцию - позиционные vs именованные
От: Буравчик Россия  
Дата: 19.03.25 19:00
Оценка: +2
Здравствуйте, Pzz, Вы писали:

Pzz>Ну и передай туда структуру с именованными полями.


Ага, а сначала не забудь определить типы структуры.

И потому вместо нескольких функций куча лишнего кода для обвязки
Best regards, Буравчик
Re[3]: Передача аргументов в функцию - позиционные vs именов
От: B0FEE664  
Дата: 19.03.25 20:04
Оценка:
Здравствуйте, netch80, Вы писали:

N>Это отличный пример, где принудительно именованные аргументы точно пригодились бы.

Согласен.
Для С++ есть, кстати, разные трюки для именования аргументов. Вот тут один из.
displayCoolName(firstName = "James", lastName = "Bond");
И каждый день — без права на ошибку...
Re[4]: Передача аргументов в функцию - позиционные vs именов
От: Shmj Ниоткуда  
Дата: 19.03.25 20:37
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Для С++ есть, кстати, разные трюки для именования аргументов. Вот тут один из.

BFE>
BFE>displayCoolName(firstName = "James", lastName = "Bond");
BFE>


Для C++ вроде и все есть, но все жутко не удобно — ведь еще нужно писать обвязку.
=сначала спроси у GPT=
Re[3]: Передача аргументов в функцию - позиционные vs именов
От: PM  
Дата: 19.03.25 20:43
Оценка: 2 (1) +1
Здравствуйте, netch80, Вы писали:

N>и все вызовы перекинул на MemsetCaller(a, len).fillWith('\xA5') и в таком же духе.


N>Это отличный пример, где принудительно именованные аргументы точно пригодились бы.


Ну или strong types:

enum class Size : std::size_t {};
enum class Fill : std::uint8_t {};

void MemSet(void* ptr, Size size, Fill fill) {
    memset(ptr, std::to_underlying(fill), std::to_underlying(size));
}


int main() {
    int x[10];
    MemSet(x, Size{10}, Fill{11});
}


https://godbolt.org/z/nE9f6f1cf
Re: Передача аргументов в функцию - позиционные vs именованн
От: Философ Ад http://vk.com/id10256428
Дата: 19.03.25 20:43
Оценка:
Здравствуйте, Shmj, Вы писали:

S>...Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.


Менять порядок аргументов нужно только вот так, с помощью вот таких инструментов:
  Resharper Change signature


Это тебе гарантирует, что ты размо поменяешь вызовы везде и ничего не пропустишь. В ином случе, ты рискуешь что-нибудь забыть или перепутать. А ещё очень полезны юнит-тесты: они должны быть прежде чем ты начнёшь рефакторить. В случае, если ты что-нибудь забудешь в процессе или перепутаешь, они должны ломаться.

Публичные методы библиотек лучше вообще не менять — этим ты почти гарантированно испортишь жизнь своим пользователям: не везде есть стопроцентное покрытие тестами. И упаси тебя бог менять семантику параметров! Тут лучше заранее думать, что твои пользователи — неуравновешенные психи, вооружённые топорами.
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 19.03.2025 20:43 Философ . Предыдущая версия .
Re[3]: Передача аргументов в функцию - позиционные vs именованные
От: GarryIV  
Дата: 19.03.25 22:15
Оценка:
Здравствуйте, Enomay, Вы писали:

E>Если в функции 40 параметров, то

E>во-первых, с функцией явные проблемы
E>во-вторых, для передачи параметров используют один объект с 40 полями

ага, а объект иммутабл нужен, упс у нас конструктор с 40 параметрами )
функции с 40 параметрами по опыту и делают часто объект с 40 полями
и там еще у большинства дефолтные значения.
вполне норм, больших проблем с этим нет.
WBR, Igor Evgrafov
Re[2]: Передача аргументов в функцию - позиционные vs именованные
От: GarryIV  
Дата: 19.03.25 22:21
Оценка: +1
Здравствуйте, Буравчик, Вы писали:

Б>Там есть и позиционные аргументы, и именованные, и дефолтные.

Б>При это в вызове ты сам решаешь как их указывать — с именами или без.
там в декларации можно форсить вызов с именами. тоже полезно бывает.
WBR, Igor Evgrafov
Re[2]: Передача аргументов в функцию - позиционные vs именованн
От: Doom100500 Израиль  
Дата: 20.03.25 06:20
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Это тебе гарантирует


Ничего это не гарантирует. В любой момент можно баг словить, даже идеального( ) решарпера.
Спасибо за внимание
Re[4]: Передача аргументов в функцию - позиционные vs именов
От: Doom100500 Израиль  
Дата: 20.03.25 06:24
Оценка:
Здравствуйте, SkyDance, Вы писали:

D>>То проект не соберётся и заставит исправлять ошибки. Тогда как, если поменялись местами аргументы одинакового типа, всё будет молчать.


SD>Что, и даже тесты не упадут?


А что, их, типа, писать все умеют (и хотят) (и хотят уметь)?
Спасибо за внимание
Re[6]: Передача аргументов в функцию - позиционные vs именованные
От: Doom100500 Израиль  
Дата: 20.03.25 07:03
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

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


D>>Чисто теоритически, язык может предоставить опции по совмещению подходов, как питон, например.

S>Чисто практически, C# такие опции тоже предоставляет.
S>Речь-то шла не о том, что есть в языке, а чего нету. А о том, что удобнее использовать.

Ну а я о чём? Когда удобнее и понятнее именованные параметры — тогда их и используем. Когда неудобно — не используем :xz
Код, ведь, для читателей пишется. Вот об этом и надо думать, а не о фанатизме применения идиом по религиозным причинам.
Спасибо за внимание
Re[4]: Передача аргументов в функцию - позиционные vs именованные
От: Enomay Россия  
Дата: 20.03.25 07:37
Оценка:
Здравствуйте, GarryIV, Вы писали:

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


E>>Если в функции 40 параметров, то

E>>во-первых, с функцией явные проблемы
E>>во-вторых, для передачи параметров используют один объект с 40 полями

GIV>ага, а объект иммутабл нужен, упс у нас конструктор с 40 параметрами )

GIV>функции с 40 параметрами по опыту и делают часто объект с 40 полями
GIV>и там еще у большинства дефолтные значения.
GIV>вполне норм, больших проблем с этим нет.

Или не нужно что бы было иммутабл, если это единоразовая передача параметров.
В Фабрику, например.
Да и не редко такие объекты конструируются не руками.
Другое дело, что 40 параметров это само по себе не нормально, особенно если мы говорим про функцию.
- Слава России!
— Героям СВО Слава!
Re[3]: Передача аргументов в функцию - позиционные vs именов
От: Muxa  
Дата: 20.03.25 07:55
Оценка:
Pzz>>Ну и передай туда структуру с именованными полями.
Б>Ага, а сначала не забудь определить типы структуры.
А это определение чем-то сложнее перечисления параметров в сигнатуре функции получится?


struct f_args {
    int i;
    double d;
    char c = 0;
};
void f(f_args args) {}

int main() {
    f({.i = 1, .d = 0.5});
    return 0;
}


Мне кажется такое можно даже макросами делать.
Отредактировано 20.03.2025 8:20 Muxa . Предыдущая версия .
Re[3]: Передача аргументов в функцию - позиционные vs именованн
От: Философ Ад http://vk.com/id10256428
Дата: 20.03.25 11:02
Оценка:
Здравствуйте, Doom100500, Вы писали:

Ф>>Это тебе гарантирует

D>Ничего это не гарантирует. В любой момент можно баг словить, даже идеального( ) решарпера.

Ни разу за много лет он не пропустил ни одного места в коде, который нужно было поменять. Я руками забывал и что-то пропускал много раз. Менять сигнатуру функции лучше с помощью вот таких инструментов, а не руками.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[4]: Передача аргументов в функцию - позиционные vs именов
От: Буравчик Россия  
Дата: 20.03.25 11:04
Оценка: +1
Здравствуйте, Muxa, Вы писали:

M>
M>struct f_args {
M>    int i;
M>    double d;
M>    char c = 0;
M>};
M>void f(f_args args) {}

M>int main() {
M>    f({.i = 1, .d = 0.5});
M>    return 0;
M>}
M>


M>А это определение чем-то сложнее перечисления параметров в сигнатуре функции получится?


Конечно, это сложнее. Сравни с "правильным" вариантом:
void f(int i, double d, char c = 0) {}

int main() {
    f(i = 1, d = 0.5);
    return 0;
}
Best regards, Буравчик
Отредактировано 20.03.2025 11:07 Буравчик . Предыдущая версия .
Re[4]: Передача аргументов в функцию - позиционные vs именованн
От: Doom100500 Израиль  
Дата: 20.03.25 11:24
Оценка: :)
Здравствуйте, Философ, Вы писали:

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


Ф>>>Это тебе гарантирует

D>>Ничего это не гарантирует. В любой момент можно баг словить, даже идеального( ) решарпера.

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


Достаточно одного маленького необработанного исключения в очередном минорном обновлении инструмента чтобы долго грустить над логерами через пару билдов.
Спасибо за внимание
Re[5]: Передача аргументов в функцию - позиционные vs именованн
От: Философ Ад http://vk.com/id10256428
Дата: 20.03.25 11:49
Оценка:
Здравствуйте, Doom100500, Вы писали:

D>Достаточно одного маленького необработанного исключения в очередном минорном обновлении...


Или один раз отредактировать сигнатуру руками, положившись на что, что функцию пока никто не успел заюзать. Или один раз пропустить пару из сотни мест, где используется функция — просто потому, что глаз замылился, а вызовов много.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[6]: Передача аргументов в функцию - позиционные vs именованн
От: Doom100500 Израиль  
Дата: 20.03.25 14:16
Оценка:
Здравствуйте, Философ, Вы писали:

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


D>>Достаточно одного маленького необработанного исключения в очередном минорном обновлении...


Ф>Или... Или...


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

Безусловно есть плюсы и за позиционные. Например в функциях типа min/max нет смысла разводить многословие, но там и порядок неважен.
Спасибо за внимание
Re[5]: Передача аргументов в функцию - позиционные vs именованные
От: GarryIV  
Дата: 20.03.25 22:33
Оценка:
Здравствуйте, Enomay, Вы писали:

E>Да и не редко такие объекты конструируются не руками.

Обычно да, сериализация какая нибудь. Но в тестах вижу такое постоянно.
WBR, Igor Evgrafov
Re[5]: Передача аргументов в функцию - позиционные vs именов
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 21.03.25 12:33
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Конечно, это сложнее. Сравни с "правильным" вариантом:

Б>
Б>void f(int i, double d, char c = 0) {}

Б>int main() {
Б>    f(i = 1, d = 0.5);
Б>    return 0;
Б>}
Б>


Завернуть в макрос, делов-то
Маньяк Робокряк колесит по городу
Re[4]: Передача аргументов в функцию - позиционные vs именов
От: SkyDance Земля  
Дата: 21.03.25 15:51
Оценка:
M>А это определение чем-то сложнее перечисления параметров в сигнатуре функции получится?

Тем, что это перечисление осуществляется в другом месте (не там где функция), что затрудняет чтение. Опять же, больше лишних строчек кода.
Re: Передача аргументов в функцию - позиционные vs именованные
От: dsorokin Россия  
Дата: 21.03.25 18:15
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вот стандартная практика — как бы по порядку. Т.е. через запятую последовательно.


S>А ведь есть более умные решения: именованные аргументы функции. Если порядок аргументов изменился, то не нужно по всему коду выискивать и исправлять.


S>Какой вариант вам удобнее?


В лиспе именованные идут строго после позиционных (и опциональных). Поэтому можно сочетать оба подхода в одном вызове. Довольно удобно и добротно. Из-за этого там даже часто злоупотребляют именованными аргументами, хотя для динамики простительно.

А вот в окамле какой-то расколбас, что запомнилось после прочтения пары книг по этому языку — там просто две библиотеки, претендующие на стандартные, но с разными стилями именования аргументов. Только на окамле я почти не писал. Поэтому какого-то диссонанса от этого не испытал.

В Scala сделано неплохо, что особо не задумываешься. Такой хороший критерий. Когда сделано по уму, то особо не напрягает глаза, не бросается (как например, необходимость постоянно писать многоэтажные std::move в замыкании C++, тогда как в Rust это записывается очень кратко и по делу).

А это вы новый C# обсуждаете? Ужас, во что его превратили. Много лет не следил за этим гибридо-монстром
Re[5]: Передача аргументов в функцию - позиционные vs именов
От: rg45 СССР  
Дата: 21.03.25 19:01
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Для C++ вроде и все есть, но все жутко не удобно — ведь еще нужно писать обвязку.


Дарю лайфхак: Designated initializers

http://coliru.stacked-crooked.com/a/3c18a1b78cced9ad

struct FooParams {int a; double b = 3.14; int c; int e = 42; int f; int g; int h;};

void foo(FooParams _) {/* . . . */}

int main()
{
    foo({.a = 123, .e = 456, .h = 789});
}


P.S. Кстати говоря, такой приём даёт ещё одно преимущество — определенность в порядке инициализации параметров — строго слева направо. Тогда как порядок инициализации обычных фактических параметров функций не регламентирован.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 21.03.2025 19:34 rg45 . Предыдущая версия . Еще …
Отредактировано 21.03.2025 19:19 rg45 . Предыдущая версия .
Отредактировано 21.03.2025 19:15 rg45 . Предыдущая версия .
Отредактировано 21.03.2025 19:10 rg45 . Предыдущая версия .
Отредактировано 21.03.2025 19:05 rg45 . Предыдущая версия .
Re: Передача аргументов в функцию - позиционные vs именованные
От: gyraboo  
Дата: 21.03.25 19:04
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Какой вариант вам удобнее?


В основном на джаве пишу и за последние лет 5 прикипел душой к ломбоку. Для данной задачи там есть аннотация Builder, которая превращает дата-обьект в билдер, а его можно передавать как входной параметр или результат работы метода. Это снижает количество ошибок, связанных с перепутанными аргументами одного типа, и вообще делает код читаемее.
У билдера есть ещё одно преимущество — он защищает код от использования недостроенного объекта. Т.е. пока ты явно не вызовешь метод build(), объект как бы находится на стадии конструирования и его нельзя использовать в коде, т.к. есть только билдер, а не сам объект. Причём такой недостроенный билдер можно передавать по цепочке, не опасаясь что на какой-то промежутой стадии кто-то решить заюзать недострой.
Re[5]: Передача аргументов в функцию - позиционные vs именов
От: swame  
Дата: 21.03.25 19:26
Оценка:
Здравствуйте, Буравчик, Вы писали:

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


Б>Конечно, это сложнее. Сравни с "правильным" вариантом:

Б>[ccode]
Б>void f(int i, double d, char c = 0) {}

Когда такое нужно пробросить через несколько вложенных вызовов, то уже не сложнее.
Либо определение повторяется у методов наследников объектов.
Отредактировано 21.03.2025 19:28 swame . Предыдущая версия .
Re[2]: Передача аргументов в функцию - позиционные vs именованн
От: rameel https://github.com/rsdn/CodeJam
Дата: 22.03.25 14:32
Оценка:
Здравствуйте, netch80, Вы писали:

S>>Какой вариант вам удобнее?


N>Так, как сделано в Swift.


Если бы еще не требовал писать дискарды "_" если хочешь просто позиционные параметры, а так получается, что составитель в постоянной борьбе со своей ленью, ведь для него удобнее всегда использовать именованные, чем позиционные, хотя нужны реже.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[3]: Передача аргументов в функцию - позиционные vs именованн
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.03.25 08:32
Оценка:
Здравствуйте, rameel, Вы писали:

N>>Так, как сделано в Swift.


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


Эта добавка двух символов слишком мелкая, чтобы на что-то влиять. Но я согласен, что к этому надо выработать привычку.
The God is real, unless declared integer.
Re[4]: Передача аргументов в функцию - позиционные vs именованные
От: vdimas Россия  
Дата: 28.03.25 08:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

Pzz>>Если в функции — сорок параметров, то эту функцию надо бы порефакторить...

S>Image: convert-table-parameters.png
S>Удачи её порефакторить

Уже, вроде, устоялось, что если более 5-ти параметров, то удобнее дать интерфейс с неким объектом property-bag (Parameters, Options, Config и т.д.), который (объект) является поставщиком параметров ф-ии. Благо, вэлью-типы позволяют провернуть такой трюк относительно дешево.

Заодно это позволяет задешево декомпозировать логику подбора параметров и целевую логику их использования затем.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.