5

I'm working with simple lists in Racket, and I was doing a function to sum the elements of a list.

But I would like to know if there is any simpler way to do this.

I did this function:

(define (mySum L)
  (if (empty? L) 0
      (+ (first L) (mySum (rest L))))
  )

output:

(mySum '(1 2 3 4))
10

I wanted to know if anyone knows a simpler way to do this. I explain myself, for example: This is another function I did:

(define (myAppend L1 L2)
  (if (empty? L1) L2
      (cons (car L1) (myAppend (cdr L1) L2)))
  )

But this function can be done more simply by doing just this:

(define (myAppend L1 L2)
  (append L1 L2)
  )

My problem is to know if there is a simpler way to do the sum of items in a list. Thanks

Jonatan Lavado
  • 954
  • 2
  • 15
  • 26

4 Answers4

6

If all you're going for is a short program,

(define (mySum L)
  (apply + L))

is shorter. Whether it is "simpler" is a matter of interpretation: The way you've written it seems "simpler" in that it is defined purely based on the structure of lists, whereas (apply + L) relies on both a semi-magical function (apply) and a semi-fancy behavior of + (the fact that it takes a variable number of arguments) that itself has to do something similar to what you've already written.

(Incidentally, I wouldn't call your myAppend example simpler, either -- the first one actually defines the function you want, whereas the second just refers to the behavior you want, which in turn had to be defined elsewhere. If you're doing this as part of a practical program, (apply + L) and using the built-in append are certainly the way to go, but if this is for educational purposes then I think the initial versions of both functions are superior.)

jacobm
  • 13,790
  • 1
  • 25
  • 27
4

Another way to approach it would be

(define (my-sum lst)
 (foldr + 0 lst))

This uses built-in function foldr and is fairly short. Foldr consumes a function (+), base-case (0) and a list (lst). I've attached a link to a visual representation of foldr, as well as a link that explains it really well.

link

More information here

Xorifelse
  • 7,878
  • 1
  • 27
  • 38
  • Some interesting discussion on fold here also http://stackoverflow.com/questions/39018163/expanded-form-of-fold-in-racket. – rnso Jan 15 '17 at 00:43
2
(apply + '(elements_of_list))

:)

Richard Telford
  • 9,558
  • 6
  • 38
  • 51
  • 5
    Would be better if you explained why and how this code solves the problem. Formatting the code is also nice. Is that `:)` part of the code? – brasofilo May 08 '17 at 20:40
1

One can also use for/sum:

(define (my+ L)
  (for/sum ((i L))
    i))

(my+ '(1 2 3 4))  ; => 10

'named let' is a version similar to recursive functions but may be easier to understand:

(define (myplus L)
  (let loop ((L L)
             (s 0))
    (cond
      [(empty? L) s]
      [else (loop (rest L) 
                  (+ s (first L)))] )))

'cond' can also be replaced by 'if' here, since there are only 2 cases. The keyword 'else' can also be omitted.

rnso
  • 23,686
  • 25
  • 112
  • 234