Tag Archives: Simply Scheme

Fizz Buzz in Scheme

I learned about a children’s game called Fizz Buzz today. It turns out that Fizz Buzz is a fairly common programming task that comes up during programming interviews.

Since I am learning to program, I decided to give it a shot.

Here is one way to code a Fizz Buzz procedure in Scheme.
It took me about 5 minutes to think out the solution to this and write the code.

(define (fizzbuzz x)
    (cond ((and (equal? (remainder x 3) 0) (equal? (remainder x 5) 0)) 'fizzbuzz)
          ((equal? (remainder x 3) 0) 'fizz)
          ((equal? (remainder x 5) 0) 'buzz)
          (else se x)))

Update 2020-05-28:

I learned about a new notation called “let” today.

I figured I could improve my Fizz Buzz code by adding “let” to the previous code. This way it becomes easier to alter the “fizz”, “buzz”, and “fizzbuzz” values since they would only have to be altered in one place instead of changing the number in all places in the code.

This was my first solution with “let“:

(define (fizzbuzz x)
    (let ((fizz 3)
          (buzz 5))
      (cond ((and (equal? (remainder x fizz) 0) (equal? (remainder x buzz) 0)) 'fizzbuzz)
          ((equal? (remainder x fizz) 0) 'fizz)
          ((equal? (remainder x buzz) 0) 'buzz)
          (else se x))))

I thought some more about it and figured I could improve on the code even more – rid it of the redundant parts.

Result:

(define (fizzbuzz x)
    (let ((fizz 3)
          (buzz 5))
      (let ((fizzname (equal? (remainder x fizz) 0))
            (buzzname (equal? (remainder x buzz) 0)))
      (cond ((and fizzname buzzname) 'fizzbuzz)
          (fizzname 'fizz)
          (buzzname 'buzz)
          (else se x)))))

Update 2020-05-29:

Adding some explanation to the evolution of above code.

The first code did what it was supposed to do. It gave the right answers to Fizz Buzz for numbers divisible with 3 and 5.

In the next step I added the “let” notation. Adding “let” made the code better because it made it easier to change the numbers from 3 and 5 to any other numbers.
By adding “let” one only needs to change the numbers in one single place of the code. Without “let” one would have to change every singel “3” and “5” that appears in the entire code. Thus there is less room for error after adding “let“. An error would be to eg miss to change one “3” in the code.

In the final step I added “let” to recurring parts of the code as well. By doing this, recurring parts of the code only need to be evaluated once instead of multiple times. This makes the code more efficient.

Simply Scheme: Chapter 6, Exercise 6.13

My main goal right now is just to learn to code. My main goal right now is not to write the best code that I possibly can.

By first focusing on just learning to code in Scheme I can focus on only that and not on writing the best possible code. This helps me to avoid overreaching (learn to code and write awesome code at the same time) and lets me improve one step at a time. Once I get better at fundamental coding in Scheme, I can focus on writing better code.

Below is how I dealt with exercise 6.13, ch 6, in Simply Scheme. My thinking process, my mistakes and how I solved them.

All my Scheme exercises can be found on Subscribestar in the $2 tier.
From chapter 4 and onwards I write out my thinking process and mistakes.
For chapter 1-3 there are only my solutions.


6.13 Write a better greet procedure that understands as many different kinds of names as you can think of:

> (greet ‘(john lennon))
(HELLO JOHN)

> (greet ‘(dr marie curie))
(HELLO DR CURIE)

> (greet ‘(dr martin luther king jr))
(HELLO DR KING)

> (greet ‘(queen elizabeth))
(HELLO YOUR MAJESTY)

(greet ‘(david livingstone))
(DR LIVINGSTONE I PRESUME?)

I will just focus on the examples given in the exercise. I will not come up with new kinds of names.

Thinking process:
1. A title will always be in front of a persons actual name – eg “dr“, “queen“, “king“.
2. For “dr” greet as “dr” followed by last name. But only if last name is not “jr” / “sr“. If last name is equal to “jr” / “sr” then use the second last name.
3. For “queen” / “king” greet as “your majesty“.
4. Don’t know how to presume if someone is a dr without making a list of all ppl that are dr.

Step 1:

Test the core concept.

(define (greet name)
    (if (equal? (first name) 'dr)
        (se '(hello dr) (last name))
        #f))

Works.


Step 2:

Add more “if” procedures. Add “king” / “queen“.

(define (greet name)
    (if (equal? (first name) 'dr)
        (se '(hello dr) (last name))
        (if (equal? (first name) (member? '(king queen)))
            (se '(hello your majesty))
            (se 'hello (first name)))))

Did not work.
member?” lacking one of its two arguments.

(define (greet name)
    (if (equal? (first name) 'dr)
        (se '(hello dr) (last name))
        (if (equal? (first name) (member? (first name) '(king queen)))
            (se '(hello your majesty))
            (se 'hello (first name)))))

Did not work.
Prints “(hello queen)

Test 1:

Effort to find the problem.

(define (greet name)
    (if (equal? (first name) (member? (first name) '(king queen)))
            (se '(hello your majesty))
            #f))

Prints “#f

Test 2:

(member? 'queen '(king queen))

Prints “#t

I think my mistake is that I am mixing the wrong domains.
member?” is a predicate (a function that returns either #t or #f). Thus “(equal? (first name) (member? (first name) ‘(king queen)))” would be evaluated as (step by step evaluation):
1. (equal? (first name) (member? (first name) ‘(king queen)))
2. (equal? ‘queen (member? ‘queen ‘(king queen)))
3. (equal? ‘queen #t)
4. #f

My “king” / “queen” code is unnecessarily confusing. I can just eliminate the “equal?” part.

(define (greet name)
    (if (equal? (first name) 'dr)
        (se '(hello dr) (last name))
        (if (member? (first name) '(king queen))
            (se '(hello your majesty))
            (se 'hello (first name)))))

Works.


Step 3:

Fix “jr” / “sr“.
jr” / “sr” only matters for ppl that are “dr” as “jr” / “sr” is at the end of the name.

(define (greet name)
    (if (equal? (first name) 'dr)
        (se '(hello dr) (last name))
        (if (and (equal? (first name) 'dr) (member? (last name) '(sr jr)))
            (se '(hello dr) (last (bl name)))
            (if (member? (first name) '(king queen))
                (se '(hello your majesty))
                (se 'hello (first name))))))

Did not work.
Prints “(hello dr jr)” for “> (greet ‘(dr martin luther king jr))“.

It is because the first “if” procedure is true. I need to change places with the first and the second procedure. That should fix it.

(define (greet name)
    (if (and (equal? (first name) 'dr) (member? (last name) '(sr jr)))
            (se '(hello dr) (last (bl name)))
            (if (equal? (first name) 'dr)
                (se '(hello dr) (last name))
                (if (member? (first name) '(king queen))
                    (se '(hello your majesty))
                    (se 'hello (first name))))))

Works.


I don’t know how to do the following without making a list of all ppl who could be considered doctors in advance.

> (greet ‘(david livingstone))
(DR LIVINGSTONE I PRESUME?)

A list of that would be something like:

(if (equal? name '(david livingstone))
        (se 'dr (last name) '(I presume?))
        ...))

Then it would look something like this:

(define (greet name)
    (if (and (equal? (first name) 'dr) (member? (last name) '(sr jr)))
            (se '(hello dr) (last (bl name)))
            (if (equal? (first name) 'dr)
                (se '(hello dr) (last name))
                (if (member? (first name) '(king queen))
                    (se '(hello your majesty))
                    (if (equal? name '(david livingstone))
                        (se 'dr (last name) '(I presume?))
                        (se 'hello (first name)))))))

Works.

Programming and Philosophy

I am learning programming. The programming language I chose to learn is Scheme.

Why learn Scheme, a symbolic programming language, of all things?

The reason is that I want to understand the conceptual thinking of programming. Regarding programming, Curi (Elliot Temple), told me:

you need the big picture instead of to treat it like a bunch of math.

Scheme looks to have good resources for doing that. From Simply Scheme’s foreword:

It [Simply Scheme] emphasizes programming as a way to express ideas, rather than just a way to get computers to perform tasks.

This is the essence of how good philosophy works as well: learning to understand concepts, integrating them into the big picture, and avoiding contradictions in the process. Objectivism teaches this. In Return of the Primitive: The Anti-Industrial Revolution, Ayn Rand writes:

There are two different methods of learning: by memorizing and by understanding. The first belongs primarily to the perceptual level of a human consciousness, the second to the conceptual.
[…] The second method of learning—by a process of understanding—is possible only to man. To understand means to focus on the content of a given subject (as against the sensory—visual or auditory—form in which it is communicated), to isolate its essentials, to establish its relationship to the previously known, and to integrate it with the appropriate categories of other subjects. Integration is the essential part of understanding.

Rand, in Atlas Shrugged:

Contradictions do not exist. Whenever you think that you are facing a contradiction, check your premises. You will find that one of them is wrong.

Do you see the similarities between good philosophy and Scheme programming?

By learning programming I work on philosophy – and by learning philosophy I work on my programming.

I am using Simply Scheme to learn Scheme.