Real Racket applications with correct idiomatic style?

Recently on Discord there was a question about "real applications written in Racket".
There were a number of thought-provoking answers which I will add here to keep them accessible and searchable. I am not the author of the question. I have omitted attribution of the question and answers. No malice is intended.

Question sequence:

  1. Could anyone recommend a good OSS project written in Racket as an example of practical, idiomatic, and stylistically correct Racket as a study aid? Don't care what it does, so long as it is nontrivial.
  2. I'm also interested in how people idiomatically create UIs, whether web, CLUI, or whatever.
  3. What I'm actually looking for is real-world production code that's actually in use, rather than tutorial and demonstration code.
  4. In my experience (other languages of course) there are weird real-world things that pop up and break the cleanest of architectures. These seem (again in my experience) to occur in complete applications more than libraries, and also in domains farther from what software devs consider home territory, like dev tools. I'd love to see how people have tackled these in Racket.
5 Likes

(one response)

If you rephrase the question into: "What constructs are used in Racket to make robust programs?"
Then I'd point you to:

File handling:

  • call-with-input-file*
  • call-with-output-file*
  • port-try-file-lock?

Custodians (resource management):
14.7 Custodians

Security guards:
14.6 Security Guards

Exception handling:
10.2 Exceptions

1 Like

(Some responses, lightly edited, with links. Again, not mine.)

1 Like

(Some responses, lightly edited, with links. Again, not mine.)

1 Like

Here are a couple more codebases that fit the "application" category:

2 Likes

Making a program robust is more than just using a language construct. It involves understanding what the program is supposed to do, what the error or limit conditions might be and handling them correctly.

Even the simple task of reading data from a file in a robust way, would require you to handle:

  • Correctly open and close ports and handle errors (call-with-input-file can help with that)
  • What should the rest of the program do if the file was not found?
  • What happens if you open a file, start reading data, but half-way through the next read fails, resulting in partial data?
  • What happens if the opened file turns out to be larger than the memory, or a malicious user tricked the program into opening /dev/null for reading, causing it to run out of memory?
  • What happens if a malicious user tricks the program into opening a file which is not supposed to? Such as tricking a web application into opening the password file and sending it to the user?
  • What happens if the data itself is malformed or the underlying file is corrupt due to a disk error?

All this just for reading some data from a file, haven't got to the point of actually using the data :slight_smile:

Alex.

1 Like

I see here only a passing mention of DrRacket, which is by far the most significant example. It's large, it's used by lots and lots of people, it has to compete with things like VS Code (albeit in the narrow arena of editing Racket code).

1 Like

@jbclements is absolutely correct: DrRacket is the most sophisticated and frequently used Racket app that comes with the main distribution. -- If you 're into video games, Naughty Dog uses Racket in a sophisticated manner. See Dan Liebgold's RacketCon presentation. -- If you like what the FAA does, it ran (runs?) one of the largest Racket apps around, if not the largest one.

If you would like to study something of modest size (somewhere between 5Kloc and 10Kloc), take a look at my Hey that's my fish tournament manager. It is the kind of app I write every year for running a course at Northeastern ("Socially Responsible Sw Dev"). It follows the code-examples-test style proposed elsewhere.

The app also illustrates some of the "robustness" ideas that @alexh mentioned, including differentiating between "trusted" and "untrusted" components in a system (loading them, discovering various forms of misbehavior, unloading them). As @alexh writes, the language per se does not make a program robust (in any sense). But, I will say that my experience with this course tells me that Racketeers have a significantly easier life than Java devs, Pythonistas, TS or JS fans, etc. I have run the course with the slogan "students choose their own rope" (i.e. their favorite PL) to build the same sw sys. At the end of the semester I run their clients against my servers and vice versa (and lightly check their robustness). I also have each student present his or her project at least three times per semester and inspect how the code in various PLs can realize this form of robustness. My life is so easy compared to my students'. (Of course experienced sw devs may do better than my students but I have the distinct sense, they will not always get close to my elegant Racket solutions and for some things they may do better.)