Some small improvements to signatures

I noticed that in the latest version of the docs for BSL, signatures get a mention. Thank you!

There are a couple of small pain points before I can use them, however.

  1. Could we provide a link to the list of Signatures in 1.15 from section 1.4 where they're discussed? Also, it looks like ListOf was left out of the list in section 1.15 and I think Posn should be in there, too, but isn't.

  2. Also, even if you (require 2htdp/image), you don't get signatures for Image or Color, so you can't really use signatures for functions that use these. (Maybe it would be worth it to add Mode, too? You can work around Color and Mode by using String and ignoring the symbol variations, but it is nice to get a check when you have "yellew" instead of "yellow".)

But it's almost there! Is it as easy as adding

(define Posn (signature Posn (predicate posn?)))

and similar or do you have to do the (... signature/arbitrary arbitrary-etc (predicate posn?)) that the other signatures use?

Actually, I just created a file with

#lang racket
(require lang/htdp-intermediate)

(provide Image)

(define Image (signature Image (predicate image?)))

and required it in my BSL file and it at least pretended that Image was a legal thing to use in a signature. I'll try putting together a PR.

On Mar 11, 2025, at 11:37 PM, Todd O'Bryan via Racket Discourse notifications@racket.discoursemail.com wrote that he’d "try putting together a PR.”

Thanks. That would be fantastic. — Matthias

Welp, I've hit a snag.

I think the only thing I'm missing from BSL, etc. is that there should be a signature for Posn (to match how you get Foo when you (define-struct foo (a b c))) and a signature for make-posn that requires the x and y to be Real.

Unfortunately, I get "make-posn: Cannot declare a signature for a built-in form". It looks like I can define Posn, however. Any ideas?

(A similar thing happens when I try to add signatures for make-pen and make-color in 2htdp/image, but I guess those aren't as important since they're protected by contracts. On the other hand, the contracts are pretty hard to explain when you're first starting out.)

(: f (posn -> Integer))
(define (f x) (posn-x x))

is all that’s available on a built-in basis.

Pedagogic rationale: The posn thing exists to teach

1. the Universe of data can be expanded in Racket 
2. constructors can be used in any which way a programmer wants e.g. `(make-posn ‘a 10)` is _okay_

If a programmer wants to represent Cartesian coordinates, then he must define a data description that identifies a subset of this newly introduced data.

Since libraries that use posns protect themselves with contracts (say image), it’s okay not to provide the parameteric variant of the posn signature.

[[ This is a compromise that Mike (the creator of signatures) and I made. ]]

So having a way to specify the signatures of fields is verboten? Given that HtDP2e says

(define-struct posn [x y])
; A Posn is a structure:
; (make-posn Number Number)
; interpretation a point x pixels from left, y from top

It doesn’t make any sense to use other kinds of data to create a posn.

it seems like this would be nice to formalize.

There's also a small wrinkle that I'm having to deal with. For the AP Computer Science Principles course, students have to upload 4 examples of code that they'll be asked about during the free response section of the exam.

These examples MAY NOT INCLUDE COMMENTS. Because signatures aren't comments, they can be included, but anything that can only be expressed as a comment is not allowed. (Students can use comments in their actual program, but they have to delete them all in the examples that they'll receive on test day.)

If the only way to specify the types of structs' fields is a comment, they won't be able to see them.

(I was actually just going to ignore signatures and rely on contracts in comments this year, but once I realized this problem, figuring out how to include them became kind of urgent.)

On Mar 22, 2025, at 1:50 PM, Todd O'Bryan via Racket Discourse notifications@racket.discoursemail.com asked whether "having a way to specify the signatures of fields is verboten”.

No it is not. It’s just not possible for the baked-on posn structure. Here is an example:

#lang htdp/bsl

(define-struct cartesian [x y])
(define CartesianCoordinate (signature (CartesianOf Integer Integer)))

(define data-example-1 (make-cartesian 3 4))
(define data-example-2 (make-cartesian 12 5))

(: distance-to-origin (CartesianCoordinate -> Real))
(define (distance-to-origin cc)
  (sqrt (+ (sqr (cartesian-x cc)) (sqr (cartesian-y cc)))))

(check-expect (distance-to-origin data-example-1) 5)
(check-expect (distance-to-origin data-example-2) 13)
(check-expect (distance-to-origin data-example-2) 13)

Does this help?

;; - - -

On Mar 22, 2025, at 1:50 PM, Todd O'Bryan via Racket Discourse notifications@racket.discoursemail.com also mentions that “[for] the AP Computer Science Principles course, students have to upload 4 examples of code that they'll be asked about during the free response section of the exam.” This sounds like a typical AP CS silliness. I am sorry to hear your students have to suffer under this regime.

Fair enough.