IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langages de programmation Discussion :

Y a-t-il une raison pour laquelle les fonctions ne retournent qu'une seule valeur ?


Sujet :

Langages de programmation

  1. #61
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Uther Voir le message
    Les langages somme le C permettent bien de retourner des structures plus grosses qu'un registre.
    "retourner" une instance d'une "structure" (structure de donnée ou "struct" ?), et donc un pointeur (en c et c++ par exemple) ou une référence (en c++, delphi, java ou c#...), bien qu'au final en réalité ce soit la même chose i.e. l'adresse de la donnée, la notion de référence en langage évolué permettant de travailler apparemment du point de vue de l'écriture avec la donnée sans considération de pointeur dont la gestion est effectué par le compilateur.

    la différence entre la référence d'instance de "struct" et de "class", comme en c#, étant le fait que la manipulation des objets de classe se fait par la référence (i.e. le pointeur) lors des passages de paramètres tandis que les objets de structure sont copiée en entier (cloning), c'est à dire qu'une donnée instance de "struct" et non pas de "class" qui par exemple contient 3 valeurs entières encapsulées va au lieu de nécessiter un dword (en x32) de pointeur (pour un pointeur d'objet de classe), 3 dword (int). donc au lieu de passer dans la pile un int, on en passe 3.

    http://cpp.developpez.com/cours/cpp/?page=page_6

    https://fr.wikipedia.org/wiki/Pointeur_(programmation)

    https://fr.wikipedia.org/wiki/Référence_(programmation)

    Choosing Between Class and Struct

  2. #62
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    27 239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 239
    Points : 40 995
    Points
    40 995
    Par défaut
    @anonyme, dans chacun de tes posts il y a un truc soit inexact, soit hors-sujet et/ou qu'on sait déjà...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #63
    Membre chevronné
    Inscrit en
    janvier 2006
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : janvier 2006
    Messages : 629
    Points : 2 190
    Points
    2 190
    Par défaut
    Citation Envoyé par anonyme Voir le message
    La réponse au sujet, qui ouvrait la réflexion, est simple et a été donnée. Elle est structurelle inhérente à l'architecture des microprocesseurs et d'une manière générale c'est pareil pour la quasi-majorité des processeurs de l'ère actuelle.
    Certainement pas. D'ailleurs tu apportes même un contre-exemple dans la suite de ton commentaire : tous les processeurs actuels, tous les langages "machine", fonctionnent avec des goto et pourtant ô miracle, la majorité des langages de haut niveau se font un malin plaisir à ne pas l'utiliser. Alors je ne vois pas pourquoi une contrainte de bas niveau viendrait perturber durablement tous les langages proches du raisonnement humain : la machine est construite par l'homme pour s'adapter à lui, et non l'inverse. Alors si une contrainte technique peut temporairement se répercuter sur les langages de programmation, ça finit toujours par disparaître (regarde comment on gérait la mémoire en C il y a 20 ans et maintenant...)

    Donc je résume mon propos précédent, si les fonctions ne retournent qu'une seule valeur c'est parce que :
    1. La majorité des appels de fonction (je parle bien de l'appel, pas de la déclaration) ne sont pas terminaux, c'est à dire qu'ils interviennent dans une expression plus complexe
    2. Renvoyer plusieurs valeurs revient de fait à renvoyer un tuple ou une structure, et alors il faut soit
      • passer par des variables intermédiaires, ce qui fait du code en plus
      • créer des opérateurs pour séparer les composantes, et alors on perd la simplicité que les résultats multiples étaient supposés apporter


  4. #64
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    @anonyme, dans chacun de tes posts il y a un truc soit inexact, soit hors-sujet et/ou qu'on sait déjà...
    ?

  5. #65
    Invité
    Invité(e)
    Par défaut
    https://en.wikipedia.org/wiki/X86_instruction_listings

    par exemple pour les processeurs intel x86 comme dans 8086, on a :

    MOV: affectation d'une valeur à un registre ou à une cellule mémoire
    ADD/SUB/MUL/DIV/AND/NOT...: calcul élémentaire et binaire
    PUSH/POP: empile, dépile dans la stack cpu
    JMP et J(cc): goto simple et goto sous condition (égal, non égal, flag...)
    CALL: appel de procédure (un JMP avec push spécial de l'adr de retour)
    RET: retour de procédure (un JMP à l'adr d'origine + 1 via pop spécial)
    les opcodes des "instructions assembleur" sont la seule chose que comprend un cpu, rien d'autre.
    https://en.wikipedia.org/wiki/Opcode

    tous les autres langages ne sont que des constructions par dessus comme avec des briques.
    https://fr.wikipedia.org/wiki/Histoi..._programmation

    ainsi, appeler une méthode d'une instance de type générique construit fermé n'est rien d'autre qu'un CALL/RET :

    var value = (new Machin<Truc>()).Bidule(chose);
    une fois traduit par le compilateur, n'est rien d'autre que :

    PUSH chose (ou utilisation de MOV ebx, chose)
    CALL adrdest (bidule)
    POP value (ou utilisation de MOV value, eax)
    dans la procedure (function et procedure sont pareil en asm), on a :

    POP chose
    [traitement]
    PUSH value (ou utilisation de MOV eax, value)
    RET (adrorg ayant appelé bidule)
    la programmation de base moderne de l'ère intel, c'est ça et seulement ça.

    mais si on sait déjà ces choses et que ce que je dis est erroné... faut savoir qu'un ordinateur n'exécute ni du c, ni du c++, ni du c#, ni du python, ni du perl, ni du haskell, ni du php ou autre, mais seulement du langage machine i.e., par défaut raccourci de langage humain, de l'assembleur.
    Dernière modification par Invité ; 18/09/2015 à 01h32. Motif: corrections de rédaction

  6. #66
    Invité
    Invité(e)
    Par défaut Pour rire
    Voici une petite énigme aussi comique que véridique, posée à la fin d'un débat sur la différence entre Java/C++/Delphi au sujet de la notion de langage pur orienté objet.

    C++ c'est pas du vrai objet, en java qui est pur objet, tout dérive de Object.
    Ok, donc la classe Object, elle dérive de quoi ?
    De Object.
    Stack overflow
    Dernière modification par Invité ; 18/09/2015 à 02h12.

  7. #67
    Expert confirmé
    Inscrit en
    avril 2008
    Messages
    2 545
    Détails du profil
    Informations personnelles :
    Âge : 62

    Informations forums :
    Inscription : avril 2008
    Messages : 2 545
    Points : 4 351
    Points
    4 351
    Par défaut
    Tomlev
    Vu comme ça, la grande majorité des features des langages de haut niveau sont du sucre syntaxique
    C'est pour te reprendre du miel syntaxique !!!

    J'en reviens pour ma part à l'aspect conceptuel de la pile qui me parait plus important... et la pile n'est pas toujours celle du hardware mais une pile software...
    Je sais comment marche une pile, ce n'était pas la question. Ce que je disais est que rien n’empêche de pousser la valeur de retour sur la pile elle aussi, donc l'argument de la limitation a un seul registre ne tient pas vraiment. D'ailleurs les langages somme le C permettent bien de retourner des structures plus grosses qu'un registre.
    Sur le plan pratique la pile possede une taille fixe ,allouee par le systeme ....
    Ains en-est-il de la pile de thread ,puisque un thread est l'unite de code executable de base dans Windows....
    Là c'est une pile SOFTWARE, et pour cela que j'ai parle d'aspect conceptuel dans le post initial.....

    Evidemment cette pile de BAS NIVEAU SYSTEME n'est pas la pile du language machine X86 -CE BAS NIVEAU c'est plutot le DERNIER SOUS-SOL en programmation - et rien n'empeche de s'octroyer une taille de pile DAS KOLLOSSAL...!!!
    On voit que le concept de pile est implemente meme en language machine....
    Les pointeures eux-memes ne sont qu'une variants de structures recursives ....

  8. #68
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2004
    Messages : 19 875
    Points : 39 710
    Points
    39 710
    Par défaut
    Citation Envoyé par anonyme Voir le message
    une fonction s'appelle elle-même à l'infini ? "STACK OVERFLOW" !
    Pas forcément. De nombreux langages, et notamment la plupart des langages fonctionnels (que tu sembles mépriser pour une raison qui m'échappe) supportent la récursion terminale (tail recursion), qui permet, pour peu que la fonction soit bien écrite, de réutiliser le même espace sur la pile que l'appel précédent. En quelque sorte, la récursion est automatiquement transformée en itération.

    .NET supporte ça avec le modifieur tail. en IL, qui n'est malheureusement pas utilisé par le compilateur C# (mais on peut tricher). Par contre, même sans ce modifieur, le JIT 64-bits est capable de déterminer qu'une fonction est éligible à la récursion terminale, et le fait tout seul dans le code exécutable généré.

  9. #69
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    Sur le plan pratique la pile possede une taille fixe ,allouee par le systeme ....Ains en-est-il de la pile de thread ,puisque un thread est l'unite de code executable de base dans Windows....Là c'est une pile SOFTWARE, et pour cela que j'ai parle d'aspect conceptuel dans le post initial.....Evidemment cette pile de BAS NIVEAU SYSTEME n'est pas la pile du language machine X86 -CE BAS NIVEAU c'est plutot le DERNIER SOUS-SOL en programmation - et rien n'empeche de s'octroyer une taille de pile DAS KOLLOSSAL...!!! On voit que le concept de pile est implemente meme en language machine.... Les pointeures eux-memes ne sont qu'une variants de structures recursives ....
    y a pas moyen...

    y a deux genre de pile : pile cpu et pile data.

    quand au pointeurs, y a aucune "variante de structure récursive", un pointeur est un nombre entier, un uint ou un ulong selon l'architecture processeur, u pour unsigned, qui indique l'adresse d'une case mémoire, par exemple 0x12345678 en 32bits, d'où on dit que en 32bits on peut adresser que 4GB et en 64bits : 18 446 744 073 709 551 616 octets. la ram n'est en effet qu'un array linéraire et tout autre point de vue n'est qu'artéfact matriciel, même la 2D ou la 3D et les objets.

    la pile cpu est une structure matérielle intrinsèque et inhérente à la structure physique du processeur pour son fonctionnement.

    il n'y a pas d'implémentation assembleur ou langage machine ou windows ou autre, elle est implémentée par le fondeur.
    https://fr.wikipedia.org/wiki/Microprocesseur

    "Architecture x86. Dans l'architecture x86 32 bits, le registre ESP sert à indiquer l'adresse du sommet d'une pile dans la RAM. Les opcodes "push" et "pop" permettent respectivement d'empiler et de désempiler des données. Les opcodes "call" et "ret" utilisent la pile pour appeler une fonction et la quitter par la suite en retournant à l'instruction suivant immédiatement l'appel. En cas d'interruption, les registres EFLAGS, CS et EIP sont automatiquement empilés. Dans le cas d'un changement de niveau de priorité lors de l'interruption, les registres SS et ESP le sont aussi. Une autre pile existe dans les CPU x86, celle de l'unité de calcul flottant (FPU). Plus précisément, cette unité utilise une pile limitée à 8 éléments, et dont le fonctionnement s’apparente à un barillet. L’élément du barillet courant est nommé st(0), les éléments suivants st(N) avec N compris entre 1 et 7. Cette pile permet d'effectuer des calculs à la manière d'une calculatrice manuelle, en empilant les valeurs, puis en appliquant une opération sur les dernières valeurs empilées par exemple."

    https://fr.wikipedia.org/wiki/Pile_(informatique)

    https://en.wikibooks.org/wiki/X86_Disassembly/The_Stack

    la pile data ou algorithmique de traitement des données du logiciel qui n'a rien à voir du tout avec les piles gérées par le cpu via les registres EBP (proc local stack frame for local data), ESP (stack pointer) et EIP (index pointer for proc call)

    exemple : class Stack<T>
    https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx

    ainsi, lorsque j'ai parlé de la notion de pile en parlant du cpu pour expliquer pourquoi originellement les fonctions retournent une seule valeur en expliquant l'histoire de eax et de push et pop, et en montrant que les évolutions des langages dits évolués se faisaient sur une base assez statique, c'était pour dire que la question revenait à demander comment évolue la pensée humaine vis à vis de la programmation et du traitement des données conceptuelles.

    quand j'ai vu le sujet, j'ai pensé que pour discuter du passage et du renvoie des paramètres et des resultats, il fallait savoir d'où ça venait pour voir où ça va.
    Dernière modification par E.Bzz ; 16/09/2016 à 14h50.

  10. #70
    Membre chevronné
    Inscrit en
    janvier 2006
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : janvier 2006
    Messages : 629
    Points : 2 190
    Points
    2 190
    Par défaut
    Citation Envoyé par anonyme Voir le message
    les liens c'est fait pour quoi ? pour argumenter...
    Elle est bien bonne celle-là : en gros, une série d'invectives suivie de liens sans contexte (tu ne dis nulle part à quelle partie de l'article sur lequel tu pointes tu t'appuies) constituent une argumentation? Moi j'appelle plutôt ça du trollage mais bon...

    Mais soit, tu veux jouer à ça? Alors dans un des articles sur lequel tu fais un lien il est écrit :

    Avec le temps, de nouveaux langages de programmation sont apparus, faisant de plus en plus abstraction du matériel sur lequel devaient tourner les programmes.
    En clair, les premiers langages sont proches de la machine puis on s'en éloigne petit à petit. Et c'est là qu'intervient l'histoire des goto : omniprésents dans les vieux BASIC et COBOL, mais presque inexistants dans les langages modernes. Du coup, un argument utilisant le fonctionnement de la machine (comme la taille des registres) pour justifier une contrainte sur un langage de programmation (dans notre cas, le retour d'une valeur unique), ça marche quand on parle d'un vieux compilateur mais si cette possibilité apporte réellement quelque chose, alors il apparait rapidement quelques langages qui la proposent et en cas de succès, tous se sentent obligés de l'adopter.

    Sauf que dans le cas du retour multiple de fonction, cela apporte certes une facilité dans certains cas, mais aussi de nouveaux problèmes pour lesquels il existe de nombreuses solutions mais aucune qui fasse consensus. Des langages qui retournent plusieurs valeurs pour une fonction j'en connais quelques-uns, mais rien qu'entre Perl et Go par exemple les solutions apportées sont totalement différentes, c'est pourquoi ça reste des exemples isolés.

    En plus l'argument de la taille des registres tombe à l'eau quand on sait que même C, qui est généralement considéré comme proche de la machine, autorise comme valeur de retour des structures dont la taille est bien supérieure à celle des registres. Et comme tu le reconnais toi-même dans un post ultérieur, dans ce cas on fait bien une copie intégrale de la structure, on ne renvoie pas un pointeur.

  11. #71
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Pas forcément. De nombreux langages, et notamment la plupart des langages fonctionnels (que tu sembles mépriser pour une raison qui m'échappe) supportent la récursion terminale (tail recursion), qui permet, pour peu que la fonction soit bien écrite, de réutiliser le même espace sur la pile que l'appel précédent. En quelque sorte, la récursion est automatiquement transformée en itération.

    .NET supporte ça avec le modifieur tail. en IL, qui n'est malheureusement pas utilisé par le compilateur C# (mais on peut tricher). Par contre, même sans ce modifieur, le JIT 64-bits est capable de déterminer qu'une fonction est éligible à la récursion terminale, et le fait tout seul dans le code exécutable généré.


    tail ou pas tail, c'est un freeze du thread...

    le compilateur C# utilise quoi pour compiler le code C# ?


  12. #72
    Invité
    Invité(e)
    Par défaut En français et en citation sans trolls ni gobelins
    https://fr.wikipedia.org/wiki/Compilateur

    Un compilateur est un programme informatique qui transforme un code source écrit dans un langage de programmation (le langage source) en un autre langage informatique (le langage cible).

    Pour qu'il puisse être exploité par la machine, le compilateur traduit le code source, écrit dans un langage de haut niveau d'abstraction, facilement compréhensible par l'humain, vers un langage de plus bas niveau, un langage d'assemblage ou langage machine. Dans le cas de langage semi-compilé (ou semi-interprété), le code source est traduit en un langage intermédiaire, sous forme binaire (code objet ou bytecode), avant d'être lui-même interprété ou compilé.

    Inversement, un programme qui traduit un langage de bas niveau vers un langage de plus haut niveau est un décompilateur.

    Un compilateur effectue les opérations suivantes : analyse lexicale, pré-traitement (préprocesseur), analyse syntaxique (parsing), analyse sémantique, génération de code et optimisation de code.
    Historique

    Les logiciels des premiers ordinateurs étaient écrits en langage assembleur1. Les langages de programmation de plus haut niveau (dans les couches d'abstraction) n'ont été inventés que lorsque les avantages apportés par la possibilité de réutiliser le logiciel sur différents types de processeurs sont devenus plus importants que le coût de l'écriture d'un compilateur. La capacité de mémoire très limitée des premiers ordinateurs a également posé plusieurs problèmes techniques dans le développement des compilateurs.
    https://fr.wikipedia.org/wiki/Langage_de_haut_niveau

    En programmation informatique, un langage de haut niveau est un langage de programmation orienté autour du problème à résoudre, qui permet d'écrire des programmes en utilisant des mots usuels des langues naturelles (très souvent de l'anglais) et des symboles mathématiques familiers. Un langage de haut niveau fait abstraction des caractéristiques techniques du matériel utilisé pour exécuter le programme, tels que les registres et les drapeaux du processeur1,2.

    Les langages de haut niveau sont plus proches des langues naturelles, ce qui facilite et vulgarise l'écriture des programmes. Ils sont généralement indépendants de la machine : le même programme pourra être utilisé tel quel sur plusieurs types d'ordinateurs — quoique les programmes puissent également être conçus pour un système d'exploitation en particulier3.

    Les langages de haut niveau sont apparus au début des années 1960. Ils ont permis d'écrire des programmes d'une manière plus familière, proche de l'anglais, et qui ne dépend pas du processeur qui sera utilisé4.

    En 2010, il existe plus de 200 langages de programmation de haut niveau. Les plus populaires sont Pascal, Java, Fortran, COBOL, OCaml et Python1.
    Caractéristiques

    Le terme « langage de haut niveau » n'implique pas que ce type de langage soit supérieur à un langage de bas niveau. La notion de profondeur désigne la distance du langage par rapport au travail de la machine. Le langage de haut niveau a un plus haut niveau d'abstraction que les langages machines. Plutôt que de s'occuper des registres, des accès mémoires et des piles, les langages de haut niveau s'occupent de concepts plus élaborés tels que les processus légers, verrous, objets, variables, tableaux, arithmétique complexe et expressions booléennes. De plus, ils n'ont en général pas la possibilité de s'occuper des détails liés à la machine tels que la gestion mémoire contrairement aux langages de bas niveau ou alors ces langages font appels à des fonctions préprogrammées (comme les instructions new et delete en C++). D'autres caractéristiques telles que des routines de manipulation de chaîne de caractères ou les concepts des langages objets peuvent être présentes.

  13. #73
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2004
    Messages : 19 875
    Points : 39 710
    Points
    39 710
    Par défaut
    Citation Envoyé par anonyme Voir le message
    tail ou pas tail, c'est un freeze du thread...
    Quel rapport ? Je répondais à ton affirmation selon laquelle "récursion infinie = stack overflow"

    Citation Envoyé par anonyme Voir le message
    le compilateur C# utilise quoi pour compiler le code C# ?
    Je vois pas non plus le rapport, mais je peux te répondre quand même...
    Les premières versions du compilateur (1 à 5) étaient en C/C++
    Le compilateur C# 6 (aka Roslyn) est écrit en C#

  14. #74
    Membre chevronné
    Inscrit en
    janvier 2006
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : janvier 2006
    Messages : 629
    Points : 2 190
    Points
    2 190
    Par défaut
    Citation Envoyé par anonyme Voir le message
    "Invective (Wiktionary) : Parole ou suite de paroles violentes et injurieuses contre quelqu’un ou contre quelque chose."

    ça sert à rien de discuter avec ceux qui savent rien, [...] je peux pas mieux faire sinon de recommander d'aller suivre des cours à l'école.
    Donc pour toi conseiller à tous ceux qui ne sont pas d'accord avec toi de retourner à l'école n'a rien d'une invective et est parfaitement digne d'un forum professionnel. Dont acte.
    L'hurluberlu, lui, tentera de rester plus constructif. Combien de temps y parviendra-t-il...

    Citation Envoyé par anonyme Voir le message
    désolé de mettre à bas les croyances de certains : un appel de méthode super méga évolué, n'est rien d'autre au final lors de l'exécution, qu'un GOTO/RETURN entouré d'un PUSH/POP des données.
    Ce qui prouve bien que tu n'as rien compris à ce que j'écris : je n'ai jamais affirmé le contraire. Ce que je dis, c'est que le but d'une fonction ou d'une méthode est de faire abstraction de ces questions techniques pour permettre au programmeur de se concentrer sur la logique métier plutôt que sur la gestion des ressources matérielles.

    En programmation informatique, un langage de haut niveau est un langage de programmation orienté autour du problème à résoudre, qui permet d'écrire des programmes en utilisant des mots usuels des langues naturelles (très souvent de l'anglais) et des symboles mathématiques familiers. Un langage de haut niveau fait abstraction des caractéristiques techniques du matériel utilisé pour exécuter le programme, tels que les registres et les drapeaux du processeur1,2.
    Tiens, c'est dommage c'est cette citation que j'aurais dû faire, elle va encore plus dans le sens de ce que je dis: comme la notion de valeur de retour est un concept pour les langages de haut niveau (alors que l'assembleur ne connait que la notion de pile), alors la notion de fonction avec plusieurs valeurs de retour est aussi une notion à haut niveau d'abstraction.
    Donc, si renvoyer plusieurs valeurs a un sens pour le programmeur, cela contribue à cette abstraction et donc un compilateur peut le proposer. Dire que c'est impossible pour des questions de taille de registre alors qu'un compilateur C peut parfaitement renvoyer un "struct" de plusieurs centaines d'octets comme valeur de retour, ce que tu reconnais plus loin, ce n'est ni plus ni moins que te contredire toi-même.
    En réalité si peu de langages renvoient des tuples comme retour de fonction, c'est parce qu'il n'y a pas consensus sur ce qu'est un tuple et quels opérateurs sont utilisables sur eux, de sorte que deux langages qui les proposent n'offrent pas forcément la même logique sous-jacente.

  15. #75
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par esperanto Voir le message
    Donc pour toi conseiller à tous ceux qui ne sont pas d'accord avec toi de retourner à l'école n'a rien d'une invective et est parfaitement digne d'un forum professionnel.
    Je conseille ça à ceux qui disent des âneries et qui refusent de considérer les preuves relatives à la réalité commune comme justes qu'elles soient adaptées ou inadaptées.

    Citation Envoyé par esperanto Voir le message
    Ce que je dis, c'est que le but d'une fonction ou d'une méthode est de faire abstraction de ces questions techniques pour permettre au programmeur de se concentrer sur la logique métier plutôt que sur la gestion des ressources matérielles.
    Dis comme ça, presque ok, mais relis tes posts. En fait, c'est le but du langage évolué et surtout en orienté objet.

    Citation Envoyé par esperanto Voir le message
    si renvoyer plusieurs valeurs a un sens pour le programmeur, cela contribue à cette abstraction et donc un compilateur peut le proposer. Dire que c'est impossible pour des questions de taille de registre alors qu'un compilateur C peut parfaitement renvoyer un "struct" de plusieurs centaines d'octets comme valeur de retour, ce que tu reconnais plus loin, ce n'est ni plus ni moins que te contredire toi-même.
    Je n'ai pas dit que c'était impossible, j'ai expliqué comment fonctionne le moteur, la mécanique réelle sur laquelle se base la virtuelle, et qu'au final, peu importe la profondeur d'abstraction, le moteur va faire ce que j'ai dit qu'il fait, et c'est pas moi qui le dit c'est le fondeur. Donc si on est pas d'accord avec ça, j'y suis pour rien. Je vais pas répéter ni reformuler une cinquième fois, sinon en disant que si tu renvoie un struct d'une centaine de valeurs, ton compilateur gère à ta place, pour ainsi dire, le pop de 100 cases mémoires... donc tu gagnes tu temps. C'est pour ça qu'un tel struct lourd y vaut mieux une classe, défaut de langage, y vaut mieux une instance de classe que de struct, qui sera donc qu'un pointeur soit un seul int.

    L'ADN avec 4 bases azotées et quelques lois de configuration spatiale, il fabrique un corps. Un processeur et les langages, c'est un peu pareil, avec quelques opcodes, on fait des choses remarquables et merveilleuses qui sont parfois utiles et parfois non en raison du libre arbitre.

    Citation Envoyé par esperanto Voir le message
    En réalité si peu de langages renvoient des tuples comme retour de fonction, c'est parce qu'il n'y a pas consensus sur ce qu'est un tuple et quels opérateurs sont utilisables sur eux, de sorte que deux langages qui les proposent n'offrent pas forcément la même logique sous-jacente.
    La notion de Tuple est conceptuelle. Un Tuple, c'est une classe ou un struct comme les autres...
    https://fr.wikipedia.org/wiki/N-uplet

  16. #76
    Membre chevronné
    Inscrit en
    janvier 2006
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : janvier 2006
    Messages : 629
    Points : 2 190
    Points
    2 190
    Par défaut
    Citation Envoyé par anonyme Voir le message
    Je n'ai pas dit que c'était impossible,
    Tu as dit qu'il y avait une raison inhérente à l'architecture des microprocesseurs, donc tu sous-entends bien une contrainte technique plutôt que conceptuelle.


    Citation Envoyé par anonyme Voir le message
    La notion de Tuple est conceptuelle. Un Tuple, c'est une classe ou un struct comme les autres...
    https://fr.wikipedia.org/wiki/N-uplet
    Pas mal, sauf que dans cette page il manque une chose très importante : les opérateurs. Le seul opérateur que cette page définit est celui d'égalité. Il manque celui permettant d'extraire une valeur du tuple, et c'est là que je dis qu'il n'y a pas consensus : faut-il voir le tuple comme un tableau où les données sont nommées [0] [1] et [2], ou comme des coordonnées .x .y et .z? Comment transférer un tuple à une fonction prenant plusieurs paramètres? ça non plus ton lien ne le dit pas. Et sur ces deux questions, les langages autorisant le renvoi d'un tuple ont des réponses différentes.
    Ce qui montre bien qu'à la question "pourquoi une fonction ne renvoie pas plusieurs valeurs", il y a bien une raison conceptuelle: il existe plusieurs types de tuples (tableaux indicés, structures statiques, structures dynamiques...) et au final renvoyer plusieurs valeurs revient à renvoyer l'une d'entre elles, ce que les langages de haut niveau permettent déjà.

  17. #77
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par esperanto Voir le message
    Tu as dit qu'il y avait une raison inhérente à l'architecture des microprocesseurs, donc tu sous-entends bien une contrainte technique plutôt que conceptuelle.
    Exactement.

    Contrainte historiquement structurelle en vigueur.

    Il n'y a aucun sous-entendu.

    Au début, après les manivelles et les cartes perforées, les programmeurs avaient le langage machine, puis l'assembleur, puis les choses comme le C et le Basic, etc.

    Et alors ils ont imaginé des concepts et des façons de faire à l'aide des briques du fondement pour faire plus simplement et plus rapidement.

    C'est ce qu'on appelle l'évolution des technologies de programmation soumise à la loi de la productivité et de la volonté d'amélioration.

    Avant un instant donné, on pense pas à faire une chose d'une certaine manière, puis quelqu'un se dit ça serait bien de pouvoir faire comme ceci ou comme cela, et lorsque c'est faisable à l'aide des briques de base, il le fait, et si c'est utile et souhaitable, d'autre suivent le mouvement, etc. (quoique même une chose mauvaise, souvent, trop de gens suivent).

    C'est comme avec les génériques, y a toute une évolution derrière ce concept, très éloignée des simples MOV/ADD/JE/CALL/RET.

    Puis on oublie souvent d'où ça vient et de comment ça marche, on l'enseigne plus, d'autant plus que le domaine se démocratise et alors on appelle "développeur web" ou "programmeur nouvelles technologies" des gens formés en 3 mois et de 2 semaines de stage qui savent ni ce qu'est le binaire, ni un pointeur, ni même la factorisation et le polymorphisme, au mieux ils savent ce qu'est encapsuler, ils savent installer IIS et assembler des contrôles web, et il ont le vague sentiment de savoir la différence entre une classe et une interface.

    Quand on sait pas ou qu'on comprends pas, et quand on nous montre qu'on a mal compris, faut avoir l’honnêteté de le dire au moins à soi-même.

    J'ai écrit ceci dans mon premier post sur ce forum :

    Citation Envoyé par anonyme Voir le message
    La question est inhérente à l'architecture des processeurs (x86 par exemple et en l'occurence) et à la gestion des opcode call/ret (assembler mnemonic). C'est une question de taille de registre et de pile de retour. Aucun langage et même l'Intermediate Language du CLR ou la Java Virtual Machine ne peuvent s'affranchir de cette contrainte. Une "procédure" en tant que concept du langage machine ne peut retourner qu'une valeur de la taille du plus grand registre possible (32bits pour x32 et 64bits pour x64, utilisé pour coder les entiers dont les adresses mémoire et les réels). On pourrait faire des processeurs qui gèrent les retours différemment mais ce ne serait qu'un artéfact à cette contraire physique et n'aurait aucun intérêt en terme de performance.

    https://www.google.com/search?q=assembler+call+ret

    La solution est en effet l'utilisation de structures et de classes et donc de pointeurs et de références pour les instances en tant que result dont la gestion relève du rôle d'un compilateur (dit "évolué"). L'utilisation des params out comme en c# est également possible et si on veut par exemple une fonction qui retourne deux entiers, il suffit de retourner un générique Tuple<int, int> ou un type adéquat spécialisé.
    Et je suis content qu'on m'est amené à penser à la possibilité de retourner plusieurs variables car j'aimerais bien pouvoir écrire des choses du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public new(int value, string str, bool res) DoSomething()
    {
        result.value = 0;
      result.str = "";
      result.res = false;
    }
    Qui est plus naturel que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public bool DoSomething(out int value, out string str)
    {
      value = 0;
      str = "";
      return = false;
    }
    J'ai développé avec 3 ou 4 autres posts avec des détails, des exemples et des références.

    Mais deux ou trois personnes sont partit dans un délire d'ignorance contestataire et d'absurdités que j'ai du mal à ne pas ignorer puisque je me suis impliqué dans la discussion publique sur un sujet aussi technique que fondamental, je sais pas pourquoi.

    Et malgré avoir mis des preuves jusqu'à du code CIL produit par le compilateur C# pour un appel de méthode, qui est donc un CALL suivit d'un RET avec les PUSH/POP habituels (en fait il génère des "mov dwordptr" sur la pile par indexage mais c'est à peu près pareil), les critiques ont empiré.

    En résumé, j'ai indiqué qu'un appel de méthode dans n'importe quel langage, était finalement en langage machine cible un goto.

    Si ça choque, j'y suis pour rien.

    C'est comme ça que les choses sont.

    Mais si on veux jouer à "je dispute et je mets -1 à des posts parce que je comprends rien à la programmation informatique de bas comme de haut niveau", c'est stupide et c'est aussi une perte de temps... et c'est même pas marrant.

  18. #78
    Membre confirmé
    Profil pro
    Inscrit en
    avril 2008
    Messages
    452
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2008
    Messages : 452
    Points : 624
    Points
    624
    Par défaut
    Citation Envoyé par anonyme Voir le message
    Exactement.Mais si on veux jouer à "je dispute et je mets -1 à des posts parce que je comprends rien à la programmation informatique de bas comme de haut niveau", c'est stupide et c'est aussi une perte de temps... et c'est même pas marrant.
    Ca serait assez drôle que ce soit toi qui aies mis le "-1" à tes contradicteurs !

  19. #79
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ijk-ref Voir le message
    Ca serait assez drôle que ce soit toi qui aies mis le "-1" à tes contradicteurs !
    j'ai mis -1 à ceux qui ont mis -1 à plus de la moitié de mes posts de manière totalement injustifiable pour m'empecher de mettre un avatar "élevé au TO7-70"

  20. #80
    Expert éminent sénior
    Avatar de Uther
    Homme Profil pro
    Inscrit en
    avril 2002
    Messages
    4 318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations forums :
    Inscription : avril 2002
    Messages : 4 318
    Points : 13 089
    Points
    13 089
    Billets dans le blog
    1
    Par défaut
    Bof moi j'ai été élevé au MO5, ça c'était une vraie machine.

    Pour la pile, je corrige un peu ce que j'ai dit après m’être un peu renseigné davantage sur l'assembleur x86. C'est vrai que sur x86 c'est pas vraiment envisageable de passer les valeurs de retour sur la pile. J'ai surtout fait du 68000 qui laisse beaucoup plus de liberté sur la façon de gérer sa pile.

    Ceci dit un langage étant avant tout là pour abstraire, je rejoint esperanto sur le fait que le but des langages de haut niveau est justement d'avoir une notation qui s'éloigne de l'assembleur et se rapproche des mathématiques.
    Donc je trouve l'explication mathématique plus convaincante que celle de l'assembleur.

    Et c'est vrai que le problème des paramètre de retours multiples c'est qu'ils sont plus gênants qu'utile si on veut faire autre chose qu'une simple affectation.

Discussions similaires

  1. [AC-2003] Une formule pour calculer les in et out d une table de pointage
    Par taz devil dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 29/06/2015, 13h46
  2. Réponses: 10
    Dernier message: 10/02/2010, 09h49
  3. Réponses: 6
    Dernier message: 06/05/2009, 16h35
  4. [Excel] fonction SOMME.SI avec une cellule pour critère
    Par repié dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 15/03/2006, 18h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo