MOI MOI MOI MOI (← titre pourri d'un blog)

Written by katchup | read & comment (0)
published 2012-05-06 13:43:59
tags: maths, prépa

MPSI 832 - Fiche récapitulatif sur l'intégration

Non, finalement il n'y aura pas de fiche sur les matrices et les déterminants parce que c'est trop lourd et pas particulièrement utile.

Mais il y en a une sur l'intégration. Elle comporte aussi un récapitulatif (très succinct) de la partie sur l'intégration de fractions rationnelles et des fonctions avec du sqrt(a*x^2+b*x+c), ainsi que quelques primitives usuelles. J'ai sauté toute la partie sur les fonctions en escaliers, et les sommes de Riemann aussi, parce que franchement c'est pas ça qui pose problème.

Soit dit en passant, je suis aussi tombé sur une mine d'or ce matin. C'est bien, je suis content.

Written by katchup | read & comment (0)
published 2012-04-26 23:12:37
tags: informatique, pif, programmation, projets

PIF - Progression

Salutations,

Aujourd'hui fut une journée de grand avancement pour PIF. En effet, nous pouvons maintenant compiler et exécuter la fonction suivante, qui donne un résultat plutôt juste :

func integrate : (f : &(x : float) -> float, x0 : float, x1 : float, n : int) -> float {
    ## Calcul approché d'une intégrale par la méthode des trapèzes

    if x1 == x0 return 0

    let dx = (x1 - x0) / (n : float)

    var sum : float = 0
    var i = 0
    while i < n {
        let x = x0 + (i : float * dx)
        sum = sum + (f(x) + f(x + dx)) / 2 * dx
        i = i + 1
    }
    return sum
}

Ou sinon j'ai ça en stock - qui tourne et qui affiche des nombres premiers, bien sûr :

func find_primes : (max : int) -> {
    var i = 1
    while i < max {
        i = i + 1
        if !is_prime(i) continue
        print_int(i)
    }
    print_nl()
}

func is_prime : (num : int) -> bool {
    var d = 2
    while d*d <= num {
        if num % d == 0 return false
        d = d + 1
    }
    return true
}

(Remarque : print_int et print_nl sont des fonctions externes aux programmes, mais intégrées au compilateur)

À ceux que ça choque le if sans then et sans crochets non plus : en fait, j'ai choisi d'être le plus laxiste possible sur la syntaxe, c'est à dire que tant que le compilateur est capable de comprendre ce que vous voulez dire, alors c'est ok. Dans des cas plus délicats il peut être nécessaire de rajouter de la ponctuation, mais de manière générale vous mettez ce que vous voulez, comme vous voulez pour que ça soit à votre goût. Moi je voulais mettre des if sans then, et en l'occurrence ça ne pose pas de problème donc je me le suis permis.

En bref, les poins importants qui rendent tout ça possible :

  • Opérateurs divers
  • Vérification des types
  • Variables, affectation
  • Structures de contrôle basiques (pas de for pour l'instant, j'aimerai faire un joli for qui soit intégré avec la POO, mais ça va être un peu compliqué je le sens)
  • Pointeurs de fonctions

Ce qui sera fait bientôt :

  • Appel de fonctions et référencement de variables situées dans d'autres paquets
  • (?) Syntaxe pour les déclarations de plusieurs variables à la fois, valeurs par défaut pour les variables non initialisées, arguments par défaut pour les fonctions, syntaxe pour définir plusieurs arguments d'un seul coup, appel de fonctions en nommant les arguments, ...
  • ... qui sait ? des classes et des objets ? ça serait cool

Le code du compilateur est bien au chaud chez moi pour l'instant. Si quelqu'un en veut, je peux le mettre sur un GitHub. Il suffit de demander.

Written by katchup | read & comment (0)
published 2012-04-23 20:10:09
tags: informatique, pif, programmation, projets

PIF - Changement

Je suis en train de réfléchir à PIF, aux variables, aux types, aux références, et j'ai décidé de tout changer.

En fait, on ne fait que changer quelques mot-clefs. J'ai renommé let en var et const en let, ce que fait que l'on aura donc maintenant deux mot-clefs super proches, dont j'espère que la dénomination est suffisamment explicite, et dont il sera impératif de comprendre la distinction et le fonctionnement sous-jacent.

J'oublie ici tout ce qui était avant pour expliquer ce que je propose maintenant.

let

Lorsque l'on utilise un let, on crée juste un nouveau nom pour la valeur que l'on a donné. On n'a pas de référence sur cette valeur, ce qui signifie que l'on ne peut pas la changer.

let a = 42   # a est du type int, c'est à dire une valeur entière
a = 43       # invalide, ne compilera pas

C'est un peu comme ce que l'on fait en caml ou dans d'autres langages fonctionnels.

Remarquez en passant que les arguments d'une fonction sont immuables, c'est à dire que c'est comme s'ils avaient été déclarés avec un let.

var

Lorsque l'on utilise un var, on crée un nouvel espace mémoire que l'on remplit alors avec la valeur proposée, puis on attribue au nom donné la valeur d'une référence vers cet emplacement mémoire.

var a = 42  # a est du type &int, c'est à dire une référence sur un entier
a = 43      # ok ça marche

Le rapport avec la POO

Définissons le type suivant :

type Complex [
    re, im : float
]

Le problème vient des deux syntaxes suivantes, qui sont identiques :

var a : Complex = [12, 23]
var a = [12, 23] : Complex

Dans cette syntaxe lors de l'initialisation de l'objet avec les crochets, on crée un emplacement mémoire pour les données de l'objet de type Complex, obtenant ainsi une référence, c'est à dire un &Complex. On donne alors des valeurs aux variables de cet objet, puis (s'il y en a un), on appelle le constructeur sur cet objet, cela étant permis par le fait que l'on a une référence. Puis on déréférence ensuite l'objet pour obtenir une valeur de type Complex, qui est ensuite copiée dans un emplacement mémoire créée par le var pour obtenir une nouvelle référence. Que de complications.

Peut-être que ceci serait optimisé par LLVM, c'est d'ailleurs probable, celui-ci étant plutôt bien foutu. Mais fondamentalement, ça reste vraiment foireux. Mais heureusement, on peut aussi faire ça :

let a : &Complex = [12, 23]
# ou
let a = [12, 23] : &Complex

On crée ici une référence sur un Complex, qui n'est pas déréférencée mais bien attribuée telle quelle au nom a.

Lorsque l'on veut définir des objets que l'on souhaite bidouiller par la suite, il est donc impératif d'utiliser la deuxième syntaxe, avec un let et en spécifiant explicitement que l'on veut une référence, et pas la première.

Peut-être même plus

Peut-être faudrait-il, pour que cela soit encore plus parlant, introduire un constructeur de copie pour les types, c'est à dire une méthode qui serait appelée à chaque fois que l'on copie un objet dans un nouvel emplacement mémoire, que ce soit lors d'un var, lors du passage d'un objet comme paramètre, ou lors d'une affectation quelconque. On verrait alors bien que avec la première syntaxe présentée ci-dessus utilisant un var, on fait le cheminement suivant : construire A, copier A vers B, détruire A, alors que la syntaxe meilleure avec un let ne fait que construire A et le garder.

Written by katchup | read & comment (0)
published 2012-04-21 18:41:09
tags: informatique, pif, programmation, projets

PIF - Introduction

Salutations camarades, amis proches ou éloignés, de tous bords, de tous genres, de toutes origines, de tout penchants religieux ou politiques, de toutes orientations sexuelles, et bien plus que ça.

Je suis actuellement en train de travailler sur un nouveau langage de programmation, non pas pour faire un langage populaire, mais plutôt comme une expérience personnelle. J'ai choisi le chemin facile, à savoir que je laisse le gros de l'optimisation et de la compilation à LLVM.

Il y a plusieurs objectifs à un tel projet :

  • Créer un langage qui soit beau, lisible, facile à comprendre
  • Créer un langage qui soit simple à utiliser et à comprendre
  • Créer un langage qui soit plutôt rapide - donc compilé
  • Créer un environnement de programmation unifié, permettant de se mettre à coder rapidement des petites applications inutiles

Je l'ai déjà dit, mais il y a aussi un non-objectif : celui de concurrencer les langages existants.

Mais j'oublie un point important : ce langage s'appelle PIF, ce qui est un acronyme pour Programming Is Fun - ce qui montre bien l'état d'esprit du projet. Il s'agit d'un langage pour apprendre la programmation en s'amusant dans son coin, mais pas particulièrement prévu pour des gros projets. Comprendre aussi : c'est mon langage, c'est mon compilateur, alors je fait ce que je veux (et je vous emmerde - sauf votre respect).

Mais dans la pratique, ça ressemble à quoi ?

J'ai commencé à écrire les spécifications sur mon bloc-notes ici (document principal).

Types de base

Il n'y a que six types de bases : void, bool, byte, int, float, string (cf les spécifications). On pourra aussi utiliser des types de taille différentes pour les nombres entiers, mais globalement j'encourage à la simplicité et donc à n'utiliser que les six types de base, les autres n'ayant leurs utilité que lorsqu'il s'agit de communiquer avec le monde extérieur (comprendre : appel de fonctions de bibliothèques en C par exemple).

Il y aura aussi des types pour les tableaux. Ceux-ci fonctionneront d'une manière similaire aux tableaux de Go. Mais chaque chose en son temps, les tableaux ne sont pas du tout dans mes priorités pour l'instant. Les string non plus, d'ailleurs, parce que c'est vraiment un gros morceau.

Syntaxe

Je m'attend à ce que personne ne comprenne pourquoi j'ai choisi une telle syntaxe. En gros, il y a toujours à peu près deux raisons pour tel ou tel choix :

  • C'est lisible, compréhensible et joli pour un humain
  • C'est organisé de manière à ce que le compilateur puisse le comprendre sans trop de complications

Voici donc, sans attendre, des exemples de code :

################# MATH LIBRARY ###################
#       BECAUSE YOU LOVE MATH AND SO DO I
##################################################

######### BASIC MATH #########
## packages/pif/math/math.pif

Attention : non seulement s'agit-il ici d'un extrait de code de la bibliothèque pour faire des maths - qui en fait fait essentiellement appel aux fonctions de la libm - mais c'est surtout du code non réaliste, qui concrètement sera écrit autrement. C'est vraiment juste pour l'exemple. En passant, remarquez que les commentaires commencent par un #.

const pi : float = 3.1415926536
let tau = 2 * pi

Les deux lignes précédentes étaient assez explicites, je laisse le soin au lecteur de les comprendre. Remarquez l'utilisation du mot-clef let pour déclarer ses variables. Je l'ai choisi car var et def sonnaient très mal, défaut rédhibitoire pour mon idée - let est tout aussi conventionnel et compréhensible à mon avis. Remarquez aussi l'organisation de la déclaration de pi : le signe deux-points (:) indiquera toujours que ce qui suit est le type à considérer pour l'objet qui précède - il est donc utilisé dans toutes les déclarations, définitions de structures, etc.

func abs : (x : float) -> float {
    if x >= 0 then return x
              else return -x
}

C'est un dilemme pour moi : dois-je écrire la fonction abs qui prend un float pour renvoyer un float, ou dois-je l'écrire avec des int ? Vais-je devoir en écrire deux ? En tout cas, il n'est pas question d'implémenter de surcharge des fonctions, c'est bien trop lourd et anti-principes-fondamentaux-décrits-plus-haut.

Mais examinons ces lignes un peu plus en détail, car elles sont très révélatrices. D'abord, constatez que la fonction abs est du type noté (x : float) -> float, à comprendre qu'elle prend en argument un float appelé x, et renvoie un float. C'est plutôt clair, non ? Le nom de l'argument (ici x) prend son importance lorsqu'on a une fonction qui prend vraiment tout plein de paramètres, et que ceux-ci sont optionnels, et que l'on veut en préciser juste quelques-uns. Sinon, c'est pas trop grave.

Ensuite, il y a le if. Peut-être le classique if...then...else... vous fait penser trop à du vieux QBasic foireux - dans ce cas, tout peut s'arranger, parce que dès que l'on veut mettre plus qu'une seule ligne dans le corps du if, il est nécessaire d'utiliser des accolades pour délimiter un bloc de code, ce qui nous dispense alors d'écrire le then (mais vous pouvez aussi le mettre si ça vous fait plaisir, franchement je m'en fous). Dans ce cas précis, ça peut donner un truc comme ça :

# AUTRE VERSION, JUSTE POUR L'EXEMPLE
func abs : (x : float) -> float {
    let ret = x
    if ret < 0 {
        ret = -ret
    }
    return ret
}

C'est mieux ? Bien, passons à la suite :

func sqrt : (x : float) -> float
    extern sqrt

func cos : (x : float) -> float
    extern cos

Ces deux exemples illustrent typiquement la référence à une fonction externe, en l'occurrence on définit les fonctions sqrt et cos, toutes les deux du même type, et faisant références aux fonctions du même nom dans la libm.

func sin : (x : float) -> float {
    return (extern sin : (x : float) -> float) (x)
}

La fonction ci-dessus montre une autre façon de référencer une fonction externe. Ici c'est tout à fait inutile, mais c'est pour l'exemple. Remarquez que l'on a tout simplement importé la fonction sin en précisant son type, sans lui donner de nom particulier dans notre programme (c'est donc une fonction anonyme), puis on l'a appelée directement.

Maintenant, parlons un peu des pointeurs de fonction. Attention : les pointeurs sur fonction, c'est pas encore au point et je suis pas convaincu que ça va se faire exactement comme ça au niveau syntaxe, même si ça a l'air plutôt pas mal. Ce n'est pas encore rentré dans les spécifications.

func tan : (x : float) -> float {
    let externTanPtr : (x : float) -> float = extern tan
    return externTanPtr(x)
}

Cette fois c'est un peu pareil, sauf qu'on a utilisé un pointeur de fonction, auquel on a attribué une référence à la fonction externe tan. On a ensuite utilisé ce pointeur pour appeler la fonction.

Finalement, pour illustrer les fonctions anonymes et les pointeurs de fonctions, du code cette fois vraiment inutile :

let func_ref = func (val : float) -> float {
    return sqrt(val)
}

let sqrtOf2 = (func (val : float) -> float { return sqrt(val) }) (2)

Dans ce premier exemple, on définit un pointeur de fonction et on lui donne comme valeur une fonction qui a été créée sur le champ. Si le let avait été un const, cela aurait été l'équivalent approximatif d'une définition de fonction classique. Mais c'est moche et inutile, en fait, donc on préfère faire comme tout le monde et déclarer ses fonctions normalement.

Dans le deuxième exemple, on crée une fonction qui renvoie la racine carrée de l'argument, que l'on applique immédiatement avec l'argument 2, pour donner la valeur récupérée à la variable sqrtOf2.

Conclusion

Je ne suis moi-même pas tout à fait convaincu de ce nouveau langage que j'imagine aujourd'hui - et dont j'avais déjà commencer à coder un bout de compilateur, mais la syntaxe a changé depuis, alors je vais devoir modifier plein de trucs. Bref, voilà.

Dans le prochain épisode, s'il y a lieu, on parlera un peu des structures, des classes, des méthodes, etc.

Written by katchup | read & comment (0)
published 2012-04-13 19:41:39
tags: alex.auvolat.free.fr

Changement de titre & nouvelles fonctionnalités

Yo.

À partir de maintenant, le blog est ouvert aux commentaires. Je sais que personne ne va en poster, mais peu importe.

Je vous rappelle aussi que n'importe qui peut venir se créer un compte ici et poster sur le blog - j'invite tous les gens que ça intéresse à y participer. Si ce que vous écrivez est intelligent, il y a une chance pour que je m'y intéresse, et même que j'y réponde. Sinon, non. Si c'est débile - ou si c'est du spam, ce qui pourrait arriver - alors ça sera l'occasion pour moi de modifier quelques lignes de code pour me permettre de supprimer vos messages - plus facilement qu'à la main en trifouillant la BDD.

Bon bref voilà.

Written by katchup | read & comment (0)
published 2012-03-20 19:32:20
tags: maths, prépa

MPSI 832 - Documents divers

Pour ceux que ça intéresse (c'est à dire personne - en effet, les personnes que ça risque d'intéresser ne se baladent sûrement pas par ici), je met en ligne mes fiches de révision pour mon cours de maths à cette adresse. La plupart du temps, il s'agit globalement de recopier les théorèmes, définitions et propriétés du cours - mais en plus joli. La dernière en date concerne le cours sur la dimension finie, il y en a aussi une sur les plolynômes et les fractions rationnelles, les développements limités, la dérivation, ainsi qu'une cheat sheet avec toutes les formules de trigo qu'il faut impérativement savoir par cœur, sous peine de rater sa vie et de mourir non seulement sans avoir rien achevé de grand et mémorable pour l'humanité, mais aussi tout simplement en ignorant la vérité profonde - et pourtant toute simple - des mathématiques. Je vais probablement en faire une sur les matrices et les déterminants aussi, parce que c'est un cours plutôt compliqué. Sinon, il y a aussi les DM que je rédige à l'ordi, ce qui n'a aucun intérêt même pour moi, si ce n'est que... *ahem*, bref ça ne vous regarde pas.

Written by katchup | read & comment (0)
published 2012-03-18 14:18:32
tags: art, informatique, maths, programmation

Quand on s'ennuie...

... on dessine des fractales (à la main bien entendu).

Voici le résultat : dossier de fractales

Pour ceux que ça intéresse, le code en Caml qui a permi de les générer :

#open "graphics";;
open_graph " 1024x768+0-0";;

(* HSV to RGB *)
let hsv h s v =
    let c = v *. s in
    let hh = (h mod 360)/60 in
    let hhf = (mod_float (float_of_int h) 360.) /. 60. in
    let x = c *. (1. -. (abs_float (mod_float hhf 2. -. 1.))) in
    let m = v -. c in
    let cc = int_of_float ((c +. m) *. 255.) in
    let xx = int_of_float ((x +. m) *. 255.) in
    let mm = int_of_float (m *. 255.) in
    match hh with
    | 0 -> rgb cc xx mm
    | 1 -> rgb xx cc mm
    | 2 -> rgb mm cc xx
    | 3 -> rgb mm xx cc
    | 4 -> rgb xx mm cc
    | 5 -> rgb cc mm xx
    | _ -> rgb mm mm mm;;


(* complex numbers *)
let zeroC = (0., 0.);;
let addC (a, b) (c, d) = (a+.c, b+.d);;
let mulC (a, b) (c, d) = (a*.c -. b*.d, a*.d +. b*.c);;
let absC (a, b) = sqrt(a**2. +. b**2.);;

(* drawing *)
let pos (xmin, xmax, ymin, ymax) (x, y) =
    int_of_float((x-.xmin)*.(float_of_int(size_x()))/.(xmax-.xmin)),
    int_of_float((y-.ymin)*.(float_of_int(size_y()))/.(ymax-.ymin));;
let pos_inv (xmin, xmax, ymin, ymax)  (x, y) =
    float_of_int(x)*.(xmax-.xmin)/.(float_of_int(size_x()))+.xmin,
    float_of_int(y)*.(ymax-.ymin)/.(float_of_int(size_y()))+.ymin;;


(* mandelbrot & julia fractal *)
let iter = 300;;

let color_frac n =
    if n = iter then set_color black
    else set_color (hsv (n*4+200) 0.7 0.6);;

let mandel_pt c =
    let rec aux z n =
        if n = iter then n
        else if absC z >= 2. then n
        else aux (addC (mulC z z) c) (n+1)
    in
        aux zeroC 0;;

let mandel repere =
    for i = 0 to size_x() do
        for j = 0 to size_y() do
            let x, y = pos_inv repere (i, j) in
            let n = mandel_pt (x, y) in
            let px, py = pos repere (x, y) in
            color_frac n;
            plot i j
        done
    done;
    set_color black;
    moveto 10 10;
    draw_string ("mandelbrot  iter = " ^ (string_of_int iter))  ;;

let julia_pt c z0 =
    let rec aux z n =
        if n = iter then n
        else if absC(z) >= 2. then n
        else aux ((addC (mulC z z) c)) (n+1) 
    in aux z0 0;;

let julia repere (a, b) =
    (* clear_graph(); *)
    for i = 0 to size_x() do
        for j = 0 to size_y() do
            let x, y = pos_inv repere (i, j) in
            let n = julia_pt (a, b) (x, y) in
            let px, py = pos repere (x, y) in
            color_frac n;
            plot i j
        done
    done;
    set_color black;
    moveto 10 10;
    draw_string ("julia " ^ (string_of_float a)
                                ^ " + " ^ (string_of_float b)
                                ^ "i   iter = " ^ (string_of_int iter));;

let repere = (-.1.6, 1.6, -.1.5, 1.5);;
mandel repere;;
julia repere (0.3, 0.01);;
julia repere (0.3, 0.024);;
julia repere (0.33, 0.024);;
julia repere (0.18, 0.7);;
julia repere (-.0.54, 0.55);;
julia repere (-0.4, 0.6);;
julia repere (0.285, 0.01);;
julia repere (-0.70176, 0.3842);;
julia repere (-0.835, 0.2321);;
julia repere (-0.8, 0.156);;

Pour pouvoir profiter du spectacle, je vous invite à utiliser ce code avec un IDE permettant l'execution pas-à-pas du code (LinCaml, WinCaml ou autre MacCaml), ou à le rentrer directement à l'invite OCaml.

Written by katchup | read & comment (0)
published 2012-03-07 15:29:00
tags: critique, idées, informatique

OS & langages : pensées noires du jour

L'utilisateur lambda, c'est tout à fait normal qu'il se tourne vers les solutions privatrices que tout le monde connaît (pour ne pas les citer, Windows et Mac OS X). Et pourquoi ? Parce que ces systèmes sont meilleurs, d'un point de vue technique et fonctionnel. En effet, les systèmes d'exploitation alternatifs libres souffrent de défauts majeurs, que je tenterai de développer ici :

  • Trop d'API (par exemple : l'audio sous Linux), trop de frameworks (ex: QT, GTK, etc.), qui ne travaillent pas de concert
  • Manque de stabilité, manque de prise en charge de certains matériels (sont concernés : certains BSD, Haiku (qui est pourtant un bel effort !), ...)
  • Peut-être qu'Unix n'est tout simplement pas adapté pour servir l'utilisateur lambda ; peut-être qu'Unix se fait vieux, et qu'il faudrait passer à autre chose
  • Un manque de direction généralisée laisse les développeurs en vadrouille, chacun sur son projet, à sa manière, sans s'imposer nécessairement les directives élémentaires de la bonne programmation (comprendre : les gens codent comme des pieds)
  • Des langages inadaptés
  • Pour l'utilisateur lambda, il en résulte un manque de fonctionnalités que l'on pourrait qualifier d' "élémentaires", ou presque

Pour résumer vite fait : les systèmes d'exploitation aujourd'hui sont soit bordéliques et inadaptés au grand public, soit privateurs. Dans un tel contexte, ce n'est pas tout à fait anormal que la majorité des utilisateurs renoncent à leurs libertés pour utiliser un système qui leur convient mieux.

Développons un peu, point par point :

Les problèmes

C'est le bordel

Techniquement

Oui, c'est le bordel du côté des systèmes GNU/Linux. Déjà, il y a une infinité de distributions, toutes avec des outils différents pour faire, au final, globalement la même chose. Par exemple :

  • Plein de gestionnaires de paquets, qui offrent sensiblement les mêmes fonctionnalités (juste avec des lignes de commande différentes, et plus ou moins optimisés - duh)
  • Plein de mécanismes d'init différents (System V, upstart, systemd, openrc (gentoo), et j'en passe sûrement)

