The following warnings occurred:
Warning [2] Undefined array key "logoutkey" - Line: 42 - File: global.php(1070) : eval()'d code PHP 8.2.24 (Linux)
File Line Function
/inc/class_error.php 153 errorHandler->error
/global.php(1070) : eval()'d code 42 errorHandler->error_callback
/global.php 1070 eval
/printthread.php 16 require_once
Warning [2] Undefined property: MyLanguage::$archive_pages - Line: 2 - File: printthread.php(287) : eval()'d code PHP 8.2.24 (Linux)
File Line Function
/inc/class_error.php 153 errorHandler->error
/printthread.php(287) : eval()'d code 2 errorHandler->error_callback
/printthread.php 287 eval
/printthread.php 117 printthread_multipage



EPITA 2018
Lacunes Caml - Printable Version

+- EPITA 2018 (https://2018.epita.eu)
+-- Forum: Cours (https://2018.epita.eu/forumdisplay.php?fid=6)
+--- Forum: Algorithmique (https://2018.epita.eu/forumdisplay.php?fid=25)
+--- Thread: Lacunes Caml (/showthread.php?tid=266)

Pages: 1 2 3


RE: Lacunes Caml - tsunami33 - 10-01-2013

Ça c'est de l'argument Dodgy
Si tu veux me dire que je n'ai pas compris quelque chose, aies au moins la décence de dire quoi. Le fait que je me serve de Wikipédia ou le fait que je ne trouve pas claire la notion d'identificateur ? Et détaille aussi pourquoi stp. Sinon ça sert à rien de poster.


RE: Lacunes Caml - yroeht - 10-01-2013

Un identifiant c'est un nom. Par exemple: toto, i, maSuperVariable. C'est un élément de la syntaxe des langages:

Code:
program := <expression>
expression := <letexp> | <intexp> | <stringexp> | <ifexp> | ...
letexp := let <identifiant> = <expression> in <expression>
intexp := [numeral]+
stringexp := "[character]*"
ifexp := if <expression> then <expression> [else <expression>]
...
Là où on dit que "let", "in", "for" sont des mots-clés, on dit également que "toto", "x", "MyVar" sont des identifiants.

Une variable, c'est un espace mémoire où une valeur est stockée. Par exemple, en C, si je dis "int toto = 42;", toto est l'identifiant d'une variable, qui a pour adresse &toto, et pour valeur 42.

La notion d'identifiant relève du langage de programmation, celle de variable relève de l'algorithme et du programme.


En OCaml c'est pareil que dans tous les langages... mais si vous décidez de penser fonctionnel pur, tout est valeur et fonction, puisque la notion de "mémoire" est abstraite de par l'absence d'effets de bords. Quand tu fais "let x = 42 in x + 1", tu as affaire à une valeur x qui vaut 42, et cette expression let... in a elle-même pour valeur 42+1=43. Il n'y a pas de variable qui se fait incrémenter.


Edit:
(09-26-2013, 22:38:48)tsunami33 Wrote: Bon alors déjà à savoir, les variables existent bel et bien en caml.

Oui, dans un contexte impur. Par exemple, en faisant
Code:
let x = ref 42 in x :=1 +  !x
, on a une variable x.

(09-26-2013, 22:38:48)tsunami33 Wrote: Voici un court exemple pour montrer la différence entre une variable et un identificateur :

let x = 1;;

Ici "x" est l'identificateur. C'est ni plus ni moins le nom de la variable. La variable ici c'est x, elle est de type int et vaut 1. On peut dire que l'identificateur "x" est déclaré avec le type des entiers et la valeur 1.

On peut dire ce qu'on veut. Moi, je dirais plutôt que tu as là défini une valeur x, qui vaut 1, et qui est de type entier. On pourrait aussi dire, si on n'est pas dans un contexte fonctionnel, qu'on déclare une variable constante dont l'identifiant est x, le type entier, et la valeur 1. Mais pas dans l'autre sens: on ne peut pas dire qu'on déclare un identifiant avec une valeur.

Edit: Les fonctions sont des valeurs, oui, mais les valeurs ne sont pas des fonctions, attention.

(09-30-2013, 01:40:25)Hatrix Wrote: Si vous voulez vraiment définir ce que c'est, fouillez les sources du compilateur pour voir ce qu'il se passe...

J'envisage plus ou moins de vous faire une conférence sur les détails de l'implémentation OCaml (représentation des valeurs, GC, inférence de types, concepts fonctionnels... que des trucs largement plus intéressants que les broutilles pour lesquels les gens se prennent la tête dans ce thread). En raison de mon incapacité à survivre devant un amphi d'inconnus (http://fr.wikipedia.org/wiki/Phobie_sociale , http://fr.wikipedia.org/wiki/Autisme), de l'emploi du temps chargé de GConfs, et du miens, j'ai aucune idée de si ça se fera.

Edit: Junior, si tu passes par là: bisous du fond de l'amphi A1 InfoSUP2014.


RE: Lacunes Caml - tsunami33 - 10-11-2013

Déjà excuse moi yroeht, j'avais lu ton message en vitesse avant un cours et je m'étais dit que j'y répondrais en rentrant chez moi. Entre temps j'ai oublié et je n'avais pas pensé à mettre la discussion en non-lu.

(10-01-2013, 22:17:49)yroeht Wrote: En OCaml c'est pareil que dans tous les langages... mais si vous décidez de penser fonctionnel pur, tout est valeur et fonction, puisque la notion de "mémoire" est abstraite de par l'absence d'effets de bords. Quand tu fais "let x = 42 in x + 1", tu as affaire à une valeur x qui vaut 42, et cette expression let... in a elle-même pour valeur 42+1=43. Il n'y a pas de variable qui se fait incrémenter.
Bon ben déjà merci pour la précision Smile Après quelques cours de caml supplémentaires, je crois que je commence à comprendre pourquoi tu dis ça. On va dire que ça m'éclaire un peu sur la façon de fonctionner de caml Wink (comment il interprète le code)

(10-01-2013, 22:17:49)yroeht Wrote: Oui, dans un contexte impur. Par exemple, en faisant
Code:
let x = ref 42 in x :=1 +  !x
, on a une variable x.
Là désolé mais mon niveau ne suit plus je ne comprends pas cette expression. J'imagine que ça viendra plus tard avec les cours. M'enfin si j'essaye de comprendre je vois que x est ici une sorte de pointeur... Mais bon je suis pas sûr du tout. Tu peux expliquer stp ? :/

Sinon je ne vois pas pourquoi dans ce cas là :
Code:
let x = 1;
on ne peut pas parler de variable x. Je vois une possibilité de fonctionnement pour caml :
La première ce serait qu'il y ait bien cette notion d'environnement dont on nous a parlé. C'est à dire qu'en gros, pour chaque endroit dans le code, caml aurait une certaine liste de valeurs associées à des identificateurs (qui seraient donc des variables c'est bien ça ou pas ?) et que chaque environnement soit stocké dans la RAM au même titre que n'importe quelle variable classique dans un autre langage. Par exemple on pourrait imaginer une implémentation en C qui prenne cette forme là :
Code:
enum {BOOL, CHAR, INT, FLOAT, STRING, OBJECT};

typedef struct Var Var;
struct Var
{
    int type;
    void* content;
    int* name;
    Var* nextElement;
}

typedef struct Environement Environement;
struct Environement
{
    Var* firstElement;
    Environnement* extends;
}
En gros donc, une structure Environement qui serait ici la tête d'une liste chaînée, qui pourrait également "contenir" un autre environnement (par exemple tous les environnements auraient extends pointant sur l'environnement des variables globales ou sur un de ses enfants. Ça évite de dupliquer des données.
Ensuite, on aurait Var qui serait une structure capable de contenir n'importe quel type de donnée (type qui serait indiqué dans la variable type pour savoir combien d'octets on doit lire pour avoir le contenu de la variable complet), donnée associée à un nom en caractères unicode, qui pointerait vers l'élément suivant dans la liste chaînée.
Ainsi à chaque lecture d'un identificateur dans une expression, caml fouillerait cette liste pour trouver un name qui match avec l'identificateur afin de retourner la valeur associée.
Dans ce cas, le fameux let x = 1 serait un simple ajout d'un élément dans la liste, et donc pourrait presque se résumer à une déclaration de variable toute bête.
Néanmoins la notion d'extends ne colle pas avec les réactions de caml. Par exemple avec ce code :
Code:
let x = 1;;
let f y = x + y;;
let x = 2;;
f 2;;
On a 3 comme réponse et non 4 dans le cas où l'environnement de f ne faisait qu'être une extension de l'environnement global. On peut donc penser que les variables sont copiées dans l'environnement de f (qui est créé à la déclaration de f) ce qui expliquerait que x vaille 1 dans cet environnement.
Dans le cas d'une fonction récursive il se passe un truc assez intéressant :
Code:
let x = 0;;
let rec f y =
    if y = 0 then
        0
    else
        let x = x + 1 in
            x + f (y-1);;
let x = 10;;
Ici en faisant f 3 on pourrait penser avoir 6 car :
Code:
f 3 => 1 + f 2 => 1 + 2 + f 1 => 1 + 2 + 3 + f 0 => 1 + 2 + 3 + 0 => 6
mais il se trouve qu'on a 3 !
Apparemment caml définit que dans l'environnement de f, x vaut x + 1 (soit 0 + 1 = 1), et ne change pas la valeur de x à chaque itération comme on pourrait penser qu'il le ferait. Et alors là je suis perdu. On voit que x est défini et ne bouge plus à partir du moment où f est déclarée, mais par contre y n'est défini qu'à l'exécution de la fonction. Ca tend à prouver que le x a été remplacé par sa valeur à la déclaration de f. Je ne sais pas pourquoi caml fait ça. Peut-être est-ce une tentative d'optimisation de fonction (la fonction sera moins longue à exécuter si caml n'a pas à recalculer x à chaque fois)

Si vous voyez un autre mode de fonctionnement de caml dites le moi. J'avoue ne pas avoir le coeur à regarder le code source de caml.

(10-01-2013, 22:17:49)yroeht Wrote:
(09-26-2013, 22:38:48)tsunami33 Wrote: Voici un court exemple pour montrer la différence entre une variable et un identificateur :

let x = 1;;

Ici "x" est l'identificateur. C'est ni plus ni moins le nom de la variable. La variable ici c'est x, elle est de type int et vaut 1. On peut dire que l'identificateur "x" est déclaré avec le type des entiers et la valeur 1.

On peut dire ce qu'on veut. Moi, je dirais plutôt que tu as là défini une valeur x, qui vaut 1, et qui est de type entier. On pourrait aussi dire, si on n'est pas dans un contexte fonctionnel, qu'on déclare une variable constante dont l'identifiant est x, le type entier, et la valeur 1. Mais pas dans l'autre sens: on ne peut pas dire qu'on déclare un identifiant avec une valeur.
D'accord mea culpa alors, j'ai fait un abus de langage. Disons simplement que si on imagine caml fonctionnant comme je l'ai détaillé au dessus, l'identifiant est "lié" à la valeur. Je voulais dire qu'on attribuait l'identifiant et la valeur à une seule et même variable.

(10-01-2013, 22:17:49)yroeht Wrote: Edit: Les fonctions sont des valeurs, oui, mais les valeurs ne sont pas des fonctions, attention.
Je n'ai pas dit ça. On est bien d'accord là dessus, une valeur n'est pas une fonction.

(10-01-2013, 22:17:49)yroeht Wrote:
(09-30-2013, 01:40:25)Hatrix Wrote: Si vous voulez vraiment définir ce que c'est, fouillez les sources du compilateur pour voir ce qu'il se passe...

J'envisage plus ou moins de vous faire une conférence sur les détails de l'implémentation OCaml (représentation des valeurs, GC, inférence de types, concepts fonctionnels... que des trucs largement plus intéressants que les broutilles pour lesquels les gens se prennent la tête dans ce thread). En raison de mon incapacité à survivre devant un amphi d'inconnus (http://fr.wikipedia.org/wiki/Phobie_sociale , http://fr.wikipedia.org/wiki/Autisme), de l'emploi du temps chargé de GConfs, et du miens, j'ai aucune idée de si ça se fera.

Edit: Junior, si tu passes par là: bisous du fond de l'amphi A1 InfoSUP2014.
Ce serait chouette si tu le faisais. Si c'est le cas sache que tu m'as déjà dans ton public. C'est intéressant de voir comment ça marche et le fait que ce soit expliqué par un conférencier évite d'avoir à passer un certain temps à se manger le code source de l'interpréteur.


RE: Lacunes Caml - yroeht - 10-12-2013

S'est-on vu hier ?

(10-11-2013, 01:56:39)tsunami33 Wrote:
(10-01-2013, 22:17:49)yroeht Wrote: Oui, dans un contexte impur. Par exemple, en faisant
Code:
let x = ref 42 in x :=1 +  !x
, on a une variable x.

Là désolé mais mon niveau ne suit plus je ne comprends pas cette expression. J'imagine que ça viendra plus tard avec les cours. M'enfin si j'essaye de comprendre je vois que x est ici une sorte de pointeur... Mais bon je suis pas sûr du tout. Tu peux expliquer stp ? :/
Il s'agit d'une référence. "!a" accède à la valeur, ":=" modifie celle-ci. On dit que la syntaxe est un peu moche parce que le concept derrière l'est lui-même, et que ça permet de décourager leur usage.
Pour information, tu remarques peut-être que ça ressemble beaucoup à un champ "mutable". En fait, une référence *est* un mutable:

Code:
type 'a ref = { mutable content : 'a }
let ref x = { content = x }
let deref r = r.content
let assign r x = r.content <- x; x

Mais oublie tout ceci; c'est pas fonctionnel, ça pue.

(10-11-2013, 01:56:39)tsunami33 Wrote: et que chaque environnement soit stocké dans la RAM au même titre que n'importe quelle variable classique dans un autre langage.

Oui, les définitions de valeurs forment des couples "nom - valeur" dans un environnement, et ceci est évidemment implémenté sous forme de variables.

Ce qui est vraiment important, c'est de comprendre que les valeurs / "variables constantes" ne peuvent pas subir d'affectation. Le programmeur OCaml ne peut pas modifier l'environnement courant, il ne peut qu'y ajouter des redéfinitions. L'exemple suivant *redéfinit* un nouveau x. Il ne modifie pas le premier x:

Code:
let x = 42 in
    let x = 43 in
    x


(10-11-2013, 01:56:39)tsunami33 Wrote: Dans le cas d'une fonction récursive il se passe un truc assez intéressant :
Code:
let x = 0;;
let rec f y =
    if y = 0 then
        0
    else
        let x = x + 1 in
            x + f (y-1);;
let x = 10;;
Apparemment caml [...] ne change pas la valeur de x à chaque itération comme on pourrait penser qu'il le ferait.

Non, car tu ne fais que redéfinir x localement à chaque appel.