Packages Example

Repository for the tests in PG104

This repository contains a set of code files for training the students in the PG104 functional programming course. These files are setup to be easily installed with automatic tests.

npm install     # Install the dependencies
make node_all # Launch all the tests
make eslint_all # Launch eslint on the files
make tsc_all # Launch tsc on the files one by one
make tsc_full # Launch tsc on all the files

To work with one exercise, say square, you can do :

make node.square
make eslint.square
make tsc.square

To work with the given code in src/utils, for example lazy, you can do :

make node_utils.lazy
make eslint_utils.lazy
make esc_utils.lazy

This is an example of a session where one uses the code inside the modules. First start node in the following manner :

node --experimental-repl-await

Then one only needs to load the modules by hand :

Welcome to Node.js v16.20.2.

> let L = await import("./src/utils/list.functional.api.js");
undefined
> let { anyToString } = await import("./src/utils/printers.js");
undefined
> L.cons(1, L.cons(2, L.nil))
{
car: 1,
cdr: {
car: 2,
cdr: { toStringFun: [Function: listToString] },
toStringFun: [Function: listToString]
},
toStringFun: [Function: listToString]
}
> anyToString(L.cons(1, L.cons(2, L.nil)))
'(|1, 2|)'

This section contains some texts that can be given to students to learn about the different test files.

  • Ecrire un module arrayhigh.js exportant (en tant que module ESM) deux fonctions scalarProduct et divisors. La fonction scalarProduct prend en paramètre deux tableaux d'entiers et renvoie leur produit scalaire, et doit utiliser les méthodes map et reduce provenant du prototype d'Array. La fonction divisors prend en paramètre un entier et renvoie le tableau de ses diviseurs strictement positifs, et doit utiliser la méthode filter provenant du prototype d'Array.
  • Ecrire un module cutting.js exportant (en tant que module ESM) une fonction cuttingStock prenant deux paramètres prices et length, et renvoyant la valeur de découpe optimale calculée dans l’exercice 4 de la feuille de TD n°3 (cf. https://www.labri.fr/perso/renault/working/teaching/functional/files/td3.pdf).

    Quelques modifications par rapport au TD : le paramètre prices doit être un tableau non vide, rempli d’entiers positifs, dont le premier élément est égal à 0, tandis que le paramètre length doit être positif. Toute forme d’erreur dans la fonction fait qu’elle renvoie undefined.

  • Ecrire un module reverse.js contenant une fonction reverseAt qui étant donné une liste l et un index i valide dans cette liste, renvoie une nouvelle liste avec les mêmes éléments, mais les éléments d'index < i ont été retournés. Les fonctions suivantes sur les listes sont disponibles dans les tests : cons, nil, head, tail et isEmpty. Par exemple, reverseAt(aList(1,2,3,4,5,6), 4) renvoie aList(4,3,2,1,5,6).
  • Ecrire un module same.js exportant (en tant que module ESM) :

    • Une fonction same curryfiée qui, étant donné un nom de champ c (sous la forme d’une chaîne de caractères), et deux objets o1 et o2, vérifie si o1 et o2 possèdent la même valeur (avec ===) pour le champ c.

    • Le module doit aussi exporter deux fonctions pointsInSameRowAs (resp. pointsInSameColAs) prenant un objet p (possédant les champs x et y) et un tableau arr d’objets (possédant tous les champs x et y), et filtrant les objets de arr ayant le même champ y (resp. le même champ x) que celui de l’objet p. Ces fonctions doivent réutiliser la fonction same. Ces fonctions ne doivent pas être curryfiées, et donc prendre leurs deux paramètres en même temps.

  • Ecrire un module sort.js exportant (en tant que module ESM) une fonction listSortGen qui, étant donné une liste l et un comparateur op renvoie la liste l triée. Le comparateur op est une fonction à 2 paramètres et renvoyant un booléen qui vaut true si et seulement si le 1er paramètre est inférieur ou égal au second. Les fonctions sur les listes sont disponibles dans un module situé en "src/utils/list.js" (chemin donné depuis la racine du dépôt). Le fichier en question est fourni ici.
  • Ecrire un module square.js exportant (en tant que module ESM) une fonction square. Cette fonction prend un paramètre x, et renvoie son carré.
  • Ecrire un module subset.js exportant (en tant que module ESM) une fonction isSubsetSum qui, étant donné un tableau d'entiers l et un entier v renvoie un booléen disant s'il est possible d'obtenir v comme somme d'éléments de l. Les entiers dans l sont rangés de manière décroissante. Les entiers dans l et l'entier v peuvent être positifs ou négatifs. La fonction isSubsetSum doit être récursive.

Les fichiers de code sont analysés avec un linter nommé ESlint. Un tel programme analyse les fichiers de code et effectue un ensemble de vérifications syntaxiques. Les différentes règles appliquées sont expliquées à cette adresse. Parmi les règles les plus communément incomprises :

  • no-mixed-spaces-and-tabs vérifie que le code ne contient pas à la fois des espaces et des tabulations. Un choix doit être fait entre les deux. Sous emacs, une solution consiste à utiliser M-x tabify ou M-x untabify.

  • semi vérifie que les instructions se terminent bien toutes par des point-virgules ;et permet de se prémunir des bugs dûs à l'insertion automatique des point-virgules.

Les modules EcmaScript sont décrits dans le dernier cours de PG104 sur la modularité, ainsi que sur cette page de la MDN. Les fichiers que vous devez produire doivent être des modules exportant les fonctions demandées. Se référer au cours et au TD pour réviser la syntaxe. Les mots-clés nécessaires sont principalement export pour les fichiers source, et éventuellement import pour les tests.

Vérifier les variables dans le Makefile

make install_repositories
git submodule foreach make -f /home/renault/teach/enseirb/functional/MachineTests/Makefile node.silent.cutting
# or
git submodule foreach make -f /home/renault/teach/enseirb/functional/MachineTests/Makefile node.silent.cutting 2> /dev/null > results.cutting.txt
make_reset_repositories

Vérifier qu'on a bien installé MELPA.

M-x package-refresh-contents
M-x package-install lsp-mode
M-x package-install lsp-mode-ui
M-x package-install company
npm config set prefix '~/.npm_root/'
echo 'export PATH="$HOME/.npm_root/bin/:$PATH"' >> ~/.bashrc
npm install -g deno
npm install -g typescript
npm install -g typescript-language-server