Mais considérons que, tant que les distributions restent cohérentes en elles-mêmes sur ces points, ça peut encore aller - d'autant plus que chaque distribution peut avoir un objectif précis, qui ne peut être réalisé qu'à l'aide d'un outil en particulier. En fait, il y a beaucoup plus gênant :

  • Il y a, par exemple, 42 façons différentes de programmer une application qui utilise les périphériques audio (clivage ALSA/OSS, utilisation ou non de PulseAudio, quelle bibliothèque choisir, etc.). C'est sûrement le cas aussi avec d'autres API.
  • Il y a parfois un gros paquet de bibliothèques qui font la même chose (exemple : gstreamer/xine/mplayer/vlc/etc...), et selon les applications que l'on utilise, on est en général obligé d'en installer plein de différentes.
  • Par rapport aux toolkit graphiques, on a le traditionnel clivage GTK/QT, on a des frameworks qui se rajoutent là dessus (les kdelibs par exemple), tant bien que le programmeur quelconque qui veut coder une application de bureau pour son système GNU/Linux sera obligé de choisir parmi plein de bibliothèques ayant toutes des avantages et des inconvénients, souffrant en général de problèmes de compatibilité, et étant obligé, pour bénéficier de certaines facilités, de lier son application à un environnement de bureau en particulier, obligeant encore une fois l'utilisateur à installer plein de bibliothèques juste pour une application (par exemple : si ktorrent ne dépendait pas de plein de morceaux de KDE, je m'en servirait probablement).

