Non! L'inefficacité de la "garbage collection" se fait remarquer de plus en plus plus le programme est grand! Si le programme est petit, il y aura peu d'allocations, donc il n'y aura pas le problème de la mémoire consommée, et la "garbage collection" ne se produira pas, donc pas de ralentissements. Si le programme est plus grand, ça change tout!
D'abord, tu surestime l'importance des GC. Dans un programme comme ackermann, par exemple, il n'y aura jamais de GC quelque soit la taille de l'argument.
Ensuite, si tu regardes les quantités de mémoire consommées dans les programmes qui réservent vraiment de la mémoire (
Regular Expression Matching par exemple), tu verras qu'il y a nécessairement des GC.
Non, on devrait les faire sur de vraies applications! Mais évidemment, le problème est qu'il faut coder la même application en C et en CAML. C'est pour ça que le bench que tu m'as montré se replie sur des mini-programmes. Mais il faut bien garder en tête que ce sont des mini-programmes et pas des benchs représentatifs de la réalité.
Un bench représentatif de la réalité, ça n'existe pas.
A part ça, coder la même application en C et en Caml est délicat car les langages ont des performances très différentes selon les domaines.
Les appels de fonction en C font le minimum nécessaire demandé par le processeur!
Alors il est amusant de constater que c'est encore plus rapide en Caml
Regarde le bench ackerman, c'est flagrant. Alors que :
- le programme C est écrit de manière optimisée, dans ce style illisible caractéristique.
- Caml, pour gérer ses entiers, doit rajouter les opérations qui selon toi pénalisent affreusement la vitesse
Déjà, les benchs ne sont pas des contre-exemples valides mathématiquement parce qu'ils sont soumis à des erreurs de mesure.
Tu veux dire que le type s'est planté en recopiant, gcc mettait 0.2 sec là où il a écrit 0.9 sec ?
Bel argument.
Et ensuite, j'ai montré que pour des valeurs suffisamment grandes de n (le nombre d'octets alloués par le programme), la "garbage collection" est inefficace de manière mesurable
C'est faux.
S'il existait des conclusions aussi catégoriques, il y aurait bien longtemps qu'on aurait abandonné les sytèmes garbage-collectés.
Tu connais la norme POSIX? Regarde TIGCC pour Linux/Unix. Il tourne sur n'importe quel processeur (à condition qu'il soit supporté comme "host" et comme "target" par GCC), et sur un grand nombre de systèmes d'exploitations. Et c'est le cas pour beaucoup de programmes conformes à la norme POSIX. Et puis, il y a aussi une librairie standard C qui est disponible sur presque tous les systèmes d'exploitation; si on se limite à cette librairie standard, le programme fonctionnera presque partout sans aucun changement. C'est le cas de certains programmes qui font partie de TIGCC: ils marchent sans problèmes sous Windows et sur les plateformes POSIX.
Tout ce que tu racontes ne change rien au fait qu'un programme C, sauf exceptions très minoritaires, ne se transporte jamais tel quel d'un windows à un linux, à un mac, sur une Ti, un Unix ou autres, sans parler des problèmes de librairies et de toute cette sorte de choses...
On ne s'en fout pas! Un langage disponible pour plus de plateformes est un langage meilleur!
Evidemment non. Tout dépend des buts, des tenants et des aboutissants de ce langage. Et on s'en fout de ne pas pouvoir faire tourner caml dans un four micro ondes.
Non. Un programmeur C sait déjà ce qu'il y a dedans.
Ouaip, et au passage, ils sont chiants et inutiles et alourdissent encore le code source (comme si le C en avait besoin...)
Non, ça se voit de loin que 3 est un entier!
Tu vois, tu deviens raisonnable!
De même, quand tu écris
function x -> x+1, ça ce voit que c'est un objet
int -> int
Mais pour le type de chaque variable, on ne le connaît pas à l'avance, et on ne le voit pas de loin, donc c'est différent!
Mais si mais si, ne sous estime pas l'intelligence du programmeur. Pour quelqu'un qui est capable de s'arracher les yeux à décortiquer de l'incompréhensible code C, le type d'un objet caml saute aux yeux.
Arrête de m'accuser de mauvaise foi!!!
De quoi d'autre alors?
Tu es tellement habitué à ce langage illisible que tu ne te rends même plus compte qu'il est illisible!
Voilà par exemple une phrase que je peux te retourner telle quelle.
On met bien le type complet! Mais on met les argument pris après le nom de la fonction, parce que c'est comme ça qu'on appelle une fonction (encore la convention "on déclare de la même manière qu'on appelle").
Oui, c'est bien ce que je dis, on déclare le type en petits morceaux. Un bout par ici, un bout par là...
C'est nettement plus lisible que ( 'a -> 'a -> bool ) -> 'a list -> 'a list, mais tu as trop pris l'habitude des écritures illisibles. Dans 'a list montri('a list l, bool (*funcptr)('a,'a)), on voit de loin que c'est une fonction parce qu'il y a une liste d'arguments entre parenthèses,
lol!
On ne voit strictement rien de loin, parce qu'il y a trop de parenthèses (3 paires, c'est vraiment se foutre de la gueule du monde). Doit on déduire des trois paires de parenthèses qu'il y a trois fonctions? visiblement pas... il faut s'échiner à démonter ce truc qui ne va pas dans le sens du cerveau humain.
Toutes ces choses sautent à l'œil, alors que dans ( 'a -> 'a -> bool ) -> 'a list -> 'a list, on est perdus dans un labyrinthe de flèches (en partie à cause de la syntaxe, et en partie parce que tu as omis des parenthèses nécessaires pour la compréhension par un être humain).

