
C0, an Imperative Programming Language for Novice Computer Scientists (2010) [pdf] - philonoist
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.480.8484&rep=rep1&type=pdf
======
macintux
For everyone complaining about how they taught themselves pointers while in
diapers so why can't college freshmen already do this stuff...

1st: Restricting the set of students who can succeed in CS 101 to those who
have already done extensive programming is one way to make sure the field
never diversifies.

2nd: Computer science is not (supposed to be) about programming. Let's teach
them how to think before we teach them how to be language lawyers.

~~~
mac01021
Computer science _is_ (and _must be_ ) about programming.

It need not be about C, or present-day digital computers, or even anything to
do with the von Neumann model.

But there must always be a formal notation for describing computations, and
students of Computer Science must always learn to treat that notation with
rigor and come to grips with its nuances.

Probably too they must always deal with the concept of indirection, and think
about references to (objects that contain) other references.

I'll grant you, though, a language with a saner notation for describing
pointers (and types in general) would be easier to learn than C, and could
still be equally useful - if not moreso.

~~~
macintux
Programming is a critical tool, but computer science isn't about programming
any more than physics is about advanced mathematics.

~~~
mac01021
What is it about, then?

~~~
macintux
When I think computer science, I think things like the lambda calculus,
invented before programming languages. Richard Hamming's work on information
theory.

In the distributed systems world we have Lamport's work on vector clocks and
Paxos, the CAP theorem by Brewer, the Domino paper from Amazon.

In other spaces we have the machine learning and neural networks,
blockchain...

These are computer science, and they're certainly implemented with programming
languages, but they were conceived (and often proved) independently of any
implementation.

~~~
jacobr1
I think what the prior posting was getting at (and this too is fuzzy and
doesn't capture the full scope of CS) is that most of what you mention is
algorithmic. Understanding, proving, and discussing algorithms requires
describing and reasoning about computation using some form of notation. That
doesn't require any particular programming language or pseudo-code notation.
But it does require something to communicate with any kind of rigor.

------
murph-almighty
I was an ECE major at CMU.

C0 basically served as an introduction to C, with contract annotations. The
contract annotations were used to enforce more thinking about your code (i.e.
proving your code worked via pre/post/loop conditions). There were still
pointers, there was just a bit of syntactic sugar surrounding it.

About 2/3's through the course we switched to full-blown C, at which point we
_had_ to learn pointers. The intro to computer systems course (think malloc,
proxy, and buffer overflow labs) used C as well, and that in turn required us
to use pointers. There's no "losing out" on learning pointers. It's basically
a step-stool to C.

At the time, I had a pretty good grasp of pointers and thought C0 was a bit
silly- I'd never used contracts in my life. I currently work as a full-stack
web developer (bit of a twist from my intended path) and I've never seen
anyone "write out contracts" like I did in C0. I now think it was a valuable
exercise in that it forces you to define the parameters that allow your code
to run.

~~~
bwasti
the CS department also offers a compiler class that has you write a compiler
for C0:
[https://www.cs.cmu.edu/~fp/courses/15411-f13/resources.html](https://www.cs.cmu.edu/~fp/courses/15411-f13/resources.html)

------
dbcurtis
C with training wheels?

So it seems to me that this course is trying to accomplish two things that are
mostly orthogonal: 1) teach principles of computation, 2) teach where the
semicolons and curly braces go.

#2 is a valid goal if you eventually want to ramp someone up on C/C++ without
suffering language switching turbulence. But overall, I would expect that an
intro course should be teaching fundamentals first. Language syntax is a
completely secondary issue with respect to learning good imperative
programming practices.

Languages come and go. Semicolons come and go. Yes, language switching causes
speed bumps, I switch between C (embedded) and Python regularly. Twitchy-
semicolon-pinky is a thing. Inventing another language to teach the basic
corpus of imperative programming ideas seems like a lot of effort for little
lasting payoff.