Personnellement, j'ai déjà voulu coder des "petites" applications de bureau, et j'étais complètement perdu dans le choix du langage de programmation et des bibliothèques et toolkits à utiliser, tant bien que j'ai la plupart du temps abandonné mon projet avant même de le commencer.

Dans la communauté

Globalement, j'aurai tendance à dire que dans le mouvement du logiciel libre, le développeur lambda tendance à coder son projet chacun dans son coin, en suivant ses tendances personnelles, ce qui de toute évidence n'aide pas à résoudre les problèmes ci-dessus.

Il serait beaucoup plus intéressant que, au lieu de vouloir promouvoir chacun son projet et sa manière de faire, les développeurs de tous bords aient une volonté commune d'avancer vers un idéal, un système qui ait une certaine forme de cohérence. Cela n'implique pas forcément que l'on impose une hiérarchie aux développeurs, c'est plutôt une prise de conscience globale, qui permettrait que chacun réfléchisse à ce qui est mieux pour la globalité, et oriente son travail dans cette direction là, plutôt que de partir chacun dans son coin.

C'est pas pratique, pas fonctionnel

Un exemple très simple devrait vous permettre de comprendre globalement où je veux en venir : où sont, mais bordel de merde où sont les logiciels de reconnaissance vocale pour Linux ? Ah ben non, il n'y en a pas. Pourtant, c'est sacrément utile, dans certains cas. En tout cas, l'utilisateur lambda, lui, il fait de la bureautique, et selon ses activités il peut être très content, voir même avoir besoin, de pouvoir dicter ses documents, pour toutes les raisons que vous pouvez imaginer. (Je connais plusieurs personnes qui ne pourraient pas vraiment se passer de ça).