Tu es vraiment trop fort quand tu t'y mets
Je te laisse à ta conception très personnelle de la simplicité...
Non, tu ne déclares pas comme tu utilises!
Bien sûr que si. (Exemples plus bas)
Tu déclares type_argument -> type_retour et tu utilises nom_fonction type_argument.
Non, puisque justement, on ne déclare pas le type
Le CAML mélange les 2, donc on déclare de manière différente qu'on utilise.
Tu es tellement obnubilié par le mode de pensée du C que tu es incapable de juger autre chose sans faire un parrallèle qui n'a pas lieu d'être.
Le Caml ne mélange pas du tout les deux, il s'en fout et utilise ses propres méthodes.
L'adéquation entre les déclaration et l'utilisation est flagrante.
DECLARATION DE TYPE
type arbre =
| Feuille
| Noeud of arbre*arbre;;
DECLARATION DE FONCTION
let rec nb_feuille = function
| Feuille -> 1
| Noeud (a,b) -> (nb_feuille a) + (nb_feuille b);;
DECLARATION D'OBJET
Noeud ( Feuille, Noeud (Feuille, Feuille) );;
APPEL DE FONCTION
Si
f est définie par
let f x y = x+y-1;;
Alors
f 3 4;; renvoie
6
J'avais déjà compris ça! Mais ces parenthèses ne sont pas inutiles, leur omission rend le code totalement illisible!
Ces parenthèses sont inutiles. Totalement inutile.
Je rappelle que *même* dans le C (!), il y a des règles de priorité entre les opérateurs afin (sacrilège!) d'éliminer des parenthèses.
"rend le code totalement illisible"
De toute façon ce type n'apparaît pas dans le code

.
Mais il est bien sûr d'une totale lisibilité.
On croirait avoir affaire à une fonction de 'a vers 'a et à une fonction de 'a vers bool, alors qu'on est devant une fonction de 'a vers une fonction de 'a vers bool.
Oui, je l'ai cru moins aussi, les 30 premières secondes où j'ai fait du Caml

.
"Utile" et "bizarre" ne sont pas forcément incompatibles! Et ce système a un grand problème: tu peux fixer seulement la valeur du premier argument. Si tu veux fixer la valeur du deuxième argument, ça ne marchera pas. Il serait plus intéressant d'avoir un moyen général de fixer la valeur d'un argument, quelle que soit sa position dans la liste des arguments.
Bref tu affirmes que la curryfication n'est pas encore assez, bravo
Allez, une ligne de code pour résoudre ce problème, dans le plus pur style ultraminimaliste que j'affectionne :
let arg2 f a b = f b a;;
Après ça,
arg2 f a représente la fonction partielle f(*,a)
(Et, au passage : on se fout totalement du type de arg2, on voit bien comment ça marche. La compilateur trouve
( 'a -> 'b -> 'c ) -> 'b -> 'a -> 'c )
Mais un tel système de curryfication du deuxième argument n'a pas d'intérêt. Les fonctions courantes +, *, sont symétriques. Les fonctions plus avancées ont leur argument dans le bon ordre, en principe.
Tes 30 secondes sont une estimation très optimiste.
Mon frère (qui n'avait *jamais* fait de programmation d'aucune sorte jusqu'à maintenant) s'est mis à Caml cette année (programme de maths sup).
Et ça marche très bien pour lui. Caml est un excellent langage d'apprentissage, entre autres.
Tu n'es pas obligé de lui faire confiance. Tu peux explicitement déclarer register int variable1 asm("d3");.
C'est judicieux, sur un PC?
Les accolades montrent clairement où commence et où se termine le code.
La syntaxe du filtrage montre de manière infiniment plus claire les différents cas.
Mais qu'est-ce qu'elles t'ont fait, ces 2 lettres?
Rien rien, je les aime bien même.
Mais I + F + ESPACE + PARENTHESES autour de l'expression booléenne + ACCOLADES + INDENTATION =
LOURD
Spécialement quand on en enfile une floppée à la suite.
Et donc le type est "Arbre" comme j'ai dit.
Ben oui, le type est Arbre
Tu voulais que ce soit quoi?
Mais il a bien besoin de faire un test en temps d'exécution, et donc de mettre un identifiant! Ou alors d'utiliser l'astuce que j'ai proposée pour l'arbre, mais ça ne marche qu'en des cas particuliers.
Mais non mais non il ne calcule pas didentifiant.
Quand le motif est
(a,_,([b::q] as w)) when a>0, il génère le code le plus efficace sans avoir besoin des mauvaises combines pour émuler ça en C.
C'est quoi cette manie de tout mettre dans des modules?
C'est une manie qui consiste à virer du langage tout ce qui est inutile
