Вот проблема программирования / языка, о которой я хотел бы услышать ваши мысли.
Мы разработали соглашения, которым должно следовать большинство программистов, которые не являются частью синтаксиса языков, но служат для того, чтобы сделать код более читабельным. Это, конечно, всегда предмет спора, но есть, по крайней мере, некоторые основные концепции, которые большинство программистов считают приемлемыми. Называя ваши переменные соответствующим образом, называя в целом, делая ваши строки не слишком длинными, избегая длинных функций, инкапсуляций и тому подобного.
Однако есть проблема, которую я пока не нашел, чтобы кто-то комментировал, и это может быть самой большой проблемой. Это проблема анонимности аргументов при вызове функции.
Функции вытекают из математики, где f (x) имеет ясное значение, потому что функция имеет гораздо более строгое определение, чем обычно в программировании. Чистые функции в математике могут делать намного меньше, чем в программировании, и они являются гораздо более элегантным инструментом, они обычно принимают только один аргумент (обычно это число) и всегда возвращают одно значение (также обычно число). Если функция принимает несколько аргументов, они почти всегда являются просто дополнительными измерениями области функции. Другими словами, один аргумент не важнее других. Конечно, они явно упорядочены, но кроме этого у них нет семантического упорядочения.
Однако в программировании у нас больше свободы в определении функций, и в этом случае я бы сказал, что это не очень хорошая вещь. Распространенная ситуация, у вас есть функция, определенная следующим образом
func DrawRectangleClipped (rectToDraw, fillColor, clippingRect) {}
Глядя на определение, если функция написана правильно, совершенно ясно, что к чему. При вызове функции в вашей IDE / редакторе может даже возникнуть какая-то магия intellisense / завершения кода, которая скажет вам, каким должен быть следующий аргумент. Но ждать. Если мне это нужно, когда я на самом деле пишу звонок, неужели здесь что-то не хватает? Человек, читающий код, не имеет преимущества IDE, и, если он не перейдет к определению, он не знает, какой из двух прямоугольников, переданных в качестве аргументов, для чего используется.
Проблема идет даже дальше, чем это. Если наши аргументы получены из какой-то локальной переменной, могут быть ситуации, когда мы даже не знаем, что такое второй аргумент, поскольку видим только имя переменной. Возьмите для примера эту строку кода
DrawRectangleClipped(deserializedArray[0], deserializedArray[1], deserializedArray[2])
Это распространяется на различные степени в разных языках, но даже в строго типизированных языках, и даже если вы разумно называете свои переменные, вы даже не упоминаете тип переменной, когда передаете ее функции.
Как обычно бывает с программированием, есть много потенциальных решений этой проблемы. Многие уже реализованы на популярных языках. Именованные параметры в C # например. Однако все, что я знаю, имеет существенные недостатки. Наименование каждого параметра при каждом вызове функции не может привести к читабельности кода. Такое ощущение, что мы, возможно, перерастаем возможности, которые дает нам простое текстовое программирование. Мы перешли от текста просто в почти каждой области, но мы все еще кодируем то же самое. Нужно больше информации для отображения в коде? Добавьте больше текста. В любом случае, это становится немного тангенциальным, поэтому я остановлюсь здесь.
Один ответ, который я получил на второй фрагмент кода, заключается в том, что вы, вероятно, сначала распакуете массив для некоторых именованных переменных, а затем будете использовать их, но имя переменной может означать много вещей, и то, как она вызывается, не обязательно говорит о том, как она должна интерпретироваться в контексте вызываемой функции. В локальной области у вас может быть два прямоугольника с именами leftRectangle и rightRectangle, потому что это то, что они семантически представляют, но не нужно расширять то, что они представляют при передаче функции.
Фактически, если ваши переменные названы в контексте вызываемой функции, вы вводите меньше информации, чем могли бы с этим вызовом функции, и на некотором уровне, если это приводит к ухудшению кода. Если у вас есть процедура, результатом которой является прямоугольник, который вы сохраняете в rectForClipping, а затем другая процедура, которая обеспечивает rectForDrawing, то фактический вызов DrawRectangleClipped - просто церемония. Линия, которая не означает ничего нового и существует только для того, чтобы компьютер знал, чего именно вы хотите, даже если вы уже объяснили это с помощью имен. Это не очень хорошая вещь.
Я бы очень хотел услышать свежие взгляды на это. Я уверен, что я не первый, кто считает эту проблему проблемой, так как она решается?