L'idée est inspirée du fait que les opérateurs tels que +, -,%, etc. peuvent être considérés comme des fonctions avec un ou deux arguments passés et sans effets secondaires. En supposant que moi ou quelqu'un d'autre écrive un langage qui empêche la transmission de plus de deux arguments et ne fonctionne que via la valeur de retour:
a) un tel langage conduirait-il à un code plus facile à comprendre?
b) le flux du code serait-il plus clair? (forcé à plus d'étapes, avec potentiellement moins d'interactions cachées)
c) les restrictions rendraient-elles le langage excessivement volumineux pour des programmes plus complexes.
d) (bonus) tout autre commentaire sur le pour / le contre
Remarque:
Deux décisions devraient encore être prises - la première est de savoir si autoriser l'entrée utilisateur en dehors de main () ou son équivalent, et aussi quelle sera la règle concernant ce qui se passe lors du passage de tableaux / structures. Par exemple, si quelqu'un veut qu'une seule fonction ajoute plusieurs valeurs, il peut contourner la limitation en la regroupant dans un tableau. Cela pourrait être arrêté en n'autorisant pas un tableau ou une structure à interagir avec lui-même, ce qui vous permettrait toujours, par exemple, de diviser chaque nombre par un montant différent, selon sa position.
result = f(a)(b)…(z)
. C'est le cas dans la famille de langages ML comme Haskell, mais aussi conceptuellement dans d'autres langages comme Lisp, JavaScript ou Perl.Réponses:
Robert C. Martin dans son livre "Clean Code" recommande fortement l'utilisation de fonctions avec 0, 1 ou 2 paramètres au maximum, donc au moins un auteur de livre expérimenté pense que le code devient plus propre en utilisant ce style (cependant, il est sûrement pas l'autorité ultime ici, et ses opinions sont discutables).
Là où Bob Martin est correct à mon humble avis: les fonctions avec 3 paramètres ou plus sont souvent des indicateurs d'une odeur de code. Dans de nombreux cas, les paramètres peuvent être regroupés pour former un type de données combiné, dans d'autres cas, cela peut être un indicateur pour la fonction qui en fait simplement trop.
Cependant, je ne pense pas que ce serait une bonne idée d'inventer un nouveau langage pour cela:
si vous voulez vraiment appliquer une telle règle dans tout votre code, vous avez juste besoin d'un outil d'analyse de code pour un langage existant, pas besoin d'inventer un tout nouveau langage pour cela (par exemple, pour C # quelque chose comme 'fxcop' pourrait probablement être utilisé ).
Parfois, combiner des paramètres à un nouveau type ne semble pas valoir la peine, ou cela deviendrait une pure combinaison artificielle. Voir, par exemple, cette
File.Open
méthode du framework .Net. Cela prend quatre paramètres, et je suis presque sûr que les concepteurs de cette API l'ont fait intentionnellement, car ils pensaient que ce serait le moyen le plus pratique de fournir les différents paramètres à la fonction.il existe parfois des scénarios du monde réel où plus de 2 paramètres simplifient les choses pour des raisons techniques (par exemple, lorsque vous avez besoin d'un mappage 1: 1 avec une API existante où vous êtes lié à l'utilisation de types de données simples et ne pouvez pas combiner différents paramètres dans un objet personnalisé)
la source
Il existe de nombreuses langues qui fonctionnent déjà de cette façon, par exemple Haskell. Dans Haskell, chaque fonction prend exactement un argument et renvoie exactement une valeur.
Il est toujours possible de remplacer une fonction qui prend n arguments par une fonction qui prend n-1 arguments et renvoie une fonction qui prend l'argument ultime. En appliquant ceci récursivement, il est toujours possible de remplacer une fonction qui prend un nombre arbitraire d'arguments par une fonction qui prend exactement un argument. Et cette transformation peut être effectuée mécaniquement, par un algorithme.
C'est ce qu'on appelle Frege-Schönfinkeling, Schönfinkeling, Schönfinkel-Currying ou Currying, après Haskell Curry qui l'a longuement étudié dans les années 1950, Moses Schönfinkel, qui l'a décrit en 1924, et Gottlob Frege, qui l'a préfiguré en 1893.
En d'autres termes, la restriction du nombre d'arguments n'a aucun impact.
la source
f *(call_with: a,b,c,d,e)
surchargecall_with :
pour commencer une chaîne,,
pour étendre la chaîne et*
sur le LHS pour l'invoquerf
en lui passant chacun des contenus de la chaîne un par un. Un système de surcharge d'opérateur suffisamment faible rend la syntaxe compliquée, mais c'est la faute du système de surcharge d'opérateur plus que tout.J'ai passé du temps ces dernières semaines à essayer d'apprendre le langage informatique J. En J, presque tout est un opérateur, donc vous n'obtenez que des "monades" (fonctions qui n'ont qu'un seul argument) et des "dyades" (fonctions avec exactement deux arguments). Si vous avez besoin de plus d'arguments, vous devez soit les fournir dans un tableau, soit les fournir dans des "boîtes".
J peut être très concis, mais comme son prédécesseur APL, il peut également être très cryptique - mais cela est principalement le résultat de l'objectif du créateur d'émuler la concision mathématique. Il est possible de rendre un programme J plus lisible en utilisant des noms plutôt que des caractères pour créer des opérateurs.
la source
Un langage basé sur la façon dont il contraint le développeur dépend de l'hypothèse que le développeur du langage comprend mieux les besoins de chaque programmeur que le programmeur ne comprend eux-mêmes ces besoins. Il y a des cas où cela est réellement valable. Par exemple, les contraintes sur la programmation multithread nécessitant une synchronisation à l'aide de mutex et de sémaphores sont considérées par beaucoup comme «bonnes» car la plupart des programmeurs ignorent complètement les complexités sous-jacentes spécifiques à la machine que ces contraintes leur cachent. De même, peu souhaitent saisir pleinement les nuances des algorithmes de récupération de place multithread; un langage qui ne vous permet tout simplement pas de casser l'algorithme GC est préféré à celui qui oblige un programmeur à être conscient de trop de nuances.
Vous devriez avoir un argument valable pour expliquer pourquoi, en tant que développeur de langage, vous comprenez l'argument passant tellement mieux que les programmeurs utilisant votre langage qu'il est utile de les empêcher de faire des choses que vous jugez nuisibles. Je pense que ce serait un argument difficile à faire valoir.
Vous devez aussi savoir que les programmeurs vont travailler autour de vos contraintes. S'ils ont besoin de 3 arguments ou plus, ils utiliseront des techniques comme le curry pour les transformer en appels à moins d'arguments. Cependant, cela se fait souvent au détriment de la lisibilité, plutôt que de l'améliorer.
La plupart des langues que je connais avec ce type de règle sont des esolangs, des langues conçues pour démontrer que vous pouvez en effet fonctionner avec un ensemble limité de fonctionnalités. En particulier, les esolangs où chaque caractère est un opcode ont tendance à limiter le nombre d'arguments, simplement parce qu'ils doivent garder la liste des opcodes courte.
la source
Vous aurez besoin de deux choses:
J'ajouterai un exemple mathématique pour expliquer la réponse écrite par Jörg W Mittag .
Considérons la fonction gaussienne .
Une fonction gaussienne a deux paramètres pour sa forme, à savoir la moyenne (position centrale de la courbe) et la variance (liée à la largeur d'impulsion de la courbe). En plus des deux paramètres, il faut également fournir la valeur de la variable libre
x
afin de l'évaluer.Dans un premier temps, nous concevrons une fonction gaussienne qui prend les trois paramètres, à savoir la moyenne, la variance et la variable libre.
Dans la deuxième étape, nous créons un type de données composite qui combine la moyenne et la variance en une seule chose.
Dans la troisième étape, nous créons une paramétrisation de la fonction gaussienne en créant une fermeture de la fonction gaussienne liée au type de données composite que nous avons créé dans la deuxième étape.
Enfin, nous évaluons la fermeture créée à la troisième étape en lui passant la valeur de la variable libre
x
.La structure est donc:
la source
Dans à peu près n'importe quel langage de programmation, vous pouvez passer un certain type de liste, tableau, tuple, enregistrement ou objet comme seul argument. Son seul but est de contenir d'autres éléments au lieu de les transmettre individuellement à une fonction. Certains IDE Java ont même une fonction " Extraire un objet de paramètre " pour cela. En interne, Java implémente un nombre variable d'arguments en créant et en passant un tableau.
Si vous voulez vraiment faire ce dont vous parlez sous la forme la plus pure, vous devez regarder le calcul lambda. C'est exactement ce que vous décrivez. Vous pouvez le rechercher sur le Web, mais la description qui me paraissait logique était dans Types et langages de programmation .
Regardez les langages de programmation Haskell et ML (ML est plus simple). Ils sont tous deux basés sur le calcul lambda et n'ont conceptuellement qu'un seul paramètre par fonction (si vous plissez les yeux un peu).
Le point 2 de Josh Bloch est: "Considérez un constructeur face à de nombreux paramètres de constructeur." Vous pouvez voir à quel point cela est détaillé , mais c'est un plaisir de travailler avec une API écrite de cette façon.
Certains langages ont nommé des paramètres, ce qui est une autre approche pour faciliter la navigation dans les énormes signatures de méthode. Kotlin a nommé des arguments par exemple.
la source