Programming Languages
From the first day of the semester forward I expect students (you) to visit this page once per 24 hours. It is the only source of truth with respect to milestones and warm-up exercises.
Saturday, September 6th, 2025 4:02:46pm
To assist you with the first homework, I have deployed a script called
check-program-1 at /course/cs4400f25/bin/. The script checks
whether you followed the instructions for delivering an executable specified in
1 —
[login-students ~]$ /course/cs4400f25/bin/check-program-1 test-one |
Cloning into 'test-two'... |
remote: Enumerating objects: 25, done. |
remote: Counting objects: 100% (25/25), done. |
remote: Compressing objects: 100% (16/16), done. |
remote: Total 25 (delta 8), reused 21 (delta 4), pack-reused 0 (from 0) |
Receiving objects: 100% (25/25), done. |
Resolving deltas: 100% (8/8), done. |
cloned, specified directories exist, xcount is exectuable, launching |
pushing EXAMPLE into xcount |
|
waiting for result from xcount |
1 |
xcount successfully launched, consumed a EXAMPLE, and returned something. |
This test script did _not_ check the output. |
By contrast, the next repo, named test-two is badly organized. The script points out what is missing:
[login-students ~]$ /course/cs4400f25/bin/check-program-1 test-two |
Cloning into 'test-two'... |
remote: Enumerating objects: 11, done. |
remote: Counting objects: 100% (11/11), done. |
remote: Compressing objects: 100% (6/6), done. |
remote: Total 11 (delta 0), reused 11 (delta 0), pack-reused 0 (from 0) |
Receiving objects: 100% (11/11), done. |
check-program: repo-level directory 1 does not exist |
Finally, I failed to supply a properly executable program in the repo named test-three, and the script reports the problem:
[login-students ~]$ /course/cs4400f25/bin/check-program-1 test-three |
Cloning into 'test-three'... |
remote: Enumerating objects: 10, done. |
remote: Counting objects: 100% (10/10), done. |
remote: Compressing objects: 100% (5/5), done. |
remote: Total 10 (delta 0), reused 10 (delta 0), pack-reused 0 (from 0) |
Receiving objects: 100% (10/10), done. |
cloned, specified directories exist, xcount is exectuable, launching |
pushing EXAMPLE into xcount |
|
waiting for result from xcount |
************************** |
the executable errored out |
xcount:13:9: cannot open module file |
module path: #<path:/home/matthias/check-program-tmp/test-three/get.rkt> |
path: /home/matthias/check-program-tmp/test-three/get.rkt |
system error: no such file or directory; rkt_err=3 |
location...: |
xcount:13:9 |
************************** |
check-program: something went wrong with running xcount and feeding an EXAMPLE |
The script will discover the presence of a Makefile and use it to build an executable.
Thursday, September 4th, 2025 12:02:36pm
#lang racket |
(struct Mumble (Xs n) #:prefab) |
(struct anX (n) #:prefab) |
(struct err [source msg] #:prefab) |
#; {type AST = (U Err [Mumble [Listof X] (U Err Number)])} |
#; {type X = (U Err (anX Number))} |
#; {type Err = (err AST String)} |
#; {IExample -> AST} |
(define (parse-mumble e) |
(match e |
[(cons x more-es) |
(define-values (xs remainder) (parse-x e)) |
(define nn (parse-number remainder)) |
(Mumble xs nn)] |
[_ (err e "a Mumble expected")])) |
#; {IExample -> (Values [Listof X] IExample)} |
; parse potential Xs and return them, plus the remainder of ‘e0‘ |
(define (parse-x e0) |
#; {IExample [Listof X] -> (Values [Listof X] IExample)} |
; ACCU INV ‘accu‘ represents parsed Xs between ‘e0‘ and ‘e‘ |
(define (parse-x/accu e accu) |
(match e |
[(? empty?) |
(values (reverse accu) '())] |
[(cons (list 'X (? number? n)) remainder) |
(parse-x/accu remainder (cons (anX n) accu))] |
[(cons (? number?) remainder) |
(values (reverse accu) e)] |
[_ |
(values (reverse (cons (err e "an X or a Number expected") accu)) e)])) |
; START HERE: |
(parse-x/accu e0 '())) |
#; {IExample -> (U Err Number)} |
; parse a Number inside of a list |
(define (parse-number e) |
(match e |
[(list (? number? n)) n] |
[_ (err e "number expected")])) |
(module+ test |
(require rackunit) |
(define ex0 (list)) |
(check-equal? (parse-mumble ex0) (err ex0 "a Mumble expected")) |
(define ex1 (list (list 'X 1.0) (list 'X 2.0) 3.0)) |
(check-equal? (parse-mumble ex1) (Mumble (list (anX 1.0) (anX 2.0)) 3.0)) |
(define ex2 (list 4.0)) |
(check-equal? (parse-mumble ex2) (Mumble (list) 4.0)) |
(define ex3 (list (list 'X 1.0))) |
(check-equal? (parse-mumble ex3) (Mumble (list (anX 1.0)) (err '() "number expected"))) |
(define ex4 (list (list 'aName) 4.0)) |
(parse-mumble ex4)) |
Wednesday, September 3rd, 2025 3:06:33pm
I am posting the following complete solution to 1 —
#lang racket |
(provide |
#; { –> Void } |
; read an Example, as specified in Assignments/Actual/1.html, |
; count the Names, and print the result as a string |
main) |
(require "../get.rkt") |
(module+ test |
(require "../tests.rkt") |
(require rackunit)) |
(define (main) |
; GUARANTEE delivers an Example: |
(define in (read-s-expression)) |
(define nn (count in)) |
(define out (~s nn)) |
(printf "~s\n" out)) |
(module+ test |
#; {tester : (-> Void) String String String -> Void} |
#; (tester main in out label-of-test) |
; is a test case that feeds ‘in‘ into ‘main‘ |
; and compares its output to ‘out‘ |
(tester main "1.0" "0" "basic test 0") |
(tester main "a" "1" "basic test 1") |
(tester main "(a b c)" "3" "basic test 2") |
(tester main "(a 1.0 c)" "2" "skip one")) |
#; {Example -> Natural} |
(define (count in) |
(match in |
[(? symbol?) 1] |
[(? number?) 0] |
[(list example* ...) (apply + (map count example*))])) |
(module+ test |
(check-equal? (count 'a) 1) |
(check-equal? (count '(a b c)) 3) |
(check-equal? (count '(a (((((((((((1.1))))))))))) c)) 2)) |
Tuesday, August 19th, 2025 10:51:15pm
Welcome to Programming Language Pragmatics Fall 2025.
Do watch the first 30s, and you know how what I mean.