- Typing discipline:
- Versions and implementations (Collapse all | Expand all):
Chef is an esoteric programming language created by David Morgan-Mar, in which programs look like recipes. The main principle of language design is: program recipes should not only generate valid output, but be easy to prepare and delicious. However, no known compilers verify the last requirement.
The language uses the following concepts:
- ingredient — variable. It is referenced by the name of the ingredient, its value is equal to the quantity of the ingredient, and the state of the ingredient (liquid, dry or unspecified) defines whether it will be printed as Unicode character (liquid) or as a number. All values are integer.
- mixing bowls and baking dishes — stacks which store integer values. All operations are done on values in mixing bowls. Baking dishes are used only to print the results. There can be plenty of both kinds of dish — if there are more than one of some kind, they are referred to by their indices (like “the second mixing bowl”).
The program consists of the following parts.
- Recipe title. Describes the purpose of the program in a recipe-like way, for example, “Hello World Souffle” or “Fibonacci Numbers with Caramel Sauce”.
- Comments. Optional free-form paragraph after the title. This is the only place in the code where comments can be placed.
Ingredient list. Holds declarations of variables that will be used, one per line, in the following format:
[initial-value] [[measure-type] measure] ingredient-name. Ingredient name can be arbitrary and can contain spaces. Initial value is optional, but note that all variables must be initialized before they are used. Measure parameters are used to set the type of the ingredient — dry, liquid or undefined.
- Cooking time and oven temperature. Optional parts, used to make the recipe more natural-looking.
- Method. The actual program body, consisting of a sequence of instructions.
- Serves. Prints the contents of the corresponding number of baking dishes. The elements in each dish are printed from top of the stack to the bottom.
- Auxiliary recipes are equivalent of procedures in other languages. They operate on their own ingredients, bowls and dishes, as well as copies of bowls and dishes of the main recipe. Once the auxiliary recipe is done, the contents of its first mixing bowl is added on top of the main recipe’s first mixing bowl (preserving the order).
Take *ingredient* from refrigerator.— read an integer from standard input and store it into the given variable.
Put *ingredient* into [nth] mixing bowl.— push the value of the variable on the top of the bowl. Here and from now on skipping the index of the bowl or dish or the reference to it completely means that there is only one bowl or dish in use.
Fold *ingredient* into [nth] mixing bowl.— pop the top element from the bowl and store it in the variable.
Add *ingredient* [into [nth] mixing bowl].— add the value of the variable to the top element of the bowl.
Remove *ingredient* [from [nth] mixing bowl].— subtract the value of the variable from the top element of the bowl.
Combine *ingredient* [into [nth] mixing bowl].— multiply the top element of the bowl by the value of the variable.
Divide *ingredient* [into [nth] mixing bowl].— divide the top element of the bowl by the value of the variable.
Add dry ingredients [to [nth] mixing bowl].— add up the values of dry ingredients and push them on the top of the bowl.
Liquefy *ingredient*.— change the type of the variable to liquid.
Liquefy contents of the [nth] mixing bowl.— change the type of all values in the bowl to liquid.
Stir [the [nth] mixing bowl] for *N* minutes.— move the top element of the bowl N positions down, and all elements above it — one position up.
Stir *ingredient* into the [nth] mixing bowl.— execute
Stirusing the value of ingredient as
Mix [the [nth] mixing bowl] well.— shuffle the elements of the bowl.
Clean [nth] mixing bowl.— delete all elements of the bowl.
Pour contents of the [nth] mixing bowl into the [pth] baking dish.— copy the elements from the bowl to the dish, preserving their order and putting them on top of the elements which have already been in the dish.
*Verb* the *ingredient*.— beginning of loop. Loop continues as long as the value of loop counter ingredient is non-zero. Any verb can be used to mark the loop.
*Verb* [the ingredient] until *verbed*.— end of loop. Must use the same verb as beginning of the loop. If the ingredient is present, its value is decremented. Note that this ingredient doesn’t have to be the loop counter.
Set aside.— break loop.
Serve with *auxiliary-recipe*.— invoke cooking of auxiliary recipe. Execution of the calling recipe is paused until the auxiliary one is done.
Refrigerate [for *N* hours].— stop executing the recipe. If the value for
Nis given, the contents of first
Nbaking dishes will be printed.
Hello, World!:Example for versions Acme-Chef-1.01
Each ingredient holds ASCII-code of one message character; for convenience their names start with the letters they hold. The codes are placed in the bowl in reverse-printing order. Then Liquify (old spelling of the command is used to make the program run in the interpreter) makes all elements of the bowl liquid (i.e. states that they should be printed as characters). Finally, the contents of the bowl is moved to the baking dish, and
Serves 1 prints its contents.
Lobsters with Fruit and Nuts. This recipe prints "Hello, World!" in a most delicious way. Ingredients. 72 g hazelnuts 101 eggs 108 g lobsters 111 ml orange juice 44 g cashews 32 g sugar 87 ml water 114 g rice 100 g durian 33 passion fruit 10 ml lemon juice Method. Put lemon juice into the mixing bowl. Put passion fruit into the mixing bowl. Put durian into the mixing bowl. Put lobsters into the mixing bowl. Put rice into the mixing bowl. Put orange juice into the mixing bowl. Put water into the mixing bowl. Put sugar into the mixing bowl. Put cashews into the mixing bowl. Put orange juice into the mixing bowl. Put lobsters into the mixing bowl. Put lobsters into the mixing bowl. Put eggs into the mixing bowl. Put hazelnuts into the mixing bowl. Liquify contents of the mixing bowl. Pour contents of the mixing bowl into the baking dish. Serves 1.
Factorial:Example for versions Acme-Chef-1.01
This example uses iterative factorial definition. Ingredients measured in
ml are liquid (characters), the ones measured in
g are dry (numbers).
The program consists of two loops. First one,
chop ... until choped, calculates the factorials in ascending order and pushes elements to be printed in the first bowl, characters and numbers alike. Smaller values which should be printed first end up at the bottom of the stack. This is cured by using the second bowl and the second loop,
mash ... until mashed, which moves elements from the first bowl to the second one, so that they get to be printed in correct order.
Unfortunately, the current version of the interpreter processes liquid ingredients in a wrong way — neither liquid units of measurement, nor the command
luquify modify their state, so they are printed as dry. Thus, the program output looks as follows:
0 33 32 61 32 1 10 1 33 32 61 32 1 10 2 33 32 61 32 2 10 3 33 32 61 32 6 10 4 33 32 61 32 24 10 5 33 32 61 32 120 10 6 33 32 61 32 720 10 7 33 32 61 32 5040 10 8 33 32 61 32 40320 10 9 33 32 61 32 362880 10 10 33 32 61 32 3628800 10 11 33 32 61 32 39916800 10 12 33 32 61 32 479001600 10 13 33 32 61 32 6227020800 10 14 33 32 61 32 87178291200 10 15 33 32 61 32 1307674368000 10 16 33 32 61 32 20922789888000 10
Factorial as a Piece of Cake. This recipe calculates and prints factorials of first integers. Ingredients. 33 ml exclamation 32 ml space 61 ml equal 10 ml newline 0 g n 1 g f 1 g one 17 g iterator 119 g second iterator Method. Liquify exclamation. Liquify space. Liquify equal. Liquify newline. Chop iterator. Put n into 1st mixing bowl. Put exclamation into 1st mixing bowl. Put space into 1st mixing bowl. Put equal into 1st mixing bowl. Put space into 1st mixing bowl. Put f into 1st mixing bowl. Put newline into 1st mixing bowl. Put n into 1st mixing bowl. Add one into 1st mixing bowl. Fold n into 1st mixing bowl. Put f into 1st mixing bowl. Combine n into 1st mixing bowl. Fold f into 1st mixing bowl. Chop iterator until choped. Mash second iterator. Fold n into 1st mixing bowl. Put n into 2nd mixing bowl. Mash second iterator until mashed. Pour contents of 2nd mixing bowl into the baking dish. Serves 1.
Fibonacci numbers:Example for versions Acme-Chef-1.01
This example uses iterative calculation of Fibonacci numbers. Last and one-before-last calculated numbers are stored in ingredients
fib2, respectively. In one iteration of loop
chop ... until choped the next number is calculated, and the previous one is written to the stack for being printed later. Second loop
mash ... until mashed pours the values from first bowl into second one, so that they can be printed in correct (increasing) order.
This version of the interpreter doesn’t allow to hold liquid and dry ingredients on one stack, and thus disallows printing both numbers and characters in one message. This punctuation has been dropped from the output; the result looks as follows:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
Fibonacci numbers. This recipe calculates and prints first Fibonacci numbers. Ingredients. 0 g fib1 1 g fib2 16 g iterator 16 g second iterator Method. Chop iterator. Put fib2 into 1st mixing bowl. Put fib2 into 1st mixing bowl. Add fib1 into 1st mixing bowl. Fold fib2 into 1st mixing bowl. Fold fib1 into 1st mixing bowl. Put fib1 into 1st mixing bowl. Chop iterator until choped. Mash second iterator. Fold fib1 into 1st mixing bowl. Put fib1 into 2nd mixing bowl. Mash second iterator until mashed. Pour contents of 2nd mixing bowl into the baking dish. Serves 1.