[gull] Types : [was: Php/MsSQL obsoletes?]
Daniel Cordey
dc at mjt.ch
Thu Sep 29 13:43:19 CEST 2005
On Wednesday 28 September 2005 23:00, JM Nunes wrote:
> ou dynamiquement (Pyhton, Perl -je crois), à l'exécution.
Ben oui... les langages interpretes ne passent pas par la phase de
compilation :-)
> Ainsi en C c'est
> char* x = "123"
> et en Ocaml c'est
> let x = "123"
>
> -"strongly typed"...
Que veux-tu dire par la... ?
>
> *************** en C ****************
> main () {
> char* x = "123";
> printf ("x=%i"; x);
> }
> ************
> compilé et exécuté résulte en:
> ./a.out
> x=134513860
>
> *************** en Ocaml ********************
> $ ledit ocaml
> Objective Caml version 3.08.3
>
> # let x = "123";;
> val x : string = "123"
> # Printf.printf "x=%i" x;;
> This expression has type string but is here used with type int
> #
> ***********************
> **************** en Python **********************
> $ python
> Python 2.3.5 (#2, May 4 2005, 08:51:39)
> [GCC 3.3.5 (Debian 1:3.3.5-12)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>
> >>> x = "123"
> >>> print 'x=%i' % x
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: int argument required
>
> ******************
> et donc C est plus faiblement typé que Ocaml et Python.
Ce ne sont pas dut tout les memes choses. Je crois que la confusion viend du
fait que les chaines de caracteres sont manipulees a l'aide de pointeurs,
alors que dans tous les autres langages (aurais-je oublier un langage qui
fasse pareil ?) il existe un type "string", totalement absent en C. Un 'char
*' n'est pas un type "tring"; ce n'est qu'un vulgaire pointeur sur des
valeurs de 1 byte !!! A ce titre, on ne compare pas du tout la meme chose. On
peut discuter longtemps de l'absence d'un type de base "string" en C... il se
trouve que c'est comme ca, que c'est tres simple mais c'est tout. Idealement,
d'ailleurs, on devrait ecrire :
const char x[] = "123";
Mais ca n'a pas beaucoup d'importance...
Ce qui fait que toute cette discussion concernant les chaines de caractere est
biaisee. Un pointeur n'est qu'un "symbole" contenant une adresse. A ce titre,
un "char *" ou un "double *" ne sont pas pareils. Tous les pointeurs ont une
"empreinte" identique en memoire, mais les operations arithmetiques sur
chacun d'eux ne sont pas identiques ! Exemple :
int main(int argc, char *argv[])
{
char *pc;
double *pd;
char c = 'X';
double d = 1.234;
pc = &c;
pd = &d;
printf("pc\t: 0x%x\npc + 1\t: 0x%x\npd\t: 0x%x\npd + 1\t: 0x%x\n", pc, pc
+ 1, pd, pd + 1);
printf("pc delta\t: %d\npd delta\t: %d\n", pc + 1 - pc, pd + 1 - pd);
}
pc : 0xbfffefef
pc + 1 : 0xbfffeff0
pd : 0xbfffefe0
pd + 1 : 0xbfffefe8
pc delta : 1
pd delta : 1
On voit que chaque pointeur est incremente en fonction du "type" sur lequel il
pointe. pc est incremente de 1 byte, alors que pd est incremente de 8 bytes !
Les pointeurs sont donc aussi "fortement" types, et le traitement des chaines
de caracteres est une utlisation particuliere d 'un type de pointeur. Une
chaine de catactere n'est en aucun cas un type en C; ce n'est qu'une suite de
bytes en memoire, conventionnellement terminee par un carcatere NULL.
> Essayons maintenant
> ***************** C ****************
> main(){
> int x = 123;
> printf ("x=%s",x);
> }
> **************
> le résultat est
> $ ./a.out
> Segmentation fault
Ici, normal... c'est plutot la librairie C qui est coupable. Elle "balaie" la
chaine de caractere representant le format, afin de determiner ce qu'elle
doit recuperer comme argument dans la liste. Sur la base du %s, elle
considere que le deuxieme argument de la fonction est un pointeur, elle en
prend donc la valeur et essaie de lire les byte a cette adresse...
Naturellement, avec une valeur de '495051', on a toute les chances de genere
un 'segmentation fault'; cette adresse ne faisant certaienement pas partie
des pages de la zone data du process...
Comme dans Ocaml, c'est donc une mauvaise definition de format d'impression
qui est a mettre en cause, plutot que le type.
> ************ Python ****************
>
> >>> x=123
> >>> print 'x=%s' % x
>
> x=123
> ******************
>
> D'où Python est plus faiblement typé que Ocaml.
Absolument pas ! C'est exactement le contraire... en Python, chaque type est
un objet, or, un objet 'int' a une methode __str__() definie par defaut... et
cest cette methode qui est appelee automatiquement par le fait de la
definition '%s' dans le format d'impression. Pour vous en convaincre, il vous
suffit de creer une classe quelqconque, sans methode __str__. En essayent
d'imprimer un instance de votre objet avec le format "%s", vous aurez une
exeption due au fait que l'interpreteur ne trouve pas de methode __str__
associee a cet objet ! Ce qui est parfaitement logique... meme elegant :-)
On voit bien qu'il n'est pas necessaire de discuter pour savoir si un langage
est plus "type" qu'un autre. Cela n'amene rien de plus. Il suffit de bien
comprendre comment chaque langage manipule ses types et ses donnees, d'en
connaitres les limites et les contraintes. A partir de la, on peut programmer
proprement.
> <troll>
> Si toutefois on cherche le langage le moins mauvais pour exprimer tout
> algorithme ---i.e., *le* langage de programmation générique--- on finit
> par trouver Ocaml. Mais je vous laisse le temps de le découvrir...
> </troll>
Pourquoi pas :-) Chaque lanagage poursuit un objectif prioritaire. Certains
sont plsu adaptes que d'autres pour certaines taches, mais aucun langage ne
peut pretendre tout faire mieux que tous les autres. Si aucun langage ne vous
satisfait, ecrivez le votre ! C'est ce que les auteurs de tous les langages
dont on parle on fait... sauf Ada et PL/1 (entre autre) :-)
dc
More information about the gull
mailing list