Je n'ai plus d'idées pour développer ce point. Veuillez m'en excuser.

Unix, ça suffit

Moi je dis, regardez : le système le plus populaire, et qui semble largement satisfaire (quand même hein, il faut le dire!), n'est pas basé sur Unix. Oui, c'est pour moi une preuve flagrante qu'Unix n'est peut-être tout simplement pas adapté à l'utilisateur lambda. Ou en tout cas, sous sa forme actuelle de GNU/Linux, il ne l'est pas. Remarquons quand même qu'Apple a réussi à en faire quelque chose d'orienté grand-public, et franchement je pense qu'ils ont réussi.

En fait, le problème vient essentiellement du fait qu'Unix, encore une fois, est multiple : il y a plein de systèmes d'init, plein d'interpréteurs de commandes différents, plein d'implémentations de la libc qui varient sur des poins fondamentaux, mais qui au final offrent nombre de différences parfois subtiles dans les interfaces offertes au programmeur, obligeant l'utilisation d'un système appelé autotools, qui alourdit considérablement le processus de développement d'applications.

En fait, il faut effectivement admettre que jeter tout Unix à la poubelle et repartir sur autre chose, ça risque d'être très difficile. On peut peut-être s'en contenter, mais il faut voir aussi où sont les problèmes, et essayer de faire avec pour construire, encore une fois, quelque chose de cohérent.

