teaching machines

CS 330 Lecture 9 – Types

February 10, 2017 by . Filed under cs330, lectures, spring 2017.

Dear students,

Today we begin our exploration of programming language concepts, rather than the tools (regex) that we’ll later use for interpreting programming languages. In particular, we start off our discussion with C. I used to talk about assembly first, because no programming language should be evaluated outside the context of history. All that humans make is shaped by what exists at the time of a thing’s making. We can summarize what led up to C as follows:

  1. Programming by circuit building. We plugged cables between hardware that only knew how to do one thing.
  2. Programming by flipping switches. Thanks to switching technology like transistors, complex circuits could be built once and left intact, with the particular pathway that electrons took between input into output programmed via hardware switches.
  3. Programming by machine code. Instead of hardware switches, the switches could be specified as a stored program, either on punch cards or a stored program.
  4. Programming by assembly. A human-readable veneer was laid over the processor’s binary instruction set, introducing the possibility for a single assembly language to be used for multiple different machine codes.
  5. Programming by Fortran, Cobol, LISP, and many others.

What did C and its above-assembly siblings bring to programming? I can think of a few things:

Let’s focus on types today. What sort of types does C provide? These go in the first draft of my list:

What types does C not provide?

Does C allow the user to define new types? Yes, through struct. One can also use typedef to create a shorter name for an existing type (or a longer name, if that’s your thing), but typedef doesn’t really introduce a new type.

Let’s write some code to back up my claim that C doesn’t really have enums—at least not typesafe ones. Let’s write a program to evaluate a hand of Blackjack.

Here’s your TODO list for next time:

See you then!

Sincerely,

P.S. It’s Haiku Friday!

“You’re one of a kind.”
That’s how he wooed 2. And 3.
And 4, 5, and 6.

dollar.rb

#!/usr/bin/env ruby

foo = 17
$foo = 17

def slar
  # puts foo
  puts $foo
end

slar

blackjack.c

#include <stdio.h>
#include <stdlib.h>

typedef enum {
  ACE = 1,
  TWO,
  THREE,
  FOUR,
  FIVE,
  SIX,
  SEVEN,
  EIGHT,
  NINE,
  TEN,
  JACK = 10,
  QUEEN = 10,
  KING = 10
} card_t;

int score(card_t *hand, int ncards) {
  int score = 0;
  int naces = 0;

  // Sum up all the non-aces, and count the aces.
  for (int i = 0; i < ncards; ++i) {
    if (hand[i] == ACE) {
      ++naces;
    } else {
      score += hand[i];
    }
  }

  // Figure out how to count the aces.
  if (naces > 0) {
    int max = 11 + naces - 1; // no more than one can be worth 11
    int min = naces;
    if (score + max <= 21) {
      score += max;
    } else {
      score += min;
    }

    /* Another way:

      // Count all aces as ones.
      score += naces;

      // Could one of them have been counted as 11 (1 + 10) instead?
      if (score + 10 <= 21) {
        score += 10;
      }

     */
  }

  return score;
}

int main(int argc, char **argv) {
  /* card_t hand[] = {ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE, ACE}; */
  card_t hand[] = {21};
  printf("Score: %d\n", score(hand, 1));
  return 0;
}