[ANN] queenshead: a British pub name generator

Just because I could, it doesn’t mean I should have; and yet I did write an entirely unnecessary generator for names of British pubs.

$ opam install queenshead
…
$ queenshead
The horse and goats

More details on this short blog post.

It was a good excuse to experiment with crunch as a way to embed some data files in an OCaml program. Turned out to be easy.

28 Likes

This is an amazing project! We need more fun projects like this in OCaml :trophy:

Only one suggestion.

When I retire, one of the things I want to do is open my own pub. I was thinking about the name a lot and came up with Boozingham Palace. You can add it to the list of your names as well :slightly_smiling_face:

2 Likes

Bravo! Too long have I suffered with type-unsafe pub-name generation in other languages :slight_smile:

11 Likes

A quick and dirty way to embed some text files into OCaml is this:

#! /bin/bash
# embed.sh

echo -n "let content = {|"
cat "$1"
echo '|}'

For example, I want to embed report.html into report.ml. I’m using the script embed.sh above and the Dune rule below to generate it.

(rule
 (target report.ml)
 (deps embed.sh report.html)
 (action
  (with-stdout-to
   %{target}
   (bash "./embed.sh report.html"))))

That’s a good technique. FYI you can do that directly in your dune file: How to Bundle Resources — Dune documentation

4 Likes

Thanks for the suggestion.

Crunch is quite handy because it takes a whole bunch of files at once so the rule for dealing with all seven files is short.

I was thinking of replacing the crunch part with a driver around ppxlib so I can do the parsing line-splitting of the file content at compile-time.

1 Like

Note that we changed the semantics of quoted string literals slightly in trunk (to be released in OCaml 5.2): \r\n sequences in the string literal are now interpreted as a single \n. (But this is not recursive, so for example \r\r\n becomes \r\n.) This is done to avoid the problem of “a Windows user checked out my OCaml project and their system converted \n into \r\n on the fly and the semantics of the string literals changed in the process”.

This might be something to keep in mind if you try to embed arbitrary content inside quoted string literals. (A devious trick suggested by Damien Doligez is to replace, at embedding time, all \n characters in the payload by \r\n, which guarantees that the file will normalize back to the original input.)

3 Likes

The way the names are generated, I can’t easily add names one-by-one… but I could add a TOPONYM variable to use in patterns so that “Boozingham” has a place in there.

1 Like

The copper RuntimeException
The deer and NoSuchMethodException
The knight’s RecursionError
The duck and NotImplementedError

1 Like

The Cozy Camel
The Hindley Milner
The Royal Xavier

3 Likes

It is not a good idea to use those as passwords. :laughing:
Just coming out of a British pub is no excuse.

A few years ago I wrote a general tool for generating things that takes BNF grammars, named BNFGen. I’ve been mostly using it for parser fuzzing, but it saw some fun use, such as this The Elder Scrolls character name generator.

Your project got me thinking about some missing features, though. I could throw together a pub grammar quite easily:

$ opam install bnfgen
$ cat pubs.bnf 
<adjective> ::= "red" | "white" | "black" | "golden" | "sad" | "merry" | "drunken" ;

<animal> ::= "horse" | "rabbit" | "pig" | "dragon" ;
<plant> ::= "oak" | "rose" ;
<person> ::= "queen" | "king" | "smith" | "traveler" | "pilgrim" ;

<body_part> ::= "head" | "leg" | "tail" ;

<item> ::= "house" | "rest" | "sword" ;

<noun> ::= <animal> | <plant> | <person> ;

<pub> ::=
    "The" <adjective> <noun>
  | "The" <noun> "and" <noun>
  | "The" <animal> "'s" <body_part>
  | "The" <person> "'s" <item>
$ 
$ bnfgen --start pub ./pubs.bnf 
The merry oak 
$ bnfgen --start pub ./pubs.bnf 
The sad rabbit 
$ bnfgen --start pub ./pubs.bnf 
The king and horse 
$ bnfgen --start pub ./pubs.bnf 
The dragon 's tail 
$ bnfgen --start pub ./pubs.bnf 
The queen 's sword 
$ bnfgen --start pub ./pubs.bnf 
The rose and rabbit 

But there’s a glaring problem: posessives have a space in them and there’s no way to control that now. I need to think how to add whitespace control options to make it possible to do exactly what your custom generator does.

4 Likes

Should not item also allow animal and plant alternatives ?

They probably should, it’s just a very quick prototype. Another thing is that the way I wrote it allows names like “The queen and the queen”, which looks pretty odd.

For the record, bnfgen does allow a hack to make possessives work, you can use --delimiter "" and embed whitespace in the terminals, but I think that’s quite a pretty ugly hack.