Programmer aujourd'hui : pas de langage satisfaisant

Les gens codent mal

Il y a deux types de programmeurs, et j'aurai tendance à les différencier selon la génération à laquelle ils appartiennent :

  • Les vieux de la veille, qui ont grandi avec du Basic sur commodore 64, qui codent en C, à gérer tous les détails à la main, pour coder au final des applications efficaces et bien codées en général, et ça c'est bien.
  • Les petits jeunes, qui ont grandi avec du PHP/HTML/Javascript, du Python, du Ruby, du Caml, et plein d'autres langages de haut-niveau, et qui n'ont plus vraiment le sens du code bien écrit, qui ont tendance à aller à la facilité, etc.
  • Enfin, il y a les ingénieurs certifiés (lol), qui sont spécialisés par exemple en Java, et qui ne savent utiliser que certains frameworks très spécifiques auxquels ils ont été formés. Ces gens sont aussi appelés pisseurs de code, travaillent en général pour une entreprise qui a besoin d'un logiciel pour des besoins spécifiques, et n'ont pas vraiment non plus le sens du code bien écrit.

En fait, l'augmentation exponentielle des performances des systèmes conduit à un certain laisser-aller de la part des développeurs, se disant que s'ils ne codent pas bien, ce n'est pas grave parce qu'un algorithme en O(n²) s'exécutera aujourd'hui (sur des petits ensembles de données) aussi rapidement qu'un algorithme en O(log n) sur du matériel d'il y a 10 ou 20 ans. En fait, je crois même qu'il y a une portion de programmeurs qui ne s'en rendent même pas compte, tout simplement car comme ils ne voient pas la lenteur de leurs programmes (ou alors celle-ci leur parait négligeable), ils vont rester sur un algorithme inefficace, se disant que ça ira bien.

