git @ Cat's Eye Technologies Quylthulg / rel_1_0_2019_1008
Merge pull request #4 from catseye/develop-2019-3 Develop 2019 3 Chris Pressey authored 11 months ago GitHub committed 11 months ago
10 changed file(s) with 707 addition(s) and 695 deletion(s). Raw diff Collapse all Expand all
+0
-73
HISTORY.markdown less more
0 History of Quylthulg
1 ====================
2
3 Version 1.0
4 -----------
5
6 Initial release, 6 December 2008.
7
8 Version 1.0 revision 2011.1214
9 ------------------------------
10
11 Cosmetic re-packaging.
12
13 Version 1.0 revision 2014.0819
14 ------------------------------
15
16 General modernization and picking of nits. Conversion of documentation to
17 Markdown. Ensuring reference implementation works with both ghc and Hugs.
18
19 Version 1.0 revision 2015.0101
20 ------------------------------
21
22 Added build script, example program, and usage message to reference
23 implementation.
24
25 Version 1.0 revision 2016.0504
26 ------------------------------
27
28 Fixed embarassing [bug](https://github.com/catseye/Quylthulg/issues/1) in
29 the reference implementation, reported by [LegionMammal978](https://github.com/LegionMammal978).
30 The interpreter wasn't able to handle cyclic lists in `foreach` expressions.
31 Also added several example programs and test cases to help confirm the fix.
32
33 Also added `-m` option to the reference implementation, which tells it to
34 use the monadic interpreter.
35
36 Version 1.0 revision 2019.0321
37 ------------------------------
38
39 Added a demo of a web-based interpreter, made by compiling Qlzqqlzuup.hs
40 to Javascript using the Haste compiler, and sticking that into an HTML
41 page along with some support glue.
42
43 Modernized the build system; `bin/qlzqqlzuup` is now a shell script that
44 runs the compiled executable if it can be found, or tries to run the source
45 using `runhaskell` if possible, or tries to run the source using `runhugs`
46 if possible, in that order.
47
48 Forgot to update this HISTORY file.
49
50 Version 1.0 revision 2019.0326
51 ------------------------------
52
53 Changed how Qlzqqlzuup, the Lord of Flesh depicts the final result of
54 running a Quylthulg program.
55
56 Previously, it would simply output the standard derived `show`
57 representation of its internal Haskell data structure. It now formats the
58 result as a literal term in Quylthulg's concrete syntax.
59
60 Such terms can be round-tripped: when treated as Quylthulg programs themselves,
61 they will evaluate to themselves. (This is true in almost all cases.
62 Discovering the one case where it is not true is left as an exercise for the
63 reader.)
64
65 This was done to make the output, if not more readable, then more idiomatic
66 (in some local sense).
67
68 Since the language doesn't really define how the result of a Quylthulg
69 program should be represented, this version number of the language remains
70 unchanged.
71
72 Also fixed a couple of typos in the README.
0 History of Quylthulg
1 ====================
2
3 Version 1.0
4 -----------
5
6 Initial release, 6 December 2008.
7
8 Version 1.0 revision 2011.1214
9 ------------------------------
10
11 Cosmetic re-packaging.
12
13 Version 1.0 revision 2014.0819
14 ------------------------------
15
16 General modernization and picking of nits. Conversion of documentation to
17 Markdown. Ensuring reference implementation works with both ghc and Hugs.
18
19 Version 1.0 revision 2015.0101
20 ------------------------------
21
22 Added build script, example program, and usage message to reference
23 implementation.
24
25 Version 1.0 revision 2016.0504
26 ------------------------------
27
28 Fixed embarassing [bug](https://github.com/catseye/Quylthulg/issues/1) in
29 the reference implementation, reported by [LegionMammal978](https://github.com/LegionMammal978).
30 The interpreter wasn't able to handle cyclic lists in `foreach` expressions.
31 Also added several example programs and test cases to help confirm the fix.
32
33 Also added `-m` option to the reference implementation, which tells it to
34 use the monadic interpreter.
35
36 Version 1.0 revision 2019.0321
37 ------------------------------
38
39 Added a demo of a web-based interpreter, made by compiling Qlzqqlzuup.hs
40 to Javascript using the Haste compiler, and sticking that into an HTML
41 page along with some support glue.
42
43 Modernized the build system; `bin/qlzqqlzuup` is now a shell script that
44 runs the compiled executable if it can be found, or tries to run the source
45 using `runhaskell` if possible, or tries to run the source using `runhugs`
46 if possible, in that order.
47
48 Forgot to update this HISTORY file.
49
50 Version 1.0 revision 2019.0326
51 ------------------------------
52
53 Changed how Qlzqqlzuup, the Lord of Flesh depicts the final result of
54 running a Quylthulg program.
55
56 Previously, it would simply output the standard derived `show`
57 representation of its internal Haskell data structure. It now formats the
58 result as a literal term in Quylthulg's concrete syntax.
59
60 Such terms can be round-tripped: when treated as Quylthulg programs themselves,
61 they will evaluate to themselves. (This is true in almost all cases.
62 Discovering the one case where it is not true is left as an exercise for the
63 reader.)
64
65 This was done to make the output, if not more readable, then more idiomatic
66 (in some local sense).
67
68 Since the language doesn't really define how the result of a Quylthulg
69 program should be represented, this version number of the language remains
70 unchanged.
71
72 Also fixed a couple of typos in the README.
73
74 Version 1.0 revision 2019.1008
75 ------------------------------
76
77 The driver script now understands the environment variable `FORCE_HUGS` to
78 mean you want to run Qlzqqlzuup using Hugs, even if you have `ghc` available.
79
80 Simplified and updated Haste driver code and command-line driver code.
81
82 Renamed `.markdown` file extensions to `.md`.
+0
-386
README.markdown less more
0 The Quylthulg Programming Language
1 ==================================
2
3 Overview
4 --------
5
6 Here is what is known about the programming language Quylthulg.
7 Quylthulg:
8
9 - is a programming language;
10 - is named Quylthulg;
11 - was designed by Chris Pressey;
12 - does *not*, quite apart from prevailing trends in programming
13 practice, shun the use of `goto`;
14 - is, however, somewhat particular about *where* `goto` may be used
15 (`goto` may only occur inside a data structure);
16 - is purely functional (in the sense that it does not allow
17 "side-effectful" updates to values);
18 - forbids recursion;
19 - provides but a single looping construct: `foreach`, which applies an
20 expression successively to each value in a data structure;
21 - is Turing-complete; and
22 - boasts an argument-less macro expansion facility (in which recursion
23 is also forbidden.)
24
25 Syntax
26 ------
27
28 The syntax for identifiers draws from the best parts of the esteemed
29 languages BASIC and Perl. Like Perl, all identifiers must be preceded by
30 a `$` symbol, and like BASIC, all identifiers must be followed by a `$`
31 symbol. Well, OK, that's for strings anyway, but we don't care about
32 their types really, so we use `$` for everything. (Also, studies show
33 that this syntax can help serious TeX addicts from "bugging out".)
34
35 A nice practical upshot of this is that identifier names may contain any
36 characters whatsoever (excepting `$`), including whitespace.
37
38 Because of this, the syntax for string literals can be, and is, derived
39 from the syntax for identifiers. A string literal is given by a `~`
40 followed by an identifier; the textual content of the name of the
41 identifier is used as the content of the string literal. A string
42 literal consisting of a single `$` symbol is given by `~~`.
43
44 Many find the syntax for labels to be quite sumilar to that for
45 identifiers. (Some even find it to be quite similar.) Labels are
46 preceded and followed by `:` symbols, and may contain any symbol except
47 for `:`.
48
49 Syntax for binary operations follows somewhat in the footsteps of the
50 identifier syntax. It is a combination of prefix, infix, and postfix
51 syntax, where the two terms must be preceeded, followed, and seperated
52 by the same symbol. We call this notation *panfix*. It is perhaps worth
53 noting that, like postfix, panfix does not require the deployment of
54 arcane contrivances such as *parentheses* to override a default operator
55 precedence. At the same time, panfix allows terms to be specified in the
56 same order and manner as infix, an unquestionably natural and intuitive
57 notation to those who have become accustomed to it.
58
59 So, we give some examples:
60
61 *+1+2+*3*
62 &~$The shoes are $&&~~&~$9.99 a pair.$&&
63
64 The first example might be stated as (1+2)\*3 in conventional, icky
65 parenthesis-ful notation, and evaluates to 9. The second evaluates to
66 the string "The shoes are $9.99 a pair."
67
68 There are no unary operators in Quylthulg. (Note that `~` isn't really a
69 unary operator, actually not an operator at all, because it must be
70 followed by an identifier, not an expression. Well, maybe it's a special
71 kind of operator then, an identifier-operator perhaps. But you see what
72 I'm getting at, don't you? Hopefully not.)
73
74 There is a special 6-ary operator, `foreach`. It has its own syntax
75 which will be covered below.
76
77 Data Types
78 ----------
79
80 ### Strings and Integers ###
81
82 Yes. Also a special type called `abort`, of which there is a single
83 value `abort`, which you'll learn about later.
84
85 ### Lists ###
86
87 The sole data structure of note in Quylthulg is the list. Lists are
88 essentially identical to those found in other functional languages such
89 as Scheme: they are either the special value `null`, which suggests an
90 empty list, or they consist of a `cons` cell, which is a pair of two
91 other values. By convention, the first of this pair is the value of this
92 list node, and the second is a sublist (a `null` or a `cons`) which
93 represents the rest of this list.
94
95 The value of a list node may be any value: a scalar such as an integer
96 or a string, another (embedded sub)list, or the special value `abort`.
97 `cons` cells are constructed by the `,` panfix operator. Some examples
98 follow:
99
100 ,1,,2,,3,null,,,
101 ,1,,2,3,,
102
103 The first example constructs a proper list. So-called "improper" lists,
104 which purely by convention do not end with `null`, can also be
105 constructed: that's the second example.
106
107 When all of the terms involved are literal constants embedded in the
108 program text, there is a shorthand syntax for these list expressions,
109 stolen from the Prolog/Erlang school:
110
111 [1, 2, 3]
112 [1, 2 | 3]
113
114 Note, however, that `[]` is not shorthand for `null`. Note also that
115 when this syntax is used, all values *must* be literal constants: there
116 will be no tolerance for variables. There will, however, be tolerance
117 for `goto`s and labels; see below for more on that.
118
119 ### Cyclic Lists ###
120
121 Labels and the `goto` construct enable the definition of cyclic data
122 structures like so:
123
124 :A:[1, 2, 3, goto $A$]
125 :B:[1, 2, :C:[3, 4, goto $B$], 5, 6, goto $C$]
126
127 Note that this can only be done in literal constant data structure
128 expressions, not in `,` (`cons`ing) operations or expression involving a
129 variable. This is to avoid the dynamic construction of labelled terms,
130 which just a tad mind-bending and which I've decided to save for a
131 sequel to Quylthulg, whatever and whenever that might be. Note also that
132 labels have their own syntax during declaration, but (oh so helpfully)
133 insist on being referred to in `goto`s by the `$` syntax used for
134 identifiers.
135
136 ### List Operators ###
137
138 The values contained in a `cons` cell can be extracted by the felicitous
139 use of the binary operators `<` ('first') and `>` ('rest'). For both of
140 these operators, the left-hand side is the `cons` cell to operate on,
141 and the right-hand side is an expression which the operator will
142 evaluate to in the case that it cannot successfully extract the value
143 from the `cons` cell (e.g., the left-hand side is not in fact a `cons`
144 cell but rather something else like a `null` or a number or a string or
145 `abort`.
146
147 There is also an operator `;` which appends one list (the right-hand
148 side) onto the end of another list (the left-hand side.) This is
149 probably not strictly necessary, since as we'll see later we can probably
150 build something equivalent using `foreach`es and macros, but what the
151 hell, we can afford it. Party down.
152
153 These list operators honour cyclic lists, so that
154 `>[:X: 4 | goto :X:]>abort>`, to take just one instance, evaluates to 4.
155
156 Control Flow
157 ------------
158
159 Quylthulg's sole looping construct, `foreach`, is a recursing abortable
160 "fold" operation. It is passed a data structure to traverse, an
161 expression (called the *body*) that it will apply to each value it
162 encounters in the traversed data structure, and an initial value called
163 the *accumulator*. Inside the body, two identifiers are bound to two
164 values: the value in the data structure that the body is currently being
165 applied to, and the value of the current value. The names of the
166 idenfiers so bound are specified in the syntax of the `foreach`
167 operator. The value that the body evaluates to is used as the
168 accumulator for the next time the body is evaluated, on the next value
169 in the data structure. The value that `foreach` evaluates to is the
170 value of the **final** accumulator (emphasis mine.) The full form of this
171 operator is as follows:
172
173 foreach $var$ = data-expr with $acc$ = initial-expr be loop-expr else be otherwise-expr
174
175 `foreach` traverses the data structure in this manner: from beginning to
176 end. It is:
177
178 - *recursing*, meaning if the current element of the list is itself a
179 (sub)list, `foreach` will begin traversing that (sub)list (with the
180 same body and current accumulator, natch) instead of passing the
181 (sub)list to the body; and
182 - *abortable*, meaning that the *loop-expr* may evaluate to a special
183 value `abort`, which causes traversal of the current (sub)list to
184 cease immediately, returning to the traversal of the containing
185 list, if any.
186
187 If the *data-expr* evaluates to some value besides a `cons` cell (for
188 example, `null` or an integer or a string), then the *loop-expr* is
189 ignored and the *otherwise-expr* is evaluated instead.
190
191 As an example,
192
193 -foreach $x$ = [2, 3, 4] with $a$ = 1 be *$a$*$x$* else be null-1-
194
195 will evaluate to 23. On the other hand,
196
197 foreach $x$ = null with $a$ = 1 be $a$ else be 23
198
199 will also evaluate to 23.
200
201 Macro System
202 ------------
203
204 Quylthulg boasts an argument-less macro expansion system. (Yes, there is
205 no argument about it: it *boasts* it. It is quite arrogant, you know.)
206 Where-ever text of the form `{foo}` appears in the source code, the
207 contents of the macro named `foo` are inserted at that point, replacing
208 `{foo}`. This process is called the *expansion* of `foo`. But it gets
209 worse: whereever text of the form `{bar}` appears in the contents of
210 that macro called `foo`, those too will be replaced by the contents of
211 the macro called `bar`. And so on. Three things to note:
212
213 - If there is no macro called `foo`, `{foo}` will not be expanded.
214 - If `{foo}` appears in the contents of `foo`, it will not be
215 expanded.
216 - Nor will it be expanded if it appears in the contents of `foo` as
217 the result of expanding some other macro in the contents of `foo`.
218
219 (I stand corrected. That was more like 2.5 things to note.)
220
221 Macros can be defined and redefined with the special macro-like form
222 `{*[foo][bar]}`. The first text between square brackets is the name of
223 the macro being defined; the text between the second square brackets is
224 the contents. Both texts can contain any symbols except unmatched `]`'s.
225 i.e. you can put square brackets in these texts as long as they nest
226 properly.
227
228 Now you see why we don't need arguments to these macros: you can simply
229 use macros as arguments. For example,
230
231 {*[SQR][*{X}*{X}*]}{*[X][5]}{SQR}
232
233 uses an "argument macro" called `X` which it defines as `5` before
234 calling the `SQR` macro that uses it.
235
236 Note that macros are expanded before any scanning or parsing of the
237 program text begins. Thus they can be used to define identifiers,
238 labels, etc.
239
240 ### Comments
241
242 The macro system also provides a way to insert comments into a Quylthulg
243 program. It should be noted that there are at least three schools of
244 thought on this subject.
245
246 The first school (Chilton County High School in Clanton, Alabama) says
247 that most comments that programmers write are next to useless anyway
248 (which is absolutely true) so there's no point in writing them at all.
249
250 The second school (Gonzaga College S.J. in Dublin, Ireland — not to be
251 confused with Gonzaga University in Spokane, Washington) considers
252 comments to be valuable *as comments*, but not as source code. They
253 advocate their use in Quylthulg by the definition of macros that are
254 unlikely to be expanded for obscure syntactical reasons. For example,
255 `{*[}][This is my comment!]}`. Note that that macro *can* be expanded in
256 Quylthulg using `{}}`; it's just that the Gonzaga school hopes that you
257 won't do that, and hopes you get a syntax error if you try.
258
259 The third school (a school of fish) believes that comments are valuable,
260 not just as comments, but also as integral (or at least distracting)
261 parts of the computation, and champions their use in Quylthulg as string
262 literals involved in expressions that are ultimately discarded. For
263 example, `<~$Addition is fun!$<+1+2+<`.
264
265 ### Integration with the Rest of the Language
266
267 To dispel the vicious rumours that the macro system used in Quylthulg
268 and the Quylthulg language are really independent and separate entities
269 which just *happen* to be sandwiched together there, we are quick to
270 point out that they are bound by two very important means:
271
272 - At the beginning of the program, at a global scope, the identifier
273 `$Number of Macros Defined$` is bound to an integer constant
274 containing the number of unique macros that were defined during
275 macro expansion before the program was parsed.
276 - The panfix operator `%` applies macros to a Quylthulg string at
277 runtime. The expression on the left-hand side should evaluate to a
278 string which contains macro definitions. The expression on the
279 right-hand side is the string to expand using these macro
280 definitions.
281
282 Turing-Completeness
283 -------------------
284
285 Now, I claim that Quylthulg is Turing-complete — that is, that it can
286 compute anything that a Turing machine (or any other Turing-complete
287 system) can. I would provide a proof, but since the point of a proof is
288 to dispel doubt, and since you have not expressed any doubt so far (at
289 least none that I have been able to observe from my vantage point), and
290 since (statistically speaking anyway) you believe that fluoride in
291 drinking water promotes dental health, that the sun is a giant nuclear
292 furnace, that Wall Street is substantially different from Las Vegas,
293 that a low-fat diet is an effective way to lose weight, that black holes
294 exist, and that point of the War on Drugs is to stop people from harming
295 themselves — well, in light of all that, a proof hardly seems
296 called-for. Instead, I shall perform a series of short vignettes, each
297 intended to invoke the spirit of a different forest animal or
298 supermarket checkout animal. Then I shall spray you with a dose of a new
299 household aerosol which I have invented and which I am marketing under
300 the name "Doubt-B-Gone".
301
302 - We can use `foreach` as an if-then-else construct by using lists to
303 represent booleans.
304
305 Using `null` to represent false, and `cons` anything to represent
306 true, we use the `else` part of `foreach` to accomplish a boolean
307 if-then-else. We can employ `;` to get boolean OR and nested
308 `foreach`es to get boolean AND. (Detailed examples of these can be
309 found in the unit tests of the Quylthulg reference interpreter,
310 which is called "Qlzqqlzuup, Lord of Flesh".)
311
312 - We can construct an infinite loop by running `foreach` on a cyclic
313 data structure.
314
315 For example,
316
317 foreach $x$ = :L:[1, 2, 3, goto $L$] with $a$ = 0 be $x$ else be null
318
319 never finishes evaluating, and in the body, `$x$` takes on the
320 values 1, 2, 3, 1, 2, 3, ... ad infinitum.
321
322 - We can treat the accumulator of a `foreach` like an unbounded tape,
323 just like on a Turing machine.
324
325 We can pass in a `cons` cell where the first value is a list
326 representing everything to the left of the head, and the second
327 value is a list representing everything to the right of the head.
328 Moving the head left or right can be accomplished by taking the
329 first (`<`) off the appropriate list and cons (`,`) it onto the
330 other list. There are also other ways to do it, of course. The point
331 is that there is no bound specified on the length of a list in
332 Quylthulg.
333
334 - We can, in fact, make `foreach` act like a `while` construct.
335
336 We just combine the looping forever with an if-then-else which
337 evaluates to `abort` when the condition comes true.
338
339 - We can give `foreach` a cyclic tree-like data structure which
340 describes the finite control of a Turing machine.
341
342 Although we don't have to — we could just use nested `foreach`es to
343 make a lot of tests against constant values.
344
345 - We can even make `foreach` work like `let` if we need to.
346
347 Just bind the accumulator to `$Name$`, refer to `$Name$` in the
348 body, and ignore the contents of the one-element list. Or use it to
349 bind two variables in one `foreach`.
350
351 PHHSHHHHHHHHHHHHHHTt.
352
353 Discussion
354 ----------
355
356 Now I'm hardly the first person to suggest using cyclic lists as an
357 equivalent alternative to a general looping construct such as `while`.
358 It has long been a [stylish LISP programming
359 technique](http://www.ccs.neu.edu/home/shivers/newstyle.html). However,
360 to comply with the Nietzschean-Calvinist mandate of our society (that
361 is, to *sustain* the *progress* that will *thrust* us toward the
362 "Perfect Meat at the End of Time" of which Hegel spoke,) we must
363 *demonstrate* that we have **innovated**:
364
365 - Quylthulg provides *only* this method of looping; without it, it
366 would not be Turing-complete, and
367 - Unlike the extant stylish programming techniques, which require
368 side-effecting operations such as `rplacd` to pull off, Quylthulg is
369 a pure functional programming language *without* updatable storage.
370
371 Huzzah.
372
373 It is somewhat sad to consider just how long Quylthulg took to design
374 and how much of that labour took place aboard airplanes. It is even
375 sadder to consider some of the delusions I was occupied with while
376 designing it. Some of the biggest were the idea that `foreach` somehow
377 had to be recursable for this to work — it doesn't, but I left it in.
378 For similar reasons I left in `;`, the append operator. And I've already
379 mentioned the headaches with allowing labels and `goto`s in expressions
380 rather than only in literals.
381
382 Long live the new flesh, eh?
383 Chris Pressey
384 Seattle, Washington
385 Dec 6, 2008
0 The Quylthulg Programming Language
1 ==================================
2
3 Overview
4 --------
5
6 Here is what is known about the programming language Quylthulg.
7 Quylthulg:
8
9 - is a programming language;
10 - is named Quylthulg;
11 - was designed by Chris Pressey;
12 - does *not*, quite apart from prevailing trends in programming
13 practice, shun the use of `goto`;
14 - is, however, somewhat particular about *where* `goto` may be used
15 (`goto` may only occur inside a data structure);
16 - is purely functional (in the sense that it does not allow
17 "side-effectful" updates to values);
18 - forbids recursion;
19 - provides but a single looping construct: `foreach`, which applies an
20 expression successively to each value in a data structure;
21 - is Turing-complete; and
22 - boasts an argument-less macro expansion facility (in which recursion
23 is also forbidden.)
24
25 Syntax
26 ------
27
28 The syntax for identifiers draws from the best parts of the esteemed
29 languages BASIC and Perl. Like Perl, all identifiers must be preceded by
30 a `$` symbol, and like BASIC, all identifiers must be followed by a `$`
31 symbol. Well, OK, that's for strings anyway, but we don't care about
32 their types really, so we use `$` for everything. (Also, studies show
33 that this syntax can help serious TeX addicts from "bugging out".)
34
35 A nice practical upshot of this is that identifier names may contain any
36 characters whatsoever (excepting `$`), including whitespace.
37
38 Because of this, the syntax for string literals can be, and is, derived
39 from the syntax for identifiers. A string literal is given by a `~`
40 followed by an identifier; the textual content of the name of the
41 identifier is used as the content of the string literal. A string
42 literal consisting of a single `$` symbol is given by `~~`.
43
44 Many find the syntax for labels to be quite sumilar to that for
45 identifiers. (Some even find it to be quite similar.) Labels are
46 preceded and followed by `:` symbols, and may contain any symbol except
47 for `:`.
48
49 Syntax for binary operations follows somewhat in the footsteps of the
50 identifier syntax. It is a combination of prefix, infix, and postfix
51 syntax, where the two terms must be preceeded, followed, and seperated
52 by the same symbol. We call this notation *panfix*. It is perhaps worth
53 noting that, like postfix, panfix does not require the deployment of
54 arcane contrivances such as *parentheses* to override a default operator
55 precedence. At the same time, panfix allows terms to be specified in the
56 same order and manner as infix, an unquestionably natural and intuitive
57 notation to those who have become accustomed to it.
58
59 So, we give some examples:
60
61 *+1+2+*3*
62 &~$The shoes are $&&~~&~$9.99 a pair.$&&
63
64 The first example might be stated as (1+2)\*3 in conventional, icky
65 parenthesis-ful notation, and evaluates to 9. The second evaluates to
66 the string "The shoes are $9.99 a pair."
67
68 There are no unary operators in Quylthulg. (Note that `~` isn't really a
69 unary operator, actually not an operator at all, because it must be
70 followed by an identifier, not an expression. Well, maybe it's a special
71 kind of operator then, an identifier-operator perhaps. But you see what
72 I'm getting at, don't you? Hopefully not.)
73
74 There is a special 6-ary operator, `foreach`. It has its own syntax
75 which will be covered below.
76
77 Data Types
78 ----------
79
80 ### Strings and Integers ###
81
82 Yes. Also a special type called `abort`, of which there is a single
83 value `abort`, which you'll learn about later.
84
85 ### Lists ###
86
87 The sole data structure of note in Quylthulg is the list. Lists are
88 essentially identical to those found in other functional languages such
89 as Scheme: they are either the special value `null`, which suggests an
90 empty list, or they consist of a `cons` cell, which is a pair of two
91 other values. By convention, the first of this pair is the value of this
92 list node, and the second is a sublist (a `null` or a `cons`) which
93 represents the rest of this list.
94
95 The value of a list node may be any value: a scalar such as an integer
96 or a string, another (embedded sub)list, or the special value `abort`.
97 `cons` cells are constructed by the `,` panfix operator. Some examples
98 follow:
99
100 ,1,,2,,3,null,,,
101 ,1,,2,3,,
102
103 The first example constructs a proper list. So-called "improper" lists,
104 which purely by convention do not end with `null`, can also be
105 constructed: that's the second example.
106
107 When all of the terms involved are literal constants embedded in the
108 program text, there is a shorthand syntax for these list expressions,
109 stolen from the Prolog/Erlang school:
110
111 [1, 2, 3]
112 [1, 2 | 3]
113
114 Note, however, that `[]` is not shorthand for `null`. Note also that
115 when this syntax is used, all values *must* be literal constants: there
116 will be no tolerance for variables. There will, however, be tolerance
117 for `goto`s and labels; see below for more on that.
118
119 ### Cyclic Lists ###
120
121 Labels and the `goto` construct enable the definition of cyclic data
122 structures like so:
123
124 :A:[1, 2, 3, goto $A$]
125 :B:[1, 2, :C:[3, 4, goto $B$], 5, 6, goto $C$]
126
127 Note that this can only be done in literal constant data structure
128 expressions, not in `,` (`cons`ing) operations or expression involving a
129 variable. This is to avoid the dynamic construction of labelled terms,
130 which just a tad mind-bending and which I've decided to save for a
131 sequel to Quylthulg, whatever and whenever that might be. Note also that
132 labels have their own syntax during declaration, but (oh so helpfully)
133 insist on being referred to in `goto`s by the `$` syntax used for
134 identifiers.
135
136 ### List Operators ###
137
138 The values contained in a `cons` cell can be extracted by the felicitous
139 use of the binary operators `<` ('first') and `>` ('rest'). For both of
140 these operators, the left-hand side is the `cons` cell to operate on,
141 and the right-hand side is an expression which the operator will
142 evaluate to in the case that it cannot successfully extract the value
143 from the `cons` cell (e.g., the left-hand side is not in fact a `cons`
144 cell but rather something else like a `null` or a number or a string or
145 `abort`.
146
147 There is also an operator `;` which appends one list (the right-hand
148 side) onto the end of another list (the left-hand side.) This is
149 probably not strictly necessary, since as we'll see later we can probably
150 build something equivalent using `foreach`es and macros, but what the
151 hell, we can afford it. Party down.
152
153 These list operators honour cyclic lists, so that
154 `>[:X: 4 | goto :X:]>abort>`, to take just one instance, evaluates to 4.
155
156 Control Flow
157 ------------
158
159 Quylthulg's sole looping construct, `foreach`, is a recursing abortable
160 "fold" operation. It is passed a data structure to traverse, an
161 expression (called the *body*) that it will apply to each value it
162 encounters in the traversed data structure, and an initial value called
163 the *accumulator*. Inside the body, two identifiers are bound to two
164 values: the value in the data structure that the body is currently being
165 applied to, and the value of the current value. The names of the
166 idenfiers so bound are specified in the syntax of the `foreach`
167 operator. The value that the body evaluates to is used as the
168 accumulator for the next time the body is evaluated, on the next value
169 in the data structure. The value that `foreach` evaluates to is the
170 value of the **final** accumulator (emphasis mine.) The full form of this
171 operator is as follows:
172
173 foreach $var$ = data-expr with $acc$ = initial-expr be loop-expr else be otherwise-expr
174
175 `foreach` traverses the data structure in this manner: from beginning to
176 end. It is:
177
178 - *recursing*, meaning if the current element of the list is itself a
179 (sub)list, `foreach` will begin traversing that (sub)list (with the
180 same body and current accumulator, natch) instead of passing the
181 (sub)list to the body; and
182 - *abortable*, meaning that the *loop-expr* may evaluate to a special
183 value `abort`, which causes traversal of the current (sub)list to
184 cease immediately, returning to the traversal of the containing
185 list, if any.
186
187 If the *data-expr* evaluates to some value besides a `cons` cell (for
188 example, `null` or an integer or a string), then the *loop-expr* is
189 ignored and the *otherwise-expr* is evaluated instead.
190
191 As an example,
192
193 -foreach $x$ = [2, 3, 4] with $a$ = 1 be *$a$*$x$* else be null-1-
194
195 will evaluate to 23. On the other hand,
196
197 foreach $x$ = null with $a$ = 1 be $a$ else be 23
198
199 will also evaluate to 23.
200
201 Macro System
202 ------------
203
204 Quylthulg boasts an argument-less macro expansion system. (Yes, there is
205 no argument about it: it *boasts* it. It is quite arrogant, you know.)
206 Where-ever text of the form `{foo}` appears in the source code, the
207 contents of the macro named `foo` are inserted at that point, replacing
208 `{foo}`. This process is called the *expansion* of `foo`. But it gets
209 worse: whereever text of the form `{bar}` appears in the contents of
210 that macro called `foo`, those too will be replaced by the contents of
211 the macro called `bar`. And so on. Three things to note:
212
213 - If there is no macro called `foo`, `{foo}` will not be expanded.
214 - If `{foo}` appears in the contents of `foo`, it will not be
215 expanded.
216 - Nor will it be expanded if it appears in the contents of `foo` as
217 the result of expanding some other macro in the contents of `foo`.
218
219 (I stand corrected. That was more like 2.5 things to note.)
220
221 Macros can be defined and redefined with the special macro-like form
222 `{*[foo][bar]}`. The first text between square brackets is the name of
223 the macro being defined; the text between the second square brackets is
224 the contents. Both texts can contain any symbols except unmatched `]`'s.
225 i.e. you can put square brackets in these texts as long as they nest
226 properly.
227
228 Now you see why we don't need arguments to these macros: you can simply
229 use macros as arguments. For example,
230
231 {*[SQR][*{X}*{X}*]}{*[X][5]}{SQR}
232
233 uses an "argument macro" called `X` which it defines as `5` before
234 calling the `SQR` macro that uses it.
235
236 Note that macros are expanded before any scanning or parsing of the
237 program text begins. Thus they can be used to define identifiers,
238 labels, etc.
239
240 ### Comments
241
242 The macro system also provides a way to insert comments into a Quylthulg
243 program. It should be noted that there are at least three schools of
244 thought on this subject.
245
246 The first school (Chilton County High School in Clanton, Alabama) says
247 that most comments that programmers write are next to useless anyway
248 (which is absolutely true) so there's no point in writing them at all.
249
250 The second school (Gonzaga College S.J. in Dublin, Ireland — not to be
251 confused with Gonzaga University in Spokane, Washington) considers
252 comments to be valuable *as comments*, but not as source code. They
253 advocate their use in Quylthulg by the definition of macros that are
254 unlikely to be expanded for obscure syntactical reasons. For example,
255 `{*[}][This is my comment!]}`. Note that that macro *can* be expanded in
256 Quylthulg using `{}}`; it's just that the Gonzaga school hopes that you
257 won't do that, and hopes you get a syntax error if you try.
258
259 The third school (a school of fish) believes that comments are valuable,
260 not just as comments, but also as integral (or at least distracting)
261 parts of the computation, and champions their use in Quylthulg as string
262 literals involved in expressions that are ultimately discarded. For
263 example, `<~$Addition is fun!$<+1+2+<`.
264
265 ### Integration with the Rest of the Language
266
267 To dispel the vicious rumours that the macro system used in Quylthulg
268 and the Quylthulg language are really independent and separate entities
269 which just *happen* to be sandwiched together there, we are quick to
270 point out that they are bound by two very important means:
271
272 - At the beginning of the program, at a global scope, the identifier
273 `$Number of Macros Defined$` is bound to an integer constant
274 containing the number of unique macros that were defined during
275 macro expansion before the program was parsed.
276 - The panfix operator `%` applies macros to a Quylthulg string at
277 runtime. The expression on the left-hand side should evaluate to a
278 string which contains macro definitions. The expression on the
279 right-hand side is the string to expand using these macro
280 definitions.
281
282 Turing-Completeness
283 -------------------
284
285 Now, I claim that Quylthulg is Turing-complete — that is, that it can
286 compute anything that a Turing machine (or any other Turing-complete
287 system) can. I would provide a proof, but since the point of a proof is
288 to dispel doubt, and since you have not expressed any doubt so far (at
289 least none that I have been able to observe from my vantage point), and
290 since (statistically speaking anyway) you believe that fluoride in
291 drinking water promotes dental health, that the sun is a giant nuclear
292 furnace, that Wall Street is substantially different from Las Vegas,
293 that a low-fat diet is an effective way to lose weight, that black holes
294 exist, and that point of the War on Drugs is to stop people from harming
295 themselves — well, in light of all that, a proof hardly seems
296 called-for. Instead, I shall perform a series of short vignettes, each
297 intended to invoke the spirit of a different forest animal or
298 supermarket checkout animal. Then I shall spray you with a dose of a new
299 household aerosol which I have invented and which I am marketing under
300 the name "Doubt-B-Gone".
301
302 - We can use `foreach` as an if-then-else construct by using lists to
303 represent booleans.
304
305 Using `null` to represent false, and `cons` anything to represent
306 true, we use the `else` part of `foreach` to accomplish a boolean
307 if-then-else. We can employ `;` to get boolean OR and nested
308 `foreach`es to get boolean AND. (Detailed examples of these can be
309 found in the unit tests of the Quylthulg reference interpreter,
310 which is called "Qlzqqlzuup, Lord of Flesh".)
311
312 - We can construct an infinite loop by running `foreach` on a cyclic
313 data structure.
314
315 For example,
316
317 foreach $x$ = :L:[1, 2, 3, goto $L$] with $a$ = 0 be $x$ else be null
318
319 never finishes evaluating, and in the body, `$x$` takes on the
320 values 1, 2, 3, 1, 2, 3, ... ad infinitum.
321
322 - We can treat the accumulator of a `foreach` like an unbounded tape,
323 just like on a Turing machine.
324
325 We can pass in a `cons` cell where the first value is a list
326 representing everything to the left of the head, and the second
327 value is a list representing everything to the right of the head.
328 Moving the head left or right can be accomplished by taking the
329 first (`<`) off the appropriate list and cons (`,`) it onto the
330 other list. There are also other ways to do it, of course. The point
331 is that there is no bound specified on the length of a list in
332 Quylthulg.
333
334 - We can, in fact, make `foreach` act like a `while` construct.
335
336 We just combine the looping forever with an if-then-else which
337 evaluates to `abort` when the condition comes true.
338
339 - We can give `foreach` a cyclic tree-like data structure which
340 describes the finite control of a Turing machine.
341
342 Although we don't have to — we could just use nested `foreach`es to
343 make a lot of tests against constant values.
344
345 - We can even make `foreach` work like `let` if we need to.
346
347 Just bind the accumulator to `$Name$`, refer to `$Name$` in the
348 body, and ignore the contents of the one-element list. Or use it to
349 bind two variables in one `foreach`.
350
351 PHHSHHHHHHHHHHHHHHTt.
352
353 Discussion
354 ----------
355
356 Now I'm hardly the first person to suggest using cyclic lists as an
357 equivalent alternative to a general looping construct such as `while`.
358 It has long been a [stylish LISP programming
359 technique](http://www.ccs.neu.edu/home/shivers/newstyle.html). However,
360 to comply with the Nietzschean-Calvinist mandate of our society (that
361 is, to *sustain* the *progress* that will *thrust* us toward the
362 "Perfect Meat at the End of Time" of which Hegel spoke,) we must
363 *demonstrate* that we have **innovated**:
364
365 - Quylthulg provides *only* this method of looping; without it, it
366 would not be Turing-complete, and
367 - Unlike the extant stylish programming techniques, which require
368 side-effecting operations such as `rplacd` to pull off, Quylthulg is
369 a pure functional programming language *without* updatable storage.
370
371 Huzzah.
372
373 It is somewhat sad to consider just how long Quylthulg took to design
374 and how much of that labour took place aboard airplanes. It is even
375 sadder to consider some of the delusions I was occupied with while
376 designing it. Some of the biggest were the idea that `foreach` somehow
377 had to be recursable for this to work — it doesn't, but I left it in.
378 For similar reasons I left in `;`, the append operator. And I've already
379 mentioned the headaches with allowing labels and `goto`s in expressions
380 rather than only in literals.
381
382 Long live the new flesh, eh?
383 Chris Pressey
384 Seattle, Washington
385 Dec 6, 2008
33 DIR=`dirname $THIS`
44 NAME=`basename $THIS`
55 SRC=$DIR/../src
6 if [ -x $DIR/$NAME.exe ] ; then
6 if [ "x$FORCE_HUGS" != "x" ] ; then
7 exec runhugs -i$SRC $SRC/Main.hs $*
8 elif [ -x $DIR/$NAME.exe ] ; then
79 exec $DIR/$NAME.exe $*
810 elif command -v runhaskell 2>&1 >/dev/null ; then
911 exec runhaskell -i$SRC $SRC/Main.hs $*
1012 elif command -v runhugs 2>&1 >/dev/null ; then
1113 exec runhugs -i$SRC $SRC/Main.hs $*
1214 else
13 echo "Cannot run $NAME; neither $NAME.exe, runhaskell, nor runhugs found."
15 echo "Cannot run $NAME; neither $NAME.exe, nor runhaskell, nor runhugs found."
1416 exit 1
1517 fi
00 module Main where
11
2 import Haste
3 import Haste.DOM
4 import Haste.Events
2 import Haste.DOM (withElems, getValue, setProp)
3 import Haste.Events (onEvent, MouseEvent(Click))
54
65 import Qlzqqlzuup
76
7
88 main = withElems ["prog", "result", "run-button"] driver
99
10 escapeHTML "" = ""
11 escapeHTML ('<' : rest) = "&lt;" ++ escapeHTML rest
12 escapeHTML ('>' : rest) = "&gt;" ++ escapeHTML rest
13 escapeHTML ('&' : rest) = "&amp;" ++ escapeHTML rest
14 escapeHTML (c : rest) = (c : escapeHTML rest)
15
16 driver [progElem, resultElem, runButtonElem] = do
17 onEvent runButtonElem Click $ \_ -> execute
18 where
19 execute = do
20 Just prog <- getValue progElem
21 setProp resultElem "innerHTML" (escapeHTML $ showRun prog)
10 driver [progElem, resultElem, runButtonElem] =
11 onEvent runButtonElem Click $ \_ -> do
12 Just prog <- getValue progElem
13 setProp resultElem "textContent" $ showRun prog
00 module Main where
11
22 import System.Environment
3 import System.Exit
4 import System.IO
5
36 import Qlzqqlzuup
7
48
59 main = do
610 args <- getArgs
1418 putStrLn $ showRun c
1519 return ()
1620 _ -> do
17 putStrLn "Usage: qlzqqlzuup [-m] <filename.quylthulg>"
21 abortWith "Usage: qlzqqlzuup [-m] <filename.quylthulg>"
22
23 abortWith msg = do
24 hPutStrLn stderr msg
25 exitWith (ExitFailure 1)
00 #!/bin/sh
11
22 APPLIANCES="tests/appliances/qlzqqlzuup.md"
3 falderal $APPLIANCES tests/Quylthulg.markdown
3 falderal $APPLIANCES tests/Quylthulg.md
+0
-217
tests/Quylthulg.markdown less more
0 Test Suite for Quylthulg
1 ========================
2
3 This test suite is written in the format of Falderal 0.7. It is far from
4 exhaustive, but provides a basic sanity check that the language I've designed
5 here comes close to what I had in mind.
6
7 -> Tests for functionality "Interpret Quylthulg Program"
8
9 Integer expressions.
10 --------------------
11
12 | 5
13 = 5
14
15 | +6+9+
16 = 15
17
18 | +1+*7*-8-1-*+
19 = 50
20
21 String expressions.
22 -------------------
23
24 | ~$Hello, world!$
25 = ~$Hello, world!$
26
27 | &~$Shoes are $&&~~&~$4.99 a pair$&&
28 = ~"Shoes are $4.99 a pair"
29
30 List expressions.
31 -----------------
32
33 | [1,2,3]
34 = [1,2,3]
35
36 | [1,2|3]
37 = [1,2|3]
38
39 | <[1,2|3]<abort<
40 = 1
41
42 | <1<abort<
43 = abort
44
45 | >[1,2|3]>abort>
46 = [2|3]
47
48 | >1>null>
49 = null
50
51 | <,1,2,<null<
52 = 1
53
54 | >,1,2,>null>
55 = 2
56
57 | ,1,,2,3,,
58 = [1,2|3]
59
60 | ;[1,2];[3];
61 = [1,2,3]
62
63 | ;[1,2];3;
64 = [1,2|3]
65
66 | ;null;null;
67 = null
68
69 | ;[1];null;
70 = [1]
71
72 | ;null;[1];
73 = [1]
74
75 Labels and gotos.
76 -----------------
77
78 | :A:goto$A$
79 = :A:goto $A$
80
81 Foreach expressions.
82 --------------------
83
84 | foreach $n$=[7,2,3] with $a$=0 be +$a$+$n$+ else be abort
85 = 12
86
87 | foreach $n$=null with $a$=0 be +$a$+$n$+ else be abort
88 = abort
89
90 | foreach $n$=[1,2,3] with $a$=null be ,$n$,$a$, else be null
91 = [3,2,1]
92
93 This is how boolean expressions can be built with `foreach`es.
94 We take `null` to mean **false** and `[1]` to mean **true**.
95
96 Boolean NOT.
97
98 | foreach $n$=null with $a$=null be null else be [1]
99 = [1]
100
101 | foreach $n$=[1] with $a$=null be null else be [1]
102 = null
103
104 Boolean OR.
105
106 | foreach $n$=;[1];[1]; with $a$=[1] be $a$ else be null
107 = [1]
108
109 | foreach $n$=;null;[1]; with $a$=[1] be $a$ else be null
110 = [1]
111
112 | foreach $n$=;[1];null; with $a$=[1] be $a$ else be null
113 = [1]
114
115 | foreach $n$=;null;null; with $a$=[1] be $a$ else be null
116 = null
117
118 Boolean AND.
119
120 | foreach $n$=[1] with $a$=[1] be
121 | foreach $m$=$a$ with $b$=null be [1]
122 | else be null
123 | else be null
124 = [1]
125
126 | foreach $n$=null with $a$=[1] be
127 | foreach $m$=$a$ with $b$=null be [1]
128 | else be null
129 | else be null
130 = null
131
132 | foreach $n$=[1] with $a$=null be
133 | foreach $m$=$a$ with $b$=null be [1]
134 | else be null
135 | else be null
136 = null
137
138 | foreach $n$=null with $a$=null be
139 | foreach $m$=$a$ with $b$=null be [1]
140 | else be null
141 | else be null
142 = null
143
144 Some list-processing-type things that you often see in functional
145 programming.
146
147 Reverse a list.
148
149 | foreach $x$ = [10, 20, 40, 80]
150 | with $a$ = null be
151 | ,$x$,$a$,
152 | else be
153 | null
154 = [80,40,20,10]
155
156 Find the length and the sum of a list of integers.
157
158 | foreach $x$ = [10, 20, 40]
159 | with $a$ = ,0,0, be
160 | ,+<$a$<0<+1+,+>$a$>0>+$x$+,
161 | else be
162 | null
163 = [3|70]
164
165 Take the first 3 elements from a list (in reverse order.)
166
167 | foreach $x$ = [10, 20, 40, 80, 60, 10, 30]
168 | with $a$ = ,null,[1,1,1,1], be
169 | foreach $n$=>>$a$>null>>null>
170 | with $r$=99999 be
171 | ,,$x$,<$a$<null<,,>>$a$>null>>null>,
172 | else be
173 | abort
174 | else be
175 | null
176 = [[40,20,10],1]
177
178 Take the first 5 elements from a cyclic list.
179
180 | foreach $x$ = :L:[10, 20, goto $L$]
181 | with $a$ = ,null,[1,1,1,1,1,1], be
182 | foreach $n$=>>$a$>null>>null>
183 | with $r$=99999 be
184 | ,,$x$,<$a$<null<,,>>$a$>null>>null>,
185 | else be
186 | abort
187 | else be
188 | null
189 = [[10,20,10,20,10],1]
190
191 Macros.
192 -------
193
194 | {*[Five][5]}{Five}
195 = 5
196
197 | {*[(A][1]}+{(A}+4+
198 = 5
199
200 | {*[SQR][*{X}*{X}*]}{*[X][5]}{SQR}
201 = 25
202
203 | {*[}][This is my comment!]}~${}}$
204 = ~$This is my comment!$
205
206 | {*[Dave][3]}{*[Emily][4]}$Number of Macros Defined$
207 = 2
208
209 | &~${$&~$*[S][T]}$&
210 = ~${*[S][T]}$
211
212 | &~${$&~$S}$&
213 = ~${S}$
214
215 | %&~${$&~$*[S][T]}$&%&~${$&~$S}$&%
216 = ~$T$
0 Test Suite for Quylthulg
1 ========================
2
3 This test suite is written in the format of Falderal 0.7. It is far from
4 exhaustive, but provides a basic sanity check that the language I've designed
5 here comes close to what I had in mind.
6
7 -> Tests for functionality "Interpret Quylthulg Program"
8
9 Integer expressions.
10 --------------------
11
12 | 5
13 = 5
14
15 | +6+9+
16 = 15
17
18 | +1+*7*-8-1-*+
19 = 50
20
21 String expressions.
22 -------------------
23
24 | ~$Hello, world!$
25 = ~$Hello, world!$
26
27 | &~$Shoes are $&&~~&~$4.99 a pair$&&
28 = ~"Shoes are $4.99 a pair"
29
30 List expressions.
31 -----------------
32
33 | [1,2,3]
34 = [1,2,3]
35
36 | [1,2|3]
37 = [1,2|3]
38
39 | <[1,2|3]<abort<
40 = 1
41
42 | <1<abort<
43 = abort
44
45 | >[1,2|3]>abort>
46 = [2|3]
47
48 | >1>null>
49 = null
50
51 | <,1,2,<null<
52 = 1
53
54 | >,1,2,>null>
55 = 2
56
57 | ,1,,2,3,,
58 = [1,2|3]
59
60 | ;[1,2];[3];
61 = [1,2,3]
62
63 | ;[1,2];3;
64 = [1,2|3]
65
66 | ;null;null;
67 = null
68
69 | ;[1];null;
70 = [1]
71
72 | ;null;[1];
73 = [1]
74
75 Labels and gotos.
76 -----------------
77
78 | :A:goto$A$
79 = :A:goto $A$
80
81 Foreach expressions.
82 --------------------
83
84 | foreach $n$=[7,2,3] with $a$=0 be +$a$+$n$+ else be abort
85 = 12
86
87 | foreach $n$=null with $a$=0 be +$a$+$n$+ else be abort
88 = abort
89
90 | foreach $n$=[1,2,3] with $a$=null be ,$n$,$a$, else be null
91 = [3,2,1]
92
93 This is how boolean expressions can be built with `foreach`es.
94 We take `null` to mean **false** and `[1]` to mean **true**.
95
96 Boolean NOT.
97
98 | foreach $n$=null with $a$=null be null else be [1]
99 = [1]
100
101 | foreach $n$=[1] with $a$=null be null else be [1]
102 = null
103
104 Boolean OR.
105
106 | foreach $n$=;[1];[1]; with $a$=[1] be $a$ else be null
107 = [1]
108
109 | foreach $n$=;null;[1]; with $a$=[1] be $a$ else be null
110 = [1]
111
112 | foreach $n$=;[1];null; with $a$=[1] be $a$ else be null
113 = [1]
114
115 | foreach $n$=;null;null; with $a$=[1] be $a$ else be null
116 = null
117
118 Boolean AND.
119
120 | foreach $n$=[1] with $a$=[1] be
121 | foreach $m$=$a$ with $b$=null be [1]
122 | else be null
123 | else be null
124 = [1]
125
126 | foreach $n$=null with $a$=[1] be
127 | foreach $m$=$a$ with $b$=null be [1]
128 | else be null
129 | else be null
130 = null
131
132 | foreach $n$=[1] with $a$=null be
133 | foreach $m$=$a$ with $b$=null be [1]
134 | else be null
135 | else be null
136 = null
137
138 | foreach $n$=null with $a$=null be
139 | foreach $m$=$a$ with $b$=null be [1]
140 | else be null
141 | else be null
142 = null
143
144 Some list-processing-type things that you often see in functional
145 programming.
146
147 Reverse a list.
148
149 | foreach $x$ = [10, 20, 40, 80]
150 | with $a$ = null be
151 | ,$x$,$a$,
152 | else be
153 | null
154 = [80,40,20,10]
155
156 Find the length and the sum of a list of integers.
157
158 | foreach $x$ = [10, 20, 40]
159 | with $a$ = ,0,0, be
160 | ,+<$a$<0<+1+,+>$a$>0>+$x$+,
161 | else be
162 | null
163 = [3|70]
164
165 Take the first 3 elements from a list (in reverse order.)
166
167 | foreach $x$ = [10, 20, 40, 80, 60, 10, 30]
168 | with $a$ = ,null,[1,1,1,1], be
169 | foreach $n$=>>$a$>null>>null>
170 | with $r$=99999 be
171 | ,,$x$,<$a$<null<,,>>$a$>null>>null>,
172 | else be
173 | abort
174 | else be
175 | null
176 = [[40,20,10],1]
177
178 Take the first 5 elements from a cyclic list.
179
180 | foreach $x$ = :L:[10, 20, goto $L$]
181 | with $a$ = ,null,[1,1,1,1,1,1], be
182 | foreach $n$=>>$a$>null>>null>
183 | with $r$=99999 be
184 | ,,$x$,<$a$<null<,,>>$a$>null>>null>,
185 | else be
186 | abort
187 | else be
188 | null
189 = [[10,20,10,20,10],1]
190
191 Macros.
192 -------
193
194 | {*[Five][5]}{Five}
195 = 5
196
197 | {*[(A][1]}+{(A}+4+
198 = 5
199
200 | {*[SQR][*{X}*{X}*]}{*[X][5]}{SQR}
201 = 25
202
203 | {*[}][This is my comment!]}~${}}$
204 = ~$This is my comment!$
205
206 | {*[Dave][3]}{*[Emily][4]}$Number of Macros Defined$
207 = 2
208
209 | &~${$&~$*[S][T]}$&
210 = ~${*[S][T]}$
211
212 | &~${$&~$S}$&
213 = ~${S}$
214
215 | %&~${$&~$*[S][T]}$&%&~${$&~$S}$&%
216 = ~$T$