Aucun message portant le libellé programmation. Afficher tous les messages
Aucun message portant le libellé programmation. Afficher tous les messages

samedi, mars 17, 2007

Calcul symbolique en Scheme

Il y a quelques semaines, j'ai commencé à lire "Structure and Interpretation of Computer Program" (ci-après référé comme SICP) de Harold Habelson et Gerald Jay & Julie Sussman du MIT. Ça n'avance pas très vite car c'est extrêmement dense. Il faut du temps pour lire et relire et pour faire les exercices. Pour ce faire, j'ai installé Guile comme interpréteur Scheme sur ma station de travail principale. J'utilise Kate comme éditeur. C'est pas ce qu'il y a de mieux mais ça fait la job.
Lisant le chapitre 2 de SICP, la section 2.3.2 a vraiment capté mon attention (en tant que physicien de formation): Elle porte sur le calcul symbolique. Je n'avais jamais utilisé un langage qui permettait ceci sauf peut-être le langage interne de Mathematica (dont l'ancêtre a été écrit en Lisp dont Scheme est un dialecte). Pour m'assurer de bien comprendre, j'ai fait l'exercice 2.56. J'ai par la suite tenté de l'étendre pour faire la dérivation de la fonction sinus. Initialement j'avais écris:

    ;Definition for sine

