La idea está inspirada en el hecho de que operadores como +, -,%, etc. se pueden ver como funciones con uno o dos argumentos aprobados y sin efectos secundarios. Suponiendo que yo, u otra persona, escriba un lenguaje que impida que se pasen más de dos argumentos, y que también solo funcione a través del valor de retorno:
a) ¿tal lenguaje conduciría a un código más fácil de entender?
b) ¿sería más claro el flujo del código? (forzado a más pasos, con potencialmente menos interacciones 'ocultas'
c) las restricciones harían que el lenguaje fuera excesivamente voluminoso para programas más complejos.
d) (bonus) cualquier otro comentario sobre pros / contras
Nota:
Todavía tendrían que tomarse dos decisiones: la primera es si se debe permitir la entrada del usuario fuera de main () o su equivalente, y también cuál será la regla con respecto a lo que sucede al pasar matrices / estructuras. Por ejemplo, si alguien quiere que una sola función agregue múltiples valores, podría sortear la limitación al agruparla en una matriz. Esto podría detenerse al no permitir que una matriz o estructura interactúe consigo misma, lo que aún le permitiría, por ejemplo, dividir cada número por una cantidad diferente, dependiendo de su posición.
result = f(a)(b)…(z)
. Este es el caso en la familia de idiomas de ML como Haskell, pero también conceptualmente en otros idiomas como Lisp, JavaScript o Perl.Respuestas:
Robert C. Martin en su libro "Clean Code" recomienda en gran medida el uso de funciones con 0, 1 o 2 parámetros como máximo, por lo que al menos hay un autor de libros experimentado que piensa que el código se vuelve más limpio al usar este estilo (sin embargo, él es seguramente no es la autoridad definitiva aquí, y sus opiniones son discutibles).
Donde Bob Martin es IMHO correcto es: las funciones con 3 o más parámetros son a menudo indicadores de un olor a código. En muchos casos, los parámetros pueden agruparse para formar un tipo de datos combinado, en otros casos, puede ser un indicador de que la función simplemente hace demasiado.
Sin embargo, no creo que sea una buena idea inventar un nuevo lenguaje para esto:
Si realmente desea aplicar una regla de este tipo en todo el código, solo necesita una herramienta de análisis de código para un lenguaje existente, no es necesario inventar un lenguaje completamente nuevo para esto (por ejemplo, para C # algo como 'fxcop' probablemente podría utilizarse )
a veces, combinar parámetros con un nuevo tipo simplemente no parece la pena, o se convertiría en una combinación artificial pura. Vea, por ejemplo, este
File.Open
método del marco .Net. Se necesitan cuatro parámetros, y estoy bastante seguro de que los diseñadores de esa API lo hicieron intencionalmente, porque pensaron que sería la forma más práctica de proporcionar los diferentes parámetros a la función.a veces hay escenarios del mundo real en los que más de 2 parámetros simplifican las cosas por razones técnicas (por ejemplo, cuando necesita una asignación 1: 1 a una API existente en la que está obligado al uso de tipos de datos simples y no puede combinar diferentes parámetros en un objeto personalizado)
fuente
Hay muchos idiomas que ya funcionan de esta manera, por ejemplo, Haskell. En Haskell, cada función toma exactamente un argumento y devuelve exactamente un valor.
Siempre es posible reemplazar una función que toma n argumentos con una función que toma n-1 argumentos y devuelve una función que toma el argumento final. Aplicando esto de forma recursiva, siempre es posible reemplazar una función que toma un número arbitrario de argumentos con una función que toma exactamente un argumento. Y esta transformación puede realizarse mecánicamente, mediante un algoritmo.
Esto se llama Frege-Schönfinkeling, Schönfinkeling, Schönfinkel-Currying, o Currying, después de Haskell Curry, quien lo investigó extensamente en la década de 1950, Moses Schönfinkel, que lo describió en 1924, y Gottlob Frege, que lo presagió en 1893.
En otras palabras, restringir el número de argumentos tiene exactamente cero impacto.
fuente
f *(call_with: a,b,c,d,e)
Sobrecargacall_with :
para comenzar una cadena,,
para extender la cadena y*
en el LHS para invocarf
pasando cada uno de los contenidos de la cadena uno a la vez. Un sistema de sobrecarga del operador suficientemente débil solo hace que la sintaxis sea engorrosa, pero esa es la falla del sistema de sobrecarga del operador más que nada.He pasado algún tiempo estas últimas semanas intentando aprender el lenguaje informático J. En J, casi todo es un operador, por lo que solo obtienes "mónadas" (funciones que tienen un solo argumento) y "díadas" (funciones con exactamente dos argumentos). Si necesita más argumentos, debe proporcionarlos en una matriz o proporcionarlos en "cuadros".
J puede ser muy conciso, pero al igual que su predecesor APL, también puede ser muy críptico, pero esto es principalmente el resultado del objetivo del creador de emular la concisión matemática. Es posible hacer que un programa J sea más legible utilizando nombres en lugar de caracteres para crear operadores.
fuente
Un lenguaje basado en cómo restringe al desarrollador depende de la suposición de que el desarrollador del lenguaje comprende las necesidades de cada programador mejor de lo que el programador entiende esas necesidades por sí mismo. Hay casos en que esto es realmente válido. Por ejemplo, muchos consideran que las restricciones en la programación multiproceso que requieren sincronización mediante mutexes y semáforos son "buenas" porque la mayoría de los programadores desconocen por completo las complejidades subyacentes específicas de la máquina que esas restricciones les ocultan. Del mismo modo, pocos desean comprender completamente los matices de los algoritmos de recolección de basura multiproceso; Se prefiere un lenguaje que simplemente no le permita romper el algoritmo GC sobre uno que obligue a un programador a ser consciente de demasiados matices.
Tendría que hacer un argumento válido de por qué, como desarrollador de lenguaje, entiende que el argumento pasa mucho mejor que los programadores que usan su lenguaje que tiene valor evitar que hagan cosas que considera perjudiciales. Creo que sería un argumento difícil de hacer.
También debe saber que los programadores evitarán sus limitaciones. Si necesitan 3 o más argumentos, utilizarán técnicas como curry para convertirlos en llamadas de menos argumentos. Sin embargo, esto a menudo conlleva el costo de la legibilidad, en lugar de mejorarlo.
La mayoría de los idiomas que conozco con este tipo de regla son esolangs, lenguajes diseñados para demostrar que puedes operar con un conjunto limitado de funcionalidades. En particular, los esolangs donde cada personaje es un código de operación tienen una tendencia a limitar el número de argumentos, simplemente porque necesitan mantener corta la lista de códigos de operación.
fuente
Necesitarás dos cosas:
Agregaré un ejemplo matemático para explicar la respuesta escrita por Jörg W Mittag .
Considera el función gaussiana .
Una función gaussiana tiene dos parámetros para su forma, a saber, la media (posición central de la curva) y la varianza (relacionada con el ancho de pulso de la curva). Además de los dos parámetros, uno también debe proporcionar el valor de la variable libre
x
para evaluarla.En el primer paso, diseñaremos una función gaussiana que tome los tres parámetros, a saber, la media, la varianza y la variable libre.
En el segundo paso, creamos un tipo de datos compuesto que combina la media y la varianza en una sola cosa.
En el tercer paso, creamos una parametrización de la función gaussiana creando un cierre de la función gaussiana vinculada al tipo de datos compuestos que creamos en el segundo paso.
Finalmente, evaluamos el cierre creado en el tercer paso al pasarle el valor de la variable libre
x
.La estructura es por lo tanto:
fuente
En casi cualquier lenguaje de programación, puede pasar algún tipo de lista, matriz, tupla, registro u objeto como único argumento. Su único propósito es mantener otros elementos en lugar de pasarlos a una función individualmente. Algunos IDE de Java incluso tienen una función de " Objeto de parámetro de extracción " para hacer precisamente eso. Internamente, Java implementa números variables de argumentos al crear y pasar una matriz.
Si realmente quieres hacer de lo que estás hablando en la forma más pura, debes mirar el cálculo lambda. Es exactamente lo que describe. Puede buscarlo en la web, pero la descripción que tenía sentido para mí estaba en Tipos y lenguajes de programación .
Mire los lenguajes de programación Haskell y ML (ML es más simple). Ambos se basan en el cálculo lambda y, conceptualmente, solo tienen un parámetro por función (si entrecierra un poco).
El ítem 2 de Josh Bloch es: "Considere un constructor cuando se enfrenta con muchos parámetros de constructor". Puede ver cuán detallado es esto , pero es una delicia trabajar con una API escrita de esta manera.
Algunos idiomas han nombrado parámetros, que es otro enfoque para hacer que las firmas de métodos enormes sean mucho más fáciles de navegar. Kotlin ha nombrado argumentos por ejemplo.
fuente