Идея вдохновлена тем фактом, что операторы фактов, такие как +, -,% и т. Д., Могут рассматриваться как функции с одним или двумя переданными аргументами, без побочных эффектов. Предполагая, что я или кто-то еще пишет язык, который останавливает передачу более двух аргументов, а также работает только через возвращаемое значение:
а) приведет ли такой язык к более легкому пониманию кода?
б) будет ли поток кода яснее? (вынуждается делать больше шагов, с потенциально меньшим количеством «скрытых» взаимодействий
c) ограничения сделали бы язык чрезмерно громоздким для более сложных программ.
d) (бонус) любые другие комментарии о плюсах / минусах
Замечания:
Два решения все еще должны быть приняты - во-первых, разрешить ли пользовательский ввод вне main () или его эквивалента, а также то, что будет правило относительно того, что происходит при передаче массивов / структур. Например, если кто-то хочет, чтобы одна функция добавила несколько значений, он мог бы обойти ограничение, связав его в массив. Это может быть остановлено, если не разрешить массиву или структуре взаимодействовать с самим собой, что позволит вам, например, разделить каждое число на различную величину, в зависимости от его положения.
result = f(a)(b)…(z)
. Это имеет место в семействе языков ML, таких как Haskell, но также концептуально в других языках, таких как Lisp, JavaScript или Perl.Ответы:
Роберт К. Мартин в своей книге «Чистый код» настоятельно рекомендует использовать функции с максимальным значением 0, 1 или 2 параметра, поэтому, по крайней мере, есть один опытный автор книги, который считает, что с помощью этого стиля код становится чище (однако он конечно, не абсолютный авторитет здесь, и его мнения спорны).
Боб Мартин, на мой взгляд, прав: функции с 3 и более параметрами часто являются индикаторами запаха кода. Во многих случаях параметры могут быть сгруппированы для формирования комбинированного типа данных, в других случаях это может быть индикатором того, что функция просто выполняет слишком много.
Однако я не думаю, что было бы хорошей идеей изобрести новый язык для этого:
если вы действительно хотите применять такое правило в своем коде, вам просто нужен инструмент анализа кода для существующего языка, для этого не нужно изобретать совершенно новый язык (например, для C # может быть использовано что-то вроде 'fxcop') ).
иногда объединение параметров с новым типом просто не стоит хлопот, иначе это станет чисто искусственной комбинацией. См., Например, этот
File.Open
метод из .Net Framework. Он принимает четыре параметра, и я уверен, что разработчики этого API сделали это намеренно, потому что они думали, что это будет наиболее практичным способом предоставления различных параметров функции.иногда существуют сценарии реального мира, в которых более 2 параметров упрощают работу по техническим причинам (например, когда вам требуется сопоставление 1: 1 с существующим API, где вы привязаны к использованию простых типов данных и не можете комбинировать разные параметры в один пользовательский объект)
источник
Есть много языков, которые уже работают таким образом, например, Haskell. В Haskell каждая функция принимает ровно один аргумент и возвращает ровно одно значение.
Всегда можно заменить функцию, которая принимает n аргументов, функцией, которая принимает n-1 аргументов и возвращает функцию, которая принимает конечный аргумент. Применяя это рекурсивно, всегда можно заменить функцию, которая принимает произвольное число аргументов, функцией, которая принимает ровно один аргумент. И это преобразование может быть выполнено механически, по алгоритму.
Это называется Фреге-Шенфинкелинг, Шёнфинкелинг, Шенфинкель-Карри или Карри, после Хаскелла Карри, который исследовал его в 1950-х годах, Моисея Шенфинкеля, который описал его в 1924 году, и Готтлоба Фреге, который предвидел его в 1893 году.
Другими словами, ограничение количества аргументов оказывает абсолютно нулевое влияние.
источник
f *(call_with: a,b,c,d,e)
перегрузкаcall_with :
для начала цепочки,,
для удлинения цепочки и*
для запуска LHSf
, передавая каждое содержимое цепочки по одному. Достаточно слабая система перегрузки операторов просто делает синтаксис обременительным, но это вина системной перегрузки операторов больше всего на свете.Последние несколько недель я проводил некоторое время, пытаясь выучить компьютерный язык J. В J почти все операторы, поэтому вы получаете только «монады» (функции, которые имеют только один аргумент) и «диады» (функции с ровно двумя аргументами). Если вам нужно больше аргументов, вы должны либо предоставить их в массиве, либо предоставить их в «ящиках».
J может быть очень кратким, но, как и его предшественник APL, он также может быть очень загадочным - но это в основном результат цели создателя подражать математической лаконичности. Можно сделать J-программу более читабельной, используя имена, а не символы для создания операторов.
источник
Язык, основанный на том, как он ограничивает разработчика, зависит от предположения, что разработчик языка понимает потребности каждого программиста лучше, чем программист сам понимает эти потребности. Есть случаи, когда это действительно допустимо. Например, ограничения на многопоточное программирование, требующие синхронизации с использованием мьютексов и семафоров, многими считаются «хорошими», поскольку большинство программистов совершенно не знают о базовых машинно-специфических сложностях, которые эти ограничения скрывают от них. Аналогичным образом, немногие хотят полностью понять нюансы многопоточных алгоритмов сборки мусора; язык, который просто не позволяет вам нарушать алгоритм GC, предпочтительнее языка, который заставляет программиста осознавать слишком много нюансов.
Вы должны были бы привести веские аргументы в пользу того, почему, как разработчик языка, вы понимаете передачу аргументов намного лучше, чем программисты, использующие ваш язык, что есть смысл в том, чтобы препятствовать им делать то, что вы считаете вредным. Я думаю, что это будет сложный аргумент.
Вы также должны знать, что программисты будут обходить ваши ограничения. Если им нужно 3 или более аргументов, они будут использовать методы, такие как карри, чтобы превратить их в вызовы с меньшим количеством аргументов. Однако это часто происходит за счет читабельности, а не улучшения.
Большинство языков, которые я знаю по этому виду правил, - это esolangs, языки, разработанные для демонстрации того, что вы действительно можете работать с ограниченным набором функций. В частности, esolangs, где каждый символ представляет собой код операции, имеет тенденцию ограничивать количество аргументов просто потому, что им необходимо сократить список кодов операций.
источник
Вам понадобятся две вещи:
Я добавлю математический пример, чтобы объяснить ответ, написанный Йоргом Миттагом .
Рассмотрим гауссову функцию .
Гауссова функция имеет два параметра для своей формы, а именно среднее (центральное положение кривой) и дисперсию (связанную с шириной импульса кривой). В дополнение к двум параметрам необходимо также указать значение свободной переменной
x
для ее оценки.На первом шаге мы разработаем гауссову функцию, которая принимает все три параметра, а именно среднее значение, дисперсию и свободную переменную.
На втором этапе мы создаем составной тип данных, который объединяет среднее значение и дисперсию в одну вещь.
На третьем шаге мы создаем параметризацию гауссовской функции, создавая замыкание гауссовской функции, связанной с составным типом данных, который мы создали на втором шаге.
Наконец, мы оцениваем замыкание, созданное на третьем шаге, передавая ему значение свободной переменной
x
.Структура поэтому:
источник
Практически на любом языке программирования вы можете передать некоторый тип списка, массива, кортежа, записи или объекта в качестве единственного аргумента. Его единственная цель - хранить другие предметы, а не передавать их функции по отдельности. Некоторые Java IDE даже имеют функцию « Извлечь объект параметров », чтобы сделать это. Внутренне Java реализует переменное число аргументов, создавая и передавая массив.
Если вы действительно хотите сделать то, о чем вы говорите, в чистом виде, вам нужно взглянуть на лямбда-исчисление. Это именно то, что вы описываете. Вы можете искать его в Интернете, но описание, которое имело смысл для меня, было в Типах и Языках программирования .
Посмотрите на языки программирования Haskell и ML (ML проще). Они оба основаны на лямбда-исчислении и концептуально имеют только один параметр для каждой функции (если вы немного щурились).
Пункт 2 Джоша Блоха: «Рассмотрим строителя, когда сталкиваемся со многими параметрами конструктора». Вы можете видеть, насколько многословно это получается , но работать с API, написанным таким образом, очень приятно.
Некоторые языки имеют именованные параметры, что является еще одним подходом, позволяющим значительно облегчить навигацию по сигнатурам больших методов. Например, Котлин назвал аргументы .
источник