(define (sine? x)
(and (pair? x) (eq? (car x) 'sin)))

(define (sine-argument angle) (car angle))

(define (make-sine angle)
(cond ((=number? angle 'pi) 0)
((=number? angle 0) 0)
(else (cons 'sin angle))))

(define (make-cosine angle)
(cond ((=number? angle 'pi ) 1)
((=number? angle 0) 1)
(else (cons 'cos angle))))


mais sine-argument retournait toujours (x) au lieu de x. Ce qui faisait planter deriv un peu plus loin. Après avoir fouillé pas mal, et lu et relu une obscure note de bas de page. J'ai trouvé le bobo: car retourne toujours un élément unique entouré de parenthèses. Pour retourné un élément unique sans parenthèses, il faut utiliser list-ref.
On aura:

(car '(a b)) -> (a)
(list-ref '(a b) 0) -> a


Une fois cette modification faite, on obtient la solution pour 2.56 plus le cas pour la fonction sinus:

(define (variable? x) (symbol? x))

(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2) (eq? v1 v2)))

(define (make-sum a1 a2)
(cond ((=number? a1 0) a2)
((=number? a2 0) a1)
((and (number? a1) (number? a2)) (+ a1 a2))
(else (list '+ a1 a2))))

(define (=number? exp num)
(and (number? exp) (= exp num)))

(define (make-product m1 m2)
(cond ((or (=number? m1 0) (=number? m2 0)) 0)
((=number? m1 1) m2)
((=number? m2 1) m1)
((and (number? m1) (number? m2)) (* m1 m2))
(else (list '* m1 m2))))

(define (sum? x)
(and (pair? x) (eq? (car x) '+)))

(define (addend s) (cadr s))

(define (augend s) (caddr s))

(define (product? x)
(and (pair? x) (eq? (car x) '*)))

(define (multiplier p) (cadr p))

(define (multiplicand p) (caddr p))

; definitions for exponentiation

(define (make-exponentiation base exponent)
(cond ((=number? exponent 0) 1)
((=number? exponent 1) base)
(else (list '** base exponent))))

(define (base exponentiation) (cadr exponentiation))

(define (exponent exponentiation) (caddr exponentiation))

(define (exponentiation? x)
(and (pair? x) (eq? (car x) '**)))

;definitions for sine

(define (sine? x)
(and (pair? x) (eq? (car x) 'sin)))

;Here, car doesn't work but list-ref works(define (sine-argument angle) (list-ref angle 1))


(define (make-sine angle)
(cond ((=number? angle 'pi) 0)
((=number? angle 0) 0)
(else (cons 'sin angle))))

(define (make-cosine angle)
(cond ((=number? angle 'pi ) 1)
((=number? angle 0) 1)
(else (cons 'cos angle))))

(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp)
(if (same-variable? exp var) 1 0))
((sum? exp)
(make-sum (deriv (addend exp) var)
(deriv (augend exp) var)))
((product? exp)
(make-sum
(make-product (multiplier exp)
(deriv (multiplicand exp) var))
(make-product (deriv (multiplier exp) var)
(multiplicand exp))))
((exponentiation? exp)
(make-product
(make-product (exponent exp)
(make-exponentiation (base exp)
(make-sum (exponent exp) -1)))
(deriv (base exp) var)))
((sine? exp)
make-product (deriv (sine-argument exp) var)
(make-cosine (sine-argument exp)) )
(else
(error "unknown expression type -- DERIV" exp))))



Je vais essayer d'étendre encore plus ce programme dès que j'en aurai le temps. À suivre...

vendredi, février 23, 2007

Expansion spirituelle

Les langages fonctionnels sont aux programmeurs ce que le LSD était aux hippies: ils élargissent l'esprit ;-)

mercredi, février 14, 2007

Sur les langages

Deux thèmes, un seul mot ce matin: langages.
Je prends des cours de chinois. Un soir par semaine. C'est peu mais c’est intellectuellement stimulant.

Ce que je trouve intéressant, c'est de comparer comment on dit une chose équivalente d'une langue à l'autre. Je parle couramment le français et l'anglais et j'ai déjà étudié le japonais et l'allemand. Je peux donc faire quelques comparaisons.
En japonais et en chinois, il y a des mots d'énumération. C'est un mot que l'on met entre le cardinal et l'objet compté et qui nous renseigne, un peu, sur la nature de l'objet compté. En japonais comme en chinois il existe un mot réservé au compte d'objet de forme ronde ou sphérique. Si on vous mentionne un mot que vous ne connaissez pas mais qui est précédé du mot d'énumération (et d’un cardinal!) pour les objets ronds ou sphériques, vous faites l'acquisition d'une information supplémentaire, qui jumelée au contexte, vous permet de (peut-être) deviner le sens du mot inconnu. Pratique.
Prenez aussi par exemple les pronoms relatifs en français. Avez-vous pensez ce que la langue serait sans eux? La phrase "La femme dont le mari est gros.." deviendrait "La femme, elle a un mari gros, ...". Même si les deux phrases ont la même signification, la première forme sonne mieux. Un petit mot, "dont", influence la syntaxe et la rend expressive (si vous trouvez un meilleur exemple, dites-le moi).

Le concept « d'expressivité par la syntaxe » n'existe pas que pour les langages humains. Il existe aussi pour les langages informatiques. On a qu'a comparer les langages de type fonctionnel (F#, ML, Erlang, Haskell, ...) aux langages impératifs (Java, C, ...). Leurs syntaxes sont radicalement différentes. Ils parviennent tous à exprimer les mêmes concepts mais sans les mêmes structures. Pour certains types de programmes, les langages de type fonctionnel mènent à des solutions plus élégantes.

Je m’intéresse pas mal ces temps-ci aux langages fonctionnels. J’étudie Lisp/Scheme et j’aimerais bien avoir le temps de jeter un coup d’œil à Haskell ou Erlang (ce dernier se prêtant pas mal bien à la programmation concurrentielle). Je trouve stimulant d’être exposé à autre chose que des langages impératifs auxquels tous sont familiers. Je suis convaincu qu’apprendre sur les langages fonctionnels fera que je serai plus productif et clair avec les langages impératifs que j’utilise les plus souvent.


En Lisp, en écrivant une macro on créé une nouvelle structure du langage qui altère la structure, la rendant plus expressive. Cette caractéristique du langage n'existe pas dans les langages de type impératifs.

En Haskell, par le biais du « pattern matching » on peut décrire à l’intérieur de la signature d’une fonction des cas d’utilisation de celle-ci plutôt que de recourir à une structure de type « case » dans le corps de la fonction.

Voilà pour ce matin. Si je pense à autre chose, je l'écrirai.

jeudi, janvier 18, 2007

Installation de Subversion

J'ai finalement installé Subversion sur la machine virtuelle VMWare qui est sur mon laptop. J'ai suivi les instructions là. Mais attention! L'information donnée sur les permissions d'accès n'est pas correcte. Le bon format est donné ici.
L'intégration de Subversion dans NetBeans 5.5 est admirable. On se sert de Subversion sans même s'en rendre compte. J'ai installé NetBeans sur une machine W2K en plus de sur mon laptop (car je n'ai pu l'installer sur ma machine XP principale). C'est bien de pouvoir utiliser NetBeans sur un écran en 1600X1200!
Ce soir je vais à une conférence au Musée des Beaux-Arts!

vendredi, janvier 12, 2007

Mondrian Code Review On The Web



Google Tech Talks
November 30, 2006

ABSTRACT

Mondrian Code Review On The Web


Video pas mal intéressant par Guido van Rossum démontrant "Mondrian", son nouveau système de revue de code pour les gningnégnieurs de Google. J'aimerais bien voir ça être OpenSourcé. Ça serait une brillante addition à CVS ou Subversion.

mardi, janvier 09, 2007

"Bug" avec NetBeans 5.5?

J'ai tenté à plusieurs reprises d'installer NetBeans 5.5 sur mon desktop Window$ XP. La seule manière de faire est d'installer premièrement le JDK sur le drive C:. Ça m'enrage, mes programmes sont tous sur le drive D:. Bug?
Mise-à-jour: Impossible à installer! Sais pas pourquoi, je devrai investiguer... Entretemps je devrai faire du java sur le laptop...

mercredi, décembre 13, 2006

Mauvais timing

Hier après-midi, j'ai acheté le livre "Head First java, 2nd edition - Covers java 5.0" (le petit bout que j'ai lu est bien fait). En arrivant de la librairie, je regarde les nouvelles sur le web et je vois que Java 6 vient de sortir: pas très bon timing...

mardi, octobre 31, 2006

La solution du problème...

J'ai poste là-bas la solution à ce "problème". Je l'aurais bien posté ici mais Blogger ne me laisse pas mettre du code HTML dans mes posts sans l'interpréter. M'enfin...