sepuku wrote:to make a multiplication we need at least 2 arguments right?

Technically, no. If passed no arguments, the '*' function in Scheme returns "1"; if passed one argument, it returns that argument.

sepuku wrote:When we (map * row) what multiplication is done?

Perhaps this would be made clear by considering the following implementation of a multiply procedure that accepts a variable number of arguments, but relies upon a 'mult2' function which requires exactly two arguments (ignoring that Scheme already provides this functionality).

- Code: Select all
`(define (my-* . args)`

(define (iter lis previous-value)

(if (null? lis)

previous-value

(iter (cdr list) (mult2 (car lis) previous-value)) ))

(iter args 1) )

; or the same thing using lambda notation

;

(define my-*

(lambda args

(define iter

(lambda (lis previous-value)

(if (null? lis)

previous-value

(iter (cdr lis) (mult2 (car lis) previous-value)) )))

(iter args 1) ))

When you map 'my-*' to a single list of numbers, each of those numbers gets multiplied by "1" to form a new list. In other words, Nothing really happens except that you've created a new copy of the original list. The behavior of the '*' function is identical (we could have named our function '*' but then we'd need to ensure that mult2 didn't reference it as such).

sepuku wrote:If i understand well the substitutions, this is like saying (map * matrix2).Is that correct?I can not understand how the substitution works in all the program...maybe it's because of the lambdas

for example when we have this:

- Code: Select all
`(matrix-multiply '((1 2) (3 4)) '((-3 -8 3) (-2 1 4)))`

We want the first element of the resulting matrix to be (+ (* 1 -3) (* 2 -2))

this happens in

- Code: Select all
`(apply + (map * row column))`

But how it understands what is everytime "row" and "column" ?

Actually, I think the secret to understanding this lies in how "(apply map (lambda colums" works. The "apply +" is not evaluated until after both lambdas are created.

Consider the evaluation of "(apply map list '((-3 -8 3) (-2 1 4)))", a list is created from the cars of each of the two lists, from each of the cadrs, and from each of the caddrs.

- Code: Select all
`(apply map list '(-3 -8 3) '(-2 1 4)) ==> ((-3 -2) (-8 1) (3 4))`

The actual breakdown of this is a little bit involved, but fairly straightforward; I will leave that for you to investigate on your own. Our main interest is how this transforms when our internal lambda is substituted for the 'list' function. If we use the "identity" lambda function (i.e., a lambda that when invoked returns its argument), we get the same result as for the above code but now we have a way to "do stuff" with the arguments other than just inserting them in a list.

- Code: Select all
`(apply map (lambda x x) '((-3 -8 3) (-2 1 4))) ==> ((-3 -2) (-8 1) (3 4))`

; just to show that the mapped cars, cadrs, etc are passed to the body of our lambda:

(apply map (lambda x (reverse x)) '((-3 -8 3) (-2 1 4))) ==> ((-2 -3) (1 -8) (4 3))

So our (inner) lambda has been passed each of those three lists (of two numbers) and is tasked with the job of multiplying them, element-by-element, with one of the 'row's of 'matrix1' (in particular, the row that is being mapped as an argument to the outer lambda).

- Code: Select all
`(define row '(1 2)) ;; simulate the outer lambda mapping of the first row of matrix1`

; just as an exercise, compute the non-summed products of the row elements by the column elements

(apply map (lambda column

(map * row column)) '((-3 -8 3) (-2 1 4))) ==> ((-3 -4) (-8 2) (3 8)) ;; before adding the factors

; now, insert our 'apply +' operation to sum the products of the element multiplication

(apply map (lambda column

(apply + (map * row column))) '((-3 -8 3) (-2 1 4))) ==> (-7 -6 11) ;; yay! this is the first row of the matrix product