[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Another code sample - symbolic derivatives

On Tue, Apr 9, 2013 at 10:57 AM, David A. Wheeler <dwheeler@xxxxxxxxxxxx> wrote:
Here's a version of the "Wizard book" symbolic derivative calculation, using sweet-expressions.
I've placed it below and put it in an attachment.

Unsurprisingly, sweet-_expression_'s ability to accept infix makes infix expressions nicer. E.G.:
deriv '{{x * y} * {x + 3}} 'x

My goal of working out examples like this is to see if there are any serious problems with the sweet-_expression_ notation.  I don't see any problems with the notation in this case.  Granted, this has a bunch of especially short and simple definitions, but I don't see any sign of trouble.


 --- David A. Wheeler

#!/usr/bin/env sweet-run
;#!guile -s

; Code to generate derivatives from the "Wizard Book" -
; Hal Abelson's, Jerry Sussman's and Julie Sussman's
; "Structure and Interpretation of Computer Programs"
; (MIT Press, 1984; ISBN 0-262-01077-1),
; http://mitpress.mit.edu/sicp/full-text/sicp/book/node39.html
; http://mitpress.mit.edu/sicp/code/index.html
;;; SECTION 2.3.2

define deriv(exp var)
    number?(exp) 0
      if same-variable?(exp var) 1 0
      make-sum deriv(addend(exp) var) deriv(augend(exp) var)
        make-product multiplier(exp) deriv(multiplicand(exp) var)
        make-product deriv(multiplier(exp) var) multiplicand(exp)
    else error("unknown _expression_ type -- DERIV" exp)

;; representing algebraic expressions

define variable?(x) symbol?(x)

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

I'd rather:

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

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

define addend(s) cadr(s)

define augend(s) caddr(s)

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

define multiplier(p) cadr(p)

define multiplicand(p) caddr(p)

;; Simplification

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

Every binary predicate is a good place to use { } on:

define make-sum(a1 a2) $ cond
  {a1 =number? 0} $ a2
  {a2 =number? 0} $ a1
  {number?(a1) and number?(a2)} $ {a1 + a2}
  else $ `{,a1 + ,a2}

... and so on...