Je te donne un autre exemple encore :
Ecris un évaluateur de lambda-expressions de façon non récursive...
Il y a quantité d'algorithme qu'il est EXTREMEMENT plus simple d'écrire
en récursif, même et surtout si on élimine les algos sur les arbres, les
listes, etc. qui pourtant, ne sont pas que des exercices de style
puisqu'ils sont utilisés dans les optimiseurs des compilateurs, les
systèmes d'exploitation, etc.
Je te donne un autre exemple encore :
Ecris un évaluateur de lambda-expressions de façon non récursive...
Il y a quantité d'algorithme qu'il est EXTREMEMENT plus simple d'écrire
en récursif, même et surtout si on élimine les algos sur les arbres, les
listes, etc. qui pourtant, ne sont pas que des exercices de style
puisqu'ils sont utilisés dans les optimiseurs des compilateurs, les
systèmes d'exploitation, etc.
Je te donne un autre exemple encore :
Ecris un évaluateur de lambda-expressions de façon non récursive...
Il y a quantité d'algorithme qu'il est EXTREMEMENT plus simple d'écrire
en récursif, même et surtout si on élimine les algos sur les arbres, les
listes, etc. qui pourtant, ne sont pas que des exercices de style
puisqu'ils sont utilisés dans les optimiseurs des compilateurs, les
systèmes d'exploitation, etc.
Suites arithmétiques :
a_(0)
a_(n+1) = a_(n) + r
Suites géométriques :
q_(0)
q_(n+1) = q_(n) * r
etc.
Si l'on a compris ça, on a compris la récursivité.
Suites arithmétiques :
a_(0)
a_(n+1) = a_(n) + r
Suites géométriques :
q_(0)
q_(n+1) = q_(n) * r
etc.
Si l'on a compris ça, on a compris la récursivité.
Suites arithmétiques :
a_(0)
a_(n+1) = a_(n) + r
Suites géométriques :
q_(0)
q_(n+1) = q_(n) * r
etc.
Si l'on a compris ça, on a compris la récursivité.
In article ,
Erwan David wrote:ça c'est mon historique de développeur embarqué qui parle...
Ca veut juste dire que tu optimises la recursion terminale a la main
en presence de compilateurs deficients...
In article <m2d431ttx2.fsf@minuetto.depot.rail.eu.org>,
Erwan David <erwan@rail.eu.org> wrote:
ça c'est mon historique de développeur embarqué qui parle...
Ca veut juste dire que tu optimises la recursion terminale a la main
en presence de compilateurs deficients...
In article ,
Erwan David wrote:ça c'est mon historique de développeur embarqué qui parle...
Ca veut juste dire que tu optimises la recursion terminale a la main
en presence de compilateurs deficients...
Donc, le concept de récursivité il est assez facile à comprendre mais il
faut aller au-delà du concept, "In code we trust!" comme on dit. Et on
se rend compte que cela peut poser certaines difficultés
d'implémentation (en C par exemple mais je suppose que ça doit être vrai
dans d'autres langages) si on veut être un minimum efficace, il n'est
pas toujours facile de voir comment faire pour que chaque appel n'alloue
pas les données et qu'au contraire, ils utilisent une sorte de pool
commun. Si en général, on suit l'algorithme mathématique de trop près,
en général, on obtient des implémentations non efficaces.
Donc, le concept de récursivité il est assez facile à comprendre mais il
faut aller au-delà du concept, "In code we trust!" comme on dit. Et on
se rend compte que cela peut poser certaines difficultés
d'implémentation (en C par exemple mais je suppose que ça doit être vrai
dans d'autres langages) si on veut être un minimum efficace, il n'est
pas toujours facile de voir comment faire pour que chaque appel n'alloue
pas les données et qu'au contraire, ils utilisent une sorte de pool
commun. Si en général, on suit l'algorithme mathématique de trop près,
en général, on obtient des implémentations non efficaces.
Donc, le concept de récursivité il est assez facile à comprendre mais il
faut aller au-delà du concept, "In code we trust!" comme on dit. Et on
se rend compte que cela peut poser certaines difficultés
d'implémentation (en C par exemple mais je suppose que ça doit être vrai
dans d'autres langages) si on veut être un minimum efficace, il n'est
pas toujours facile de voir comment faire pour que chaque appel n'alloue
pas les données et qu'au contraire, ils utilisent une sorte de pool
commun. Si en général, on suit l'algorithme mathématique de trop près,
en général, on obtient des implémentations non efficaces.
C'est quoi un "pool commun" ?
Des variables globales ? statiques ?
Quand on utilise la récursivité, on va éviter les variables justement
(on n'utilisera que des paramètres).
On ne va faire que des appels de
fonctions (récursivement). C'est évidemment possible en C.
La programmation fonctionnelle, tu connais ?
Les langages sans affectation, tu connais ?
Les langages à assignation unique, tu connais ?
L'évaluation paresseuse, tu connais ?
Fonction d'Ackermann en Haskell :
ackermann 0 n = (n + 1)
ackermann m 0 = ackermann (m-1) 1
ackermann m n = ackermann (m-1) (ackermann m (n-1))
Justement, le mieux c'est de suivre, au plus près, la définition
mathématique.
C'est quoi un "pool commun" ?
Des variables globales ? statiques ?
Quand on utilise la récursivité, on va éviter les variables justement
(on n'utilisera que des paramètres).
On ne va faire que des appels de
fonctions (récursivement). C'est évidemment possible en C.
La programmation fonctionnelle, tu connais ?
Les langages sans affectation, tu connais ?
Les langages à assignation unique, tu connais ?
L'évaluation paresseuse, tu connais ?
Fonction d'Ackermann en Haskell :
ackermann 0 n = (n + 1)
ackermann m 0 = ackermann (m-1) 1
ackermann m n = ackermann (m-1) (ackermann m (n-1))
Justement, le mieux c'est de suivre, au plus près, la définition
mathématique.
C'est quoi un "pool commun" ?
Des variables globales ? statiques ?
Quand on utilise la récursivité, on va éviter les variables justement
(on n'utilisera que des paramètres).
On ne va faire que des appels de
fonctions (récursivement). C'est évidemment possible en C.
La programmation fonctionnelle, tu connais ?
Les langages sans affectation, tu connais ?
Les langages à assignation unique, tu connais ?
L'évaluation paresseuse, tu connais ?
Fonction d'Ackermann en Haskell :
ackermann 0 n = (n + 1)
ackermann m 0 = ackermann (m-1) 1
ackermann m n = ackermann (m-1) (ackermann m (n-1))
Justement, le mieux c'est de suivre, au plus près, la définition
mathématique.
Marc Espie a écrit :In article ,
Erwan David wrote:ça c'est mon historique de développeur embarqué qui parle...
Ca veut juste dire que tu optimises la recursion terminale a la main
en presence de compilateurs deficients...
Un truc a savoir, c'est que si l'optimiseur vire une récursivité, ton
prog devient nettement moins débuggable par perte du contexte courant
("stack frame"). En théorie on s'en fiche, mais à l'usage c'est chiant
et il vaut mieux que le compilo garde la structure asm assez proche du
code d'origine.
Je te raconte pas les surprise qu'on trouve en débuggant un code
optimisé par un compilo qui en fait trop.
Par exemple au niveau
couverture du code on se retrouve à passer par les deux branches d'un
if() simultanément et crois moi c'est pas bon du tout pour certains
critères de couverture du code (mc/dc etc). En plus quand le code ASM ne
trace plus les lignes du code C dans le même ordre où elle sont écrite
rend le truc in-traçable. En théorie on s'en fiche d'avoir un code non
tracable s'il est bon.. mais voila le moindre code, meme hyper simple,
est souvent buggé (cf les pbs d'overflow en arithmetique) et on est
content d'avoir un code ASM assez proche du code C.
Marc Espie a écrit :
In article <m2d431ttx2.fsf@minuetto.depot.rail.eu.org>,
Erwan David <erwan@rail.eu.org> wrote:
ça c'est mon historique de développeur embarqué qui parle...
Ca veut juste dire que tu optimises la recursion terminale a la main
en presence de compilateurs deficients...
Un truc a savoir, c'est que si l'optimiseur vire une récursivité, ton
prog devient nettement moins débuggable par perte du contexte courant
("stack frame"). En théorie on s'en fiche, mais à l'usage c'est chiant
et il vaut mieux que le compilo garde la structure asm assez proche du
code d'origine.
Je te raconte pas les surprise qu'on trouve en débuggant un code
optimisé par un compilo qui en fait trop.
Par exemple au niveau
couverture du code on se retrouve à passer par les deux branches d'un
if() simultanément et crois moi c'est pas bon du tout pour certains
critères de couverture du code (mc/dc etc). En plus quand le code ASM ne
trace plus les lignes du code C dans le même ordre où elle sont écrite
rend le truc in-traçable. En théorie on s'en fiche d'avoir un code non
tracable s'il est bon.. mais voila le moindre code, meme hyper simple,
est souvent buggé (cf les pbs d'overflow en arithmetique) et on est
content d'avoir un code ASM assez proche du code C.
Marc Espie a écrit :In article ,
Erwan David wrote:ça c'est mon historique de développeur embarqué qui parle...
Ca veut juste dire que tu optimises la recursion terminale a la main
en presence de compilateurs deficients...
Un truc a savoir, c'est que si l'optimiseur vire une récursivité, ton
prog devient nettement moins débuggable par perte du contexte courant
("stack frame"). En théorie on s'en fiche, mais à l'usage c'est chiant
et il vaut mieux que le compilo garde la structure asm assez proche du
code d'origine.
Je te raconte pas les surprise qu'on trouve en débuggant un code
optimisé par un compilo qui en fait trop.
Par exemple au niveau
couverture du code on se retrouve à passer par les deux branches d'un
if() simultanément et crois moi c'est pas bon du tout pour certains
critères de couverture du code (mc/dc etc). En plus quand le code ASM ne
trace plus les lignes du code C dans le même ordre où elle sont écrite
rend le truc in-traçable. En théorie on s'en fiche d'avoir un code non
tracable s'il est bon.. mais voila le moindre code, meme hyper simple,
est souvent buggé (cf les pbs d'overflow en arithmetique) et on est
content d'avoir un code ASM assez proche du code C.
Perso, si je voulais faire de l'asm, je ferais de l'asm. J'attend de mon
compilo qu'il fasse un boulot decent cote optimisation. Je suis conscient
que ca n'est pas toujours le cas sur certaines archis peu repandues, helas...
Perso, si je voulais faire de l'asm, je ferais de l'asm. J'attend de mon
compilo qu'il fasse un boulot decent cote optimisation. Je suis conscient
que ca n'est pas toujours le cas sur certaines archis peu repandues, helas...
Perso, si je voulais faire de l'asm, je ferais de l'asm. J'attend de mon
compilo qu'il fasse un boulot decent cote optimisation. Je suis conscient
que ca n'est pas toujours le cas sur certaines archis peu repandues, helas...
Wykaaa a écrit :C'est quoi un "pool commun" ?
Des variables globales ? statiques ?
En pratique c'est souvent le cas mais on peut aussi passer en paramètre
un pointeur vers ce qui va être le pool.
Quand on utilise la récursivité, on va éviter les variables justement
(on n'utilisera que des paramètres).
Regarde un implémentation correcte de qsort() par un quicksort et tu
verras qu'il n'y a pas que des paramètres. J'ai celle de Plauger sous
les yeux (c'est pas vraiment un mauvais programmeur!) et il définit un
paquet de variables. Au final, c'est pas très gênant vu que la
complexité est en n*ln(n) donc on limite la casse.
On peut bien sûr éviter les variables mais alors on introduit des
paramètres factices, qui ne servent qu'au fonctionnement interne de la
fonction, bref on mélange interface et implémentation, le truc que je
déteste.
On ne va faire que des appels de
fonctions (récursivement). C'est évidemment possible en C.
Oui, tu enfonces des portes ouvertes.
La programmation fonctionnelle, tu connais ?
Plusieurs de mes collègues ont tenté de m'y convertir (enfin à Caml)
mais en vain.
Les langages sans affectation, tu connais ?
NonLes langages à assignation unique, tu connais ?
NonL'évaluation paresseuse, tu connais ?
Lazy evaluation ? j'ai vu le nom dans des docs Python mais je ne sais
pas ce que c'est.
Fonction d'Ackermann en Haskell :
ackermann 0 n = (n + 1)
ackermann m 0 = ackermann (m-1) 1
ackermann m n = ackermann (m-1) (ackermann m (n-1))
Justement, le mieux c'est de suivre, au plus près, la définition
mathématique.
Certainement pas. Exemple classique :
int f(int n)
{
return n <= 1 ? 1 : f(n - 1) + f(n - 2);
}
ce qui une fois de plus montre qu'il y a une distance entre le concept
souvent simple voire trivial, et l'implémentation. Bref, ne confondons
pas récursivité de salon et récursivité de codeur.
Au demeurant, peut-être que certains certains langages sont plus aptes
que d'autres à suivre au plus près la définition mathématique.
Wykaaa a écrit :
C'est quoi un "pool commun" ?
Des variables globales ? statiques ?
En pratique c'est souvent le cas mais on peut aussi passer en paramètre
un pointeur vers ce qui va être le pool.
Quand on utilise la récursivité, on va éviter les variables justement
(on n'utilisera que des paramètres).
Regarde un implémentation correcte de qsort() par un quicksort et tu
verras qu'il n'y a pas que des paramètres. J'ai celle de Plauger sous
les yeux (c'est pas vraiment un mauvais programmeur!) et il définit un
paquet de variables. Au final, c'est pas très gênant vu que la
complexité est en n*ln(n) donc on limite la casse.
On peut bien sûr éviter les variables mais alors on introduit des
paramètres factices, qui ne servent qu'au fonctionnement interne de la
fonction, bref on mélange interface et implémentation, le truc que je
déteste.
On ne va faire que des appels de
fonctions (récursivement). C'est évidemment possible en C.
Oui, tu enfonces des portes ouvertes.
La programmation fonctionnelle, tu connais ?
Plusieurs de mes collègues ont tenté de m'y convertir (enfin à Caml)
mais en vain.
Les langages sans affectation, tu connais ?
Non
Les langages à assignation unique, tu connais ?
Non
L'évaluation paresseuse, tu connais ?
Lazy evaluation ? j'ai vu le nom dans des docs Python mais je ne sais
pas ce que c'est.
Fonction d'Ackermann en Haskell :
ackermann 0 n = (n + 1)
ackermann m 0 = ackermann (m-1) 1
ackermann m n = ackermann (m-1) (ackermann m (n-1))
Justement, le mieux c'est de suivre, au plus près, la définition
mathématique.
Certainement pas. Exemple classique :
int f(int n)
{
return n <= 1 ? 1 : f(n - 1) + f(n - 2);
}
ce qui une fois de plus montre qu'il y a une distance entre le concept
souvent simple voire trivial, et l'implémentation. Bref, ne confondons
pas récursivité de salon et récursivité de codeur.
Au demeurant, peut-être que certains certains langages sont plus aptes
que d'autres à suivre au plus près la définition mathématique.
Wykaaa a écrit :C'est quoi un "pool commun" ?
Des variables globales ? statiques ?
En pratique c'est souvent le cas mais on peut aussi passer en paramètre
un pointeur vers ce qui va être le pool.
Quand on utilise la récursivité, on va éviter les variables justement
(on n'utilisera que des paramètres).
Regarde un implémentation correcte de qsort() par un quicksort et tu
verras qu'il n'y a pas que des paramètres. J'ai celle de Plauger sous
les yeux (c'est pas vraiment un mauvais programmeur!) et il définit un
paquet de variables. Au final, c'est pas très gênant vu que la
complexité est en n*ln(n) donc on limite la casse.
On peut bien sûr éviter les variables mais alors on introduit des
paramètres factices, qui ne servent qu'au fonctionnement interne de la
fonction, bref on mélange interface et implémentation, le truc que je
déteste.
On ne va faire que des appels de
fonctions (récursivement). C'est évidemment possible en C.
Oui, tu enfonces des portes ouvertes.
La programmation fonctionnelle, tu connais ?
Plusieurs de mes collègues ont tenté de m'y convertir (enfin à Caml)
mais en vain.
Les langages sans affectation, tu connais ?
NonLes langages à assignation unique, tu connais ?
NonL'évaluation paresseuse, tu connais ?
Lazy evaluation ? j'ai vu le nom dans des docs Python mais je ne sais
pas ce que c'est.
Fonction d'Ackermann en Haskell :
ackermann 0 n = (n + 1)
ackermann m 0 = ackermann (m-1) 1
ackermann m n = ackermann (m-1) (ackermann m (n-1))
Justement, le mieux c'est de suivre, au plus près, la définition
mathématique.
Certainement pas. Exemple classique :
int f(int n)
{
return n <= 1 ? 1 : f(n - 1) + f(n - 2);
}
ce qui une fois de plus montre qu'il y a une distance entre le concept
souvent simple voire trivial, et l'implémentation. Bref, ne confondons
pas récursivité de salon et récursivité de codeur.
Au demeurant, peut-être que certains certains langages sont plus aptes
que d'autres à suivre au plus près la définition mathématique.
Alors je comprends que tu n'aime pas la récursivité.
Oui la suite de Fibonacci écrite de cette manière n'est pas optimisée
car les mêmes évaluations se font à plusieurs endroits.
ce qui une fois de plus montre qu'il y a une distance entre le concept
souvent simple voire trivial, et l'implémentation. Bref, ne confondons
pas récursivité de salon et récursivité de codeur.
Ce n'est pas à moi que tu vas tenir ce discours. J'ai trempé pendant 10
ans dans les compilateurs et il y avait de la récursion à tous les
étages...
Alors je comprends que tu n'aime pas la récursivité.
Oui la suite de Fibonacci écrite de cette manière n'est pas optimisée
car les mêmes évaluations se font à plusieurs endroits.
ce qui une fois de plus montre qu'il y a une distance entre le concept
souvent simple voire trivial, et l'implémentation. Bref, ne confondons
pas récursivité de salon et récursivité de codeur.
Ce n'est pas à moi que tu vas tenir ce discours. J'ai trempé pendant 10
ans dans les compilateurs et il y avait de la récursion à tous les
étages...
Alors je comprends que tu n'aime pas la récursivité.
Oui la suite de Fibonacci écrite de cette manière n'est pas optimisée
car les mêmes évaluations se font à plusieurs endroits.
ce qui une fois de plus montre qu'il y a une distance entre le concept
souvent simple voire trivial, et l'implémentation. Bref, ne confondons
pas récursivité de salon et récursivité de codeur.
Ce n'est pas à moi que tu vas tenir ce discours. J'ai trempé pendant 10
ans dans les compilateurs et il y avait de la récursion à tous les
étages...
Bonjour,
le 29/11/2009 à 11:07, -ed- a écrit dan s
le message
:
>> loin dans la programmation, je veux comprendre ce qui se passe dans la
>> machine tant que c'est à "porter de mains".
> Tu ne conduis une voiture que si tu es un expert en sciences
> mécanique ?
L'analogie est mauvaise. La programmation, c'est plutôt la fabrication
de la voiture, l'utilisation du programme étant la conduite.
Je veux fabriquer une voiture. Dans tous les cas il me faut des plans
(algorithmes) et c'est indépendant du choix que je vais faire pour sa
fabrication (langage de programmation). Ensuite, j'ai le choix :
- je veux construire moi-même toutes les pièces (assembleurs)
- je veux acheter toutes les matières premières et réaliser tou s les
usinages, par contre j'utilise des vis du commerce (C)
- je veux acheter des composants existants dans le commerce comme le
moteur, la carrosserie et ne réaliser que l'assemblage (Python,
Perl, etc.)
Ça reste une analogie, la réalité est un peu plus complexe quand au
choix du langage.
Ceci dit, pour quelqu'un qui n'est pas informaticien (comme moi) et
qui ne pratique pas la programmation de manière régulière, il ne fa ut
pas s'attendre à pouvoir programmer en C correctement avant plusieurs
années (pratiquement dix ans dans mon cas mais je suis une
feignasse ;-) ).
Je pense qu'on apprends un langage de programmation comme une langue
étrangère : au début, on comprends rien et c'est bien normal. Il ne faut
surtout pas s'attarder sur tous les petits détails sinon on n'apprend
rien. Avec le temps, on commence à comprendre le sens des phrases mêm e
si on ne comprend pas chaque mot. Avec la pratique, on acquière des
automatismes qui permettent de ne plus réfléchir à certaines choses et
donc de pouvoir se concentrer sur d'autre dont on ignorait l'existence.
Pour une personne qui apprend seule, parler couramment, avoir l'accent
et pouvoir faire du littéraire, c'est beaucoup, beaucoup de travail (je
veux pas décourager mais je pense même que c'est quasiment impossible ).
Si l'on veux vraiment avoir une maîtrise du langage, la seule solution
c'est d'aller dans un pays où les gens parlent cette langue (milieu
professionnel ou participer au développement d'une application réelle ).
Mes deux cents.
Benoit Izac
Bonjour,
le 29/11/2009 à 11:07, -ed- <emmanuel.delah...@gmail.com> a écrit dan s
le message
<d99cd762-ed06-4f79-af6a-f6ecd5136...@e27g2000yqd.googlegroups.com> :
>> loin dans la programmation, je veux comprendre ce qui se passe dans la
>> machine tant que c'est à "porter de mains".
> Tu ne conduis une voiture que si tu es un expert en sciences
> mécanique ?
L'analogie est mauvaise. La programmation, c'est plutôt la fabrication
de la voiture, l'utilisation du programme étant la conduite.
Je veux fabriquer une voiture. Dans tous les cas il me faut des plans
(algorithmes) et c'est indépendant du choix que je vais faire pour sa
fabrication (langage de programmation). Ensuite, j'ai le choix :
- je veux construire moi-même toutes les pièces (assembleurs)
- je veux acheter toutes les matières premières et réaliser tou s les
usinages, par contre j'utilise des vis du commerce (C)
- je veux acheter des composants existants dans le commerce comme le
moteur, la carrosserie et ne réaliser que l'assemblage (Python,
Perl, etc.)
Ça reste une analogie, la réalité est un peu plus complexe quand au
choix du langage.
Ceci dit, pour quelqu'un qui n'est pas informaticien (comme moi) et
qui ne pratique pas la programmation de manière régulière, il ne fa ut
pas s'attendre à pouvoir programmer en C correctement avant plusieurs
années (pratiquement dix ans dans mon cas mais je suis une
feignasse ;-) ).
Je pense qu'on apprends un langage de programmation comme une langue
étrangère : au début, on comprends rien et c'est bien normal. Il ne faut
surtout pas s'attarder sur tous les petits détails sinon on n'apprend
rien. Avec le temps, on commence à comprendre le sens des phrases mêm e
si on ne comprend pas chaque mot. Avec la pratique, on acquière des
automatismes qui permettent de ne plus réfléchir à certaines choses et
donc de pouvoir se concentrer sur d'autre dont on ignorait l'existence.
Pour une personne qui apprend seule, parler couramment, avoir l'accent
et pouvoir faire du littéraire, c'est beaucoup, beaucoup de travail (je
veux pas décourager mais je pense même que c'est quasiment impossible ).
Si l'on veux vraiment avoir une maîtrise du langage, la seule solution
c'est d'aller dans un pays où les gens parlent cette langue (milieu
professionnel ou participer au développement d'une application réelle ).
Mes deux cents.
Benoit Izac
Bonjour,
le 29/11/2009 à 11:07, -ed- a écrit dan s
le message
:
>> loin dans la programmation, je veux comprendre ce qui se passe dans la
>> machine tant que c'est à "porter de mains".
> Tu ne conduis une voiture que si tu es un expert en sciences
> mécanique ?
L'analogie est mauvaise. La programmation, c'est plutôt la fabrication
de la voiture, l'utilisation du programme étant la conduite.
Je veux fabriquer une voiture. Dans tous les cas il me faut des plans
(algorithmes) et c'est indépendant du choix que je vais faire pour sa
fabrication (langage de programmation). Ensuite, j'ai le choix :
- je veux construire moi-même toutes les pièces (assembleurs)
- je veux acheter toutes les matières premières et réaliser tou s les
usinages, par contre j'utilise des vis du commerce (C)
- je veux acheter des composants existants dans le commerce comme le
moteur, la carrosserie et ne réaliser que l'assemblage (Python,
Perl, etc.)
Ça reste une analogie, la réalité est un peu plus complexe quand au
choix du langage.
Ceci dit, pour quelqu'un qui n'est pas informaticien (comme moi) et
qui ne pratique pas la programmation de manière régulière, il ne fa ut
pas s'attendre à pouvoir programmer en C correctement avant plusieurs
années (pratiquement dix ans dans mon cas mais je suis une
feignasse ;-) ).
Je pense qu'on apprends un langage de programmation comme une langue
étrangère : au début, on comprends rien et c'est bien normal. Il ne faut
surtout pas s'attarder sur tous les petits détails sinon on n'apprend
rien. Avec le temps, on commence à comprendre le sens des phrases mêm e
si on ne comprend pas chaque mot. Avec la pratique, on acquière des
automatismes qui permettent de ne plus réfléchir à certaines choses et
donc de pouvoir se concentrer sur d'autre dont on ignorait l'existence.
Pour une personne qui apprend seule, parler couramment, avoir l'accent
et pouvoir faire du littéraire, c'est beaucoup, beaucoup de travail (je
veux pas décourager mais je pense même que c'est quasiment impossible ).
Si l'on veux vraiment avoir une maîtrise du langage, la seule solution
c'est d'aller dans un pays où les gens parlent cette langue (milieu
professionnel ou participer au développement d'une application réelle ).
Mes deux cents.
Benoit Izac