~~~
tinalumfoil
Although I learned to program past when it was popular, I can't shake the
feeling that BASIC is the best way to teach programming. The basis of any
computer is the sequential execution of instructions, and it's this model of
computation that informs things like algorithmic complexity or Turing
completeness. Even if teaching BASIC wasn't possible, I would still prefer to
see a subset of x86 assembly taught than something ridiculous like "a simpler
C" which obscures the core functionality of a computer with abstractions,
without teaching a practical language.

~~~
eru
These days the sequential execution of instructions is a convenient lie at
most.

BASIC is one way. But you can also start with 'How to Design Programs'
approach and start with Racket
([http://www.ccs.neu.edu/home/matthias/HtDP2e/Draft/index.html](http://www.ccs.neu.edu/home/matthias/HtDP2e/Draft/index.html)).

~~~
tinalumfoil
> sequential execution of instructions is a convenient lie at most

Could you expand? Obviously some processors reorder instructions and try to do
things in parallel, although this isn't true everywhere and the model of
sequential instructions is still valid.

~~~
khedoros1
Instruction reordering, branch prediction, speculative execution, and
optimizing compilers would all be examples of details that are abstracted over
by the model of sequential instructions.

"Lie" might be too strong of a word, but "simplification" would be accurate.
And sometimes that abstraction is leaky.

~~~
XorNot
Not to anyone working in BASIC.

And probably more importantly, they're implementation details: you can't feed
a modern processor out of order instructions, the entire system is built and
optimised to efficiently execute sequential programs (but possibly several of
them concurrently).

~~~
khedoros1
Depends on the BASIC. Some varieties are compiled and have modern
optimizations.

> And probably more importantly, they're implementation details

Well, right, programming languages are abstractions built on top of the actual
implementation.

------
lmm
If you're willing to break compatibility with C, why not make a clean break
and use a language that better supports the things you want? The authors go on
(correctly) at great length about the difficulty of union types in C compared
to an ML-family language; why not use an ML-family language? (My university
used Standard ML for their first programming course and I see it as a good
choice)

~~~
instruction-ptr
The course that uses C0 goes on later to C, and is literally titled
“Principles Of Imperative Computation”. We use Standard ML for “Introduction
to Functional Programming”.

\- source: I’m a TA for this course

~~~
murph-almighty
I was an ECE and now regret not taking Intro To Functional Programming (I
almost typed 150 by instinct). I was put off by the horror stories, and
perhaps also by a lab I saw once that was basically a longform story about
"pleasing Senpai".

My iteration of Principles of Imperative Computation was... something. I liked
the course but the professors who ran it that semester were really unpleasant.
They accused a friend of mine for cheating when she pointed out an obvious
mistake in someone's code during office hours when the line for TA help was
basically on two whiteboards. She became a TA the following semester.
¯\\_(ツ)_/¯

------
Avshalom
I mean I get the idea but

    
    
      No floating point datatypes
      No ... switch statements or do...while loops
    

seem like terrible things to leave out, occasional gotchas of floating point
not with standing being only integers means no division

~~~
instruction-ptr
“No division”? How do you reason this? Integer division is a thing

~~~
Avshalom
division is not defined on the set of integers, you only have modular
arithmetic.

~~~
instruction-ptr
See section 7 of
[http://www.cs.cmu.edu/~15122/handouts/02-ints.pdf](http://www.cs.cmu.edu/~15122/handouts/02-ints.pdf)

(As an aside nearly every language defines division on the set of integers
this way so it’s not even like we’re making this up)

------
thecompilr
C language is as simple as it gets. The only concept people struggle with is
pointers, but even that is a very simple concept. Teaching something that is
simpler than C to computer scientists will breed very poor engineers.

~~~
flafla2
I am currently a TA for 15-122 at Carnegie Mellon, the class that C0 was
originally made for. I would argue that C0 does an excellent job at breeding
good programmers because of the following features:

1\. Contracts in C0 bake preconditions, post conditions, and loop invariants
right into the language. Contracts are only checked when in "dynamic
recompilation" mode (basically debug mode). This allows you to check the
correctness of your code more easily (and, importantly, in an easily gradable
way).

2\. The language is designed in such a way to introduce C to programmers that
are used to other higher level languages. In the C0 phase of the course we
introduce students to fundamental concepts like memory allocation, code
reasoning and contracts, binary representations of numbers, and unit testing.
Next we transition to C1 (included in the C0 install) which introduces
typedefs and other features of C. At this point we focus on introducing data
structures. Finally we make the final transition to C, where we talk about
undefined behavior, gcc, stack vs heap, etc.

I've taken this course myself, and I would argue that this measured approach
to learning C is far superior to throwing students (most of whom have no low-
level programming experience) straight into C.

~~~
grayhatter
I've replied here
[https://news.ycombinator.com/item?id=15500321](https://news.ycombinator.com/item?id=15500321)
I think I mean to reply to you.

------
SeanDav
I would have thought that Pascal is a great candidate for a simpler, safer
language that still has enough features to write serious applications.

------
JTbane
One can see why they chose a more-safe version of C for an intro course-
beginner C programmers can fall into a wide variety of difficult to debug
pitfalls (memory leaks, out of bounds reads and writes, undefined behavior)
that can make the task of teaching and grading a nightmare.

My university opted to use C++ as the introductory programming language, since
it is somewhat more safe. Now they are transitioning to even safer languages
like Python and Javascript. While I don't agree with it, I can see why it is
necessary to reduce the headache for instructors.

C0 seems like a good tool to use for teaching, although it may lead to bad
habits later.

To wrap it up, in my opinion students should definitely be exposed to the
concepts of the C family of languages early on: imperative programming,
pointers, dynamic memory allocation, et cetera. All the pitfalls associated
with these concepts also need to be explored.

The language doesn't necessarily matter as long as the students are allowed to
make mistakes and learn from them.

------
Shoop
Here is some more information about C0:

C0 is used in 15-122, Carnegie Mellon's second semester introductory
programming class. I am currently taking this class. The class teaches C0 for
the first two thirds of the semester and then transitions to C for the final
part of the semester.

C0 has essentially the same syntax as C, but for pedagogical purposes the
semantics of the language have been changed to be much more similar to java.
Instead of manual memory management, there is a garbage collector, and user
defined structs can only be allocated on the heap. Additionally, there is only
one integer type which is a signed 32-bit two's complement integer. Overflow
is defined as wrapping. strings are opaque immutable types implemented at a
language level, rather than just null-terminated buffers. C0 catches out of
bounds array accesses at run time. While C0 internally stores array lengths to
perform this check, the length is not accessible from C0 code so array lengths
must be passed around just the same as C.

C0's biggest feature beyond C is that it allows for contracts. Functions can
have preconditions and postconditions. There are also loop invariant contracts
and assertions. These contracts are checked at run time when specific flag is
passed to the compiler or interpreter (C0 has both, and uses a bytecode
internally). A major focus of the class is proving the safety and correctness
of the programs we write using these contracts. We are encouraged to prove
safety and correctness using only logical reasoning from contract to contract,
not operational reasoning. A co-requisite of the class is a course in proofs.
There seems to be a heavy influence on the teaching style from Dijkstra's "On
the cruelty of really teaching computing science" [1].

The 15-122 class has written assignments focusing on the proofs part of the
course and programming assignments which for the most part are automatically
graded by autolab [5]. Our code is tested against a number of unit tests to
ensure its correctness and our contracts are also tested to see if they can
catch bugs in faulty implementations.

C0's implementation is not open source, but it appears to be used in ongoing
research [2]. Here is the language website and course website [3], [4].

[1]
[https://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD103...](https://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1036.html)

[2]
[http://www.cs.cmu.edu/~fp/papers/cc016.pdf](http://www.cs.cmu.edu/~fp/papers/cc016.pdf)

[3] [http://c0.typesafety.net/](http://c0.typesafety.net/)

[4] [http://www.cs.cmu.edu/~15122/](http://www.cs.cmu.edu/~15122/)

[5] [http://www.autolabproject.com/](http://www.autolabproject.com/)

~~~
acmustudent
A cmu freshmen on hn and over 900 days old. The one thing i don’t like about
this school is that most cs majors aren’t the hn type

~~~
ksikka
What is the HN type?

~~~
grayhatter
Likes to solve interesting problems that no one has done before?

Learning about strange/engaging things, even if it's not directly useful?

Taking apart a new toy, just to see how it works?

~~~
adrianN
Having too much free time on your hands and wasting it on the Internet while
fooling yourself into believing that you learn something useful..

------
azhenley
Does anyone know of a website containing resources for teaching this? I'd also
be interested in seeing who is using it now a days.

~~~
0xd3adbeef
15-122, an introductory programming course at CMU, uses C0 for most of the
course. Lecture notes are available on the site:
[http://www.cs.cmu.edu/~15122/schedule.shtml](http://www.cs.cmu.edu/~15122/schedule.shtml)

~~~
hackermailman
also their compiler course you implement a compiler for C0
[http://www.cs.cmu.edu/~rjsimmon/15411-f15/schedule.html](http://www.cs.cmu.edu/~rjsimmon/15411-f15/schedule.html)

------
pklausler
Using a weird local subset of C as an introductory imperative programming
language seems like a really bad idea to me, unless you're using your weird
local subset of C as the source language for a compiler construction course.

There's just so many other good options.

------
ExceptionRaised
Here's an interesting extension to the language to allow for session-typed
concurrency.

[0]:
[http://mwillsey.com/papers/cc0-thesis.pdf](http://mwillsey.com/papers/cc0-thesis.pdf)

------
fpig
I thought this would be for kids, I don't see the point of a simplified
language for college students.

However, if they as someone said use it in a compiler-writing course, for that
purpose it makes sense to have a simplified language. I had to do that back in
college and basically used a C subset for it (for the compiled language, not
the implementation language).

~~~
instruction-ptr
To quote a fellow TA below:

“I am currently a TA for 15-122 at Carnegie Mellon, the class that C0 was
originally made for. I would argue that C0 does an excellent job at breeding
good programmers because of the following features:

1\. Contracts in C0 bake preconditions, post conditions, and loop invariants
right into the language. Contracts are only checked when in "dynamic
recompilation" mode (basically debug mode). This allows you to check the
correctness of your code more easily (and, importantly, in an easily gradable
way).

2\. The language is designed in such a way to introduce C to programmers that
are used to other higher level languages. In the C0 phase of the course we
introduce students to fundamental concepts like memory allocation, code
reasoning and contracts, binary representations of numbers, and unit testing.
Next we transition to C1 (included in the C0 install) which introduces
typedefs and other features of C. At this point we focus on introducing data
structures. Finally we make the final transition to C, where we talk about
undefined behavior, gcc, stack vs heap, etc.

I've taken this course myself, and I would argue that this measured approach
to learning C is far superior to throwing students (most of whom have no low-
level programming experience) straight into C.”

~~~
grayhatter
>I've taken this course myself, and I would argue that this measured approach
to learning C is far superior to throwing students (most of whom have no low-
level programming experience) straight into C.

Sure, I'd love to read this argument. I taught myself to program, started with
python, then learned C. The hurdle of learning how memory is mapped, the
knowledge/understanding gained by being required to clean up after yourself
when you do *alloc. That's what makes learning C helpful. Perhaps I gave up
reading the introduction to soon, but honestly, after I read it adds in GC to
C.... I had the same reaction everyone else has already voiced. "Why use C
here?" There's many other better languages if your just adding in hand
holding.

Finally, if grading assignments was one of the defining reasons for inventing
a new language, you need to take a step back from the text editor, and ask...
"How did I get here?"

~~~
stuffaandthings
Just wanna add that we used C0 for a subset of the class, and most of the
students jump into a more rigorous course which involves actually implementing
malloc.

I agree with you that learning the ins and outs of memory is super important,
but the methodology of this course doesn't imply the lack of teaching memory
management

------
augustk
Why not use Oberon instead?

------
baldfat
Here is the Tutorial Wiki