De manière générale, on peut donc dire que les gens qui codent ne codent pas forcément bien, ce qui conduit au principe suivant, bien connu de tous (ou pas ?) : les logiciels deviennent plus lents (bloatware, mal codés, etc.) plus vite que les ordinateurs deviennent plus performants et plus rapides.

En toute logique, les applications que l'on avait déjà il y a 20 ans (mail, traitement de texte, etc.) devraient être soit vraiment vraiment plus rapides, soit vraiment vraiment plus riches en fonctionnalités aujourd'hui qu'à l'époque. En pratique, certes on a plus de fonctionnalité, mais pas forcément tant que ça, et surtout on n'a pratiquement pas gagné en vitesse d'exécution de ces programmes. C'est un peu problématique, vous en conviendrez.

Quel langage utiliser ?

En fait, le problème vient aussi des langages de programmation que nous avons à disposition. Globalement, il y a deux options : * Coder en C (ou en C++ éventuellement), ce qui implique de se faire chier à un certain degré dès que l'on veut coder des trucs un peu complexes * Coder dans un langage interprété, par exemple Python, qui offre plein d'outils et de bibliothèques pour programmer simplement des applications assez complexes, mais finalement Python étant un langage interprété il n'est pas adapté non plus pour des projets qui doivent traiter une masse de données.

