last week involved a simple daily programmer challenge that asked for user input. Since then I’ve also dug a bit further into Scheme as that last week only really supplied me with 1-2 hours worth of scratching my head.

Challenge 1

I’ve been making my way through various challenges from the TSPL3 book. One of them included the challenge for a ‘shorter’ function

The procedure ‘length’ returns the length of its argument, which must be a list. For example, (length ‘(a b c)) is 3. Using length, define the procedure shorter, which returns the shorter of two list arguments. Have it return the first list if they have the same length.

Solution

(define shorter
  (lambda (ls other-ls)
    (cond
      ((< (length ls) (length other-ls)) ls)
      ((> (length ls) (length other-ls)) other-ls)
      (ls))))

I’m starting to get a bit more comfortable with Scheme, in particular I am now finally grasping the placement of the parenthesis and in general getting a better feel for the syntax.

Apart from this challenge (which I managed to do on my lunchbreak at work) I’ve been going through another easy challenge from daily programmer. I don’t think I’ll be hitting the intermediate ones for a good few weeks. This is one of the most frustrating things for me personally as I see several harder problems and know how to solve them in a ‘C like language’, translating that to Scheme is non-trivial. It really does show how Lisp(s) are so different from the norm that I’m used to.

Challenge 2

Doing these challenges has also made me aware of how much I rely on mutable state in other languages. For example, the challenge on /r/dailyprogrammer states

Add an item to the to-do list Delete a selected item from the to-do list And obviously, print out the list so I can see what to do!

This is extremely easy with mutable state. Just have an array that you add and remove from, but given that assignments are frowned upon in Scheme, I try not to use them. Infact I haven’t used any set!’s just yet. Kent Dybvig states

In fact, most of the assignments that are either necessary or convenient in other languages are both unnecessary and inconvenient in Scheme

And since I’m only learning whatever people tell me about Scheme at this point, I think I’ll learn from a reputable source. In the case of this challenge, I won’t be going with one global list that can be altered but rather just a new list each item.

Solution

;todo  list

(define todo '("eat breakfast" "take a shower"))

;doesn't really need to be a procedure
;since it's just a wrapper for cons...
(define add-item
  (lambda (item ls)
    (cons item ls)))

(define show-list
  (lambda (ls)
    (cond
      ((null? ls) (newline))
      (else (display 
              (string-append(car ls) "\n"))
            (show-list (cdr ls))))))

(define delete-item
  (lambda (item ls)
    (cond
      ((null? ls) '())
      ((eqv? item (car ls)) (delete-item item (cdr ls)))
      (else (cons (car ls) (delete-item item (cdr ls)))))))

Other Stuff

Apart from the above, I’ve also been doing some small tests on my own just to get better acquainted with the language.

One in particular is converting a number into a list i.e.

12345 => '(1 2 3 4 5)

I ended up making quite a few helper functions to help get through this. I was surprised that there was no char->number procedure but there was string->number and other similar procedures. So I made my own (hacky) version

(define char->number
  (lambda (char)
    (- (char->integer char) 48)))

This would then allow me to do the following

(number->string 12345) => "12345"
(string->list "12345") => '(#\1 #\2 #\3 #\4 #\5)
(char->number #\1) => 1

Now that we have that functionality. We just need one more procedure that calls (char->number) over the given list and then we’re done. This sounds like the perfect opportunity for map, so I went with this:

(define number->list
  (lambda (n) 
    (map char->number(string->list (number->string n)))))

And it worked!

(number->list 123456) => '(1 2 3 4 5 6)
(car(number->list 123456)) => 1

Questions

As with last time, here are some questions I asked myself throughout.

Unanswered Questions

These challenges made me question a few things. I also have a few other questions that I’d like to ask alongside this.