C'est pourquoi je suis sidéré aujourd'hui de voir que l'on a écrit Tribler, un client BitTorrent aux fonctionnalités certes révolutionnaires, mais en python quoi, bordel de merde ! J'avais à peine lancé le logiciel et effectué quelques recherches que celui-ci me bouffait quelques centaines de Mo de RAM. C'est absolument inadmissible, je n'ai que 2Go moi ! Au secours !

Dans le même genre, j'ai essayé plein de lecteurs de musique, et finalement la plupart étant écrits effectivement en Python, ils avaient tendance à ramer (un peu) quant à la gestion de ma bibliothèque, qui n'est pourtant pas si grosse que ça. (Enfin si, mais même : c'est normalement le propre de ces logiciels que de savoir gérer une collection importante de musique. Je me trompe ?). Mais ça dépend des logiciels, certains sont mal écrits, d'autres pas si mal, et j'ai plus ou moins fini par trouver une solution satisfaisante. Mais je me suis fait chier. Sous Windows, j’aurai tout simplement utilisé le Windows Media Player, et sous Mac OS X je me serai contenté d'iTunes, qui niveau fonctionnalités et vitesse d'exécution sont franchement satisfaisant, le principal défaut étant celui que vous êtes tous là à me pointer du doit - ce sont des logiciels privateurs.

Mais les fautifs dans l'histoire, ce sont peut-être les langages de programmation eux-même : il est difficile (voir impossible, et même s'il existait, alors il est bien trop peu connu) de trouver un langage qui réunisse les avantages suivants : * Rapidité d’exécution (ce qui implique globalement qu'il soit compilé, éventuellement JIT) * Retour rapide pour le développeur (temps de compilation nul ou négligeable, ce qui n'est pas le cas avec C, C++, Vala, etc.) * Facilité d'écriture (orienté objet, ramasse-miettes, librairie standard fournie, syntaxe pas trop lourde). Remarquez que cela n'implique pas pour moi que le langage n'est pas typé, au contraire, je défend le typage fort pour imposer un peu de rigueur chez le programmeur. Mais même, on peut faire un langage qui soit plus facile à utiliser tout en étant assez fortement typé. * Possibilité de s'intégrer avec la majorité des bibliothèques C ou C++ dont tout le monde à besoin (GTK ou QT, bibliothèques multimédia, etc.)

Les conséquences

Du côté du grand public, vu que de toute évidence les logiciels libres ne sont pas prêts, il est tout à fait naturel que les utilisateurs préfèrent les solutions privatrices bien connues de tous. Pourtant, le but du logiciel libre n'était-il pas de permettre à tout un chacun (même les plus incompétents et imperméables à l'informatique) de reprendre le contrôle de son PC ? J'aurai tendance à dire : RMS fail. Mais ça n'engage que moi (comme tout cet article, d'ailleurs).

Du côté des développeurs, l'esprit qui règne dans la communauté des logiciels libre n'est pas vraiment satisfaisant, comme je l'ai déjà dit, chacun voulant avancer dans son coin à faire son projet avec ses idées et la méthode qui lui parait à lui la plus satisfaisante (parfois d'un point de vue qui ne prend en compte que ce qu'il connaît déjà, donc voilà quoi). Il en résulte donc que pour l'instant, on est dans un plutôt gros merdier (c'est franchement pas très agréable) qui n'a pas l'air d'avancer beaucoup.

Les solutions

Déjà, il faudrait que tout le monde se rende compte qu'il y a un problème. On pourrait en discuter un peu sérieusement, plutôt que de troller (enfin ceci dit je n'ai pas dit que troller c'est mal, d'ailleurs je suis probablement moi-même en train de troller, et c'est une bonne chose car ça me permet de dire ce que j'en pense. Là où il y a un problème, c'est quand le débat n'avance pas et qu'il en résulte de la merde).

Déjà, moi je pense qu'il faudrait que tout le monde s'impose de coder bien, proprement, avec rigueur, etc. Le problème, c'est que parmi les gens que je fréquente (comprendre : parmi les autres élèves de prépa maths/physique), même parmi ceux qui s'intéressent à l'informatique et à la programmation, aucun ne semble avoir le goût du code bien écrit, ni la clarté d'esprit requise pour coder bien. C'est dommage. Et ce n'est pas notre prof d'informatique qui aide à développer ça. C'est dommage aussi.

Sinon, sur un ton plus radical, et c'est ce que j'aurai bien envie de faire - malheureusement, tout seul je ne vais pas aller bien loin - il y aurait la possibilité de faire table rase et de concevoir un nouveau système d'exploitation, basé sur un nouveau langage de programmation (ou deux éventuellement, si on veut séparer le vraiment bas niveau, c'est à dire le noyau, les périphériques, et les systèmes de fichiers, et le moins bas niveau, ce qui semble effectivement logique ; mais essentiellement toutes les applications seraient alors écrites avec le langage de haut niveau, qui sera de toute façon totalement optimisé aussi bien pour les performances que la facilité d'écriture), le tout étant planifié à l'avance pour avoir une cohésion globale, c'est à dire qu'il faudrait, à défaut d'imposer le totalitarisme au développeur, au moins débattre et décider une fois pour toute de comment le système sera organisé, et ensuite gérer le projet de manière à n'accepter que le code qui suit cette organisation - et accessoirement, qui satisfait des critères de bien-écriture que l'on définira aussi à ce moment. Mais c'est peut-être un peu utopique (voir beaucoup), donc voilà, globalement je ne sais pas si on peut faire grand chose.

Written by katchup | read & comment (1)
published 2012-02-12 20:28:52
tags: alex.auvolat.free.fr

Le début de la fin (ou peut-être pas)

Plop.

Un petit mot pour anoncer au gens que j'ouvre ici un blog, parce que j'en avais envie. Il s'agit d'un blog à écriture publique, c'est à dire que n'importe qui peut poster en créant un compte. Je modère les posts merdiques, bien entendu. Mais si vous venez pour critiquer le capitalisme, discuter de questions métaphysiques, annoncer vos exploits de programmation, partager vos lectures de manga, ou autres sujets potentiellements intéressants, je vous en prie.

Commençons donc par les modifications que j'ai apportées au code du site :

  • Demande de l'adresse e-mail lors de l'inscription de quelqu'un
  • Possiblilité de donner un titre aux images uploadés sur le site, suppression du quota d'upload (limitation ridicule, quand on y pense - et de toute façon personne ne s'en sert)
  • Création de ce système (fort incomplet) de blog

Ce qu'il reste à faire :

  • Flux RSS pour le blog (EDIT: fait)
  • Système de commentaires pour le blog (EDIT: fait)
  • Possibilité de récupérer un mot de passe perdu, grâce à l'email demandée lors de l'enregistrement
  • Possibilité de ranger ses images dans des galeries. (EDIT: fait)

Désolé, mais je n'ai pas vraiment le temps de poster aujourd'hui. Je serai bientôt de retour avec un billet scientifique/philosophique/anarcho-communiste/geek/otaku/autre.

Filter by author

Filter by date

Filter by tag

...