Poplar Language ManualJim MorrisEric SchmidtNovember 1, 1978(Revised: December 1980, version 0.3)Poplar is an experimental language for text manipulation. We hope to apply it to a variety of taskscommonly found in office environments. Ultimately, we hope to develop a language suitable for useby Xerox customers, but the present language will be too difficult for a non-programmer toassimilate. Its goal is simply to explore the range of functionality such a language might have. It isbased on ideas from LISP, SNOBOL, APL and the UNIX operating system. Certain of yourfavorite features have been left out or given strange implementations in order to encourageexploration of different programming styles. Read this, try the implementation, and give us somefeedback. Example programs, successful or not, will be greatly appreciated.The implementation is more of a sketch than a finished picture: it represents three months effort byone and one-half of us, so it has not been possible to provide all the things one might think of oreliminate all the bugs one might find. This manual is composed of several sections:ExpressionsStrings and ListsFunction ApplicationConditional ExpressionsIteration over ListsVariables, Assignment, and SequencingProgrammer-defined FunctionsPatterns and MatchingMatching Combined with EvaluationThe Matching ProcessGeneral Iteration and RecursionEquality AssertionsFile, Display, and Keyboard functionsThe Poplar ExecutiveIt has some appendices:A: ExamplesB: Primitive Functions^p'!Z qX &W $U!SSrF% Oq[ Mr'; K>C I Z FP D'4 Bl,5 @7L <\R :'W 7( 4,1 .,*r(=& %#!k!7%e   M >QU*Poplar Language Manual 2C: Syntax Equations for PoplarD: Getting StartedSeveral people have made very helpful suggestions to improve this document and the language:Doug Clark, Gene McDaniel, Paul McJones, Tom Moran, Alan Perlis, Dana Scott.ExpressionsPoplar is an expression-oriented language (rather than statement-oriented or command-oriented).Poplar programs consist of expressions. The implementation is an evaluator which reduces anexpression to a simple form, called its value. Throughout this manual we shall write things like1+2 = 3which suggests that the evaluator will transform 1+2 into 3.In general, an expression is a constant like 2 or "abc", a variable like x or a compound expressionconsisting of one or two sub-expressions and an operator, like +. An operator may be binary, inwhich case it separates two subexpressions; it may be unary prefix, in which case it precedes a singlesubexpression; it may be unary postfix, in which case it follows a single subexpression.Subexpressions are often enclosed in parentheses (), brackets [] or braces {}. For example[(((~"abc") !), (1 + 2)]is an expression composed of many nested subexpressions. Often, parentheses can be omitted. Theabove expression is the same as[(~"abc")!, 1 + 2]The implicit parenthesization rules are based on the concept of precedence. We say that an operator,!, has higher precedence than another one, +, if it is performed first on an operand placed betweenthem, i.e.x+y! = x+(y!)In general, unary postfix operators have the highest precedence, followed by unary prefix, thenbinary operators. If two adjacent operators have equal precedence the one on the left is performedfirst. Thusx+~y!+y=(x+(~(y!)))+y!@fsiG_q\ Y? VL P4t LXq u qH J#,uq G(uqDv @7q1vqvq <\uqvqvquqvq :'0uquq 7+ u q$ 52u q2 3vq vq vq /v +qa )%v !q#u q 03 }  R 12 ]   :?QZPoplar Language Manual 3There are exceptions to these rules. They will be noted when the effected operators are introduced.A complete set of rules for expression formation is given in Appendix C.Strings and ListsThere are three types of values in Poplar: Strings, Lists, and Functions. Functions may be primitive(built-in), programmer-defined, or patterns. There is also a special value fail. Any sequence of characters enclosed in quotes is a string. For example,"I am a string"""are two strings. The second is called the empty string.Numbers are also strings, but need not be quoted; e.g. 123 = "123".Special, two-character combinations can be used inside strings to represent characters which areinconvenient or impossible to type:^" is a quote mark^ is a space (There is a space after that "^")^^ is just ^In general for any upper-case letter X from A-Z, ^X is the ASCII character control-X. In particular,^M is a RETURN^I is a TAB^Z is control-ZFinally, ^nnn where nnn is precisely three digits is considered a single character with that octalASCII code.A list is a sequence of things denoted using brackets and commas. For example,["abc", "xyz"][16][]are lists, the last being the empty list. Lists can be components of lists, e.g.["roster", ["jim", "417 Smith St.", "555-7821"], ["fred", "625 B St.", "555-9021"]]!@fsiG _qT \H VDt RhqSu P4q uquq!vq LX3uqH|vFH Blq+u q >7v q :6* 8#4vq2pvq*vq0;vqv ,_q%vqvqvq2(vqw&Ovqw$vq ?vq>   /uqISv  qQ 3vA0 ?Q^Poplar Language Manual 4is a list of three items, two of which are lists of three items. Other kinds of values discussed later(functions, patterns) can also be list elements.Considered as an operator, a comma, has the lowest possible precedence, so it is never necessary toenclose a list element in parentheses.Function ApplicationThe operator / (application) means apply the function that follows it to the preceding value.There are many primitive functions. For example, the function length may be applied to strings orlists to produce the number of characters in the string or items in the list."abc"/length = 3""/length = 0["abc", "c"]/length = 2[]/length = 0Functions with two or more inputs take them in a list.The function conc will combine a list of strings into one.["abc", "def"]/conc = "abcdef"[123, 678]/conc = 123678["abc", ""]/conc = "abc"The functions plus, minus, times, and divide may be applied to pairs of numbers.[1,3]/plus = 4[1,"a"]/plus is an error[4,6]/minus = -2[3, -8]/times = -24[7, 3]/divide = [2, 1]The value of a divide function application is a quotient and remainder.Since they are used so frequently, there are shorter notations for conc, plus and minus.Concatenation is designated simply by juxtaposition."abc" "def" = "abcdef"Plus and minus are designated by + and -.!@fsiG _qN \0 Y+8 V& Rt Nq vqu q- J#vq HMDvB @~>J :nq6 6 vuq(2v0.M *rq vqvqvqvq$&v $a q "-v qvq2  4vqvqvq 4v qvqvqvq ?Q\2Poplar Language Manual 5123+4 = 1275-10 = -5The various components of a list may be designated by applying integers to the list, as if the integerwere a function. The numbering starts with 1.["ab", "c", "d"]/1 = "ab"["ab", "c", "d"]/3 = "d"["ab", "c", "d"]/0 is an error["ab", "c", "d"]/4 is an errorApplying a negative number to a list results in a list shortened by removing that number of elementsfrom the beginning.["ab", "c", "d"]/-1 = ["c", "d"]["ab", "c", "d"]/-3 = []["ab", "c", "d"]/-4 is an errorTwo lists may be concatenated by placing two commas between them.["abc", "def"] ,, [123, 456] = ["abc", "def", 123, 456][123, 456] ,, [0] = [123, 456, 0]["a", "b"] ,, [] = ["a", "b"]The expression x--y will generate a list of numbers starting with x and ending with y.1--7 = [1, 2, 3, 4, 5, 6, 7]3--3 = [3]4--2 = [4, 3, 2]The function sort rearranges a list in ascending alphabetical order.["beta", "zero", "alpha"]/sort = ["alpha", "beta", "zero"]If an element of the list is itself a list, sort assumes the first component of the list is a string anduses that string in deciding where the list goes.[["fred", 20], "al", ["jane", 3]]/sort = ["al", ["fred", 20], ["jane", 3]]There is a complete description of Poplar primitive functions in Appendix B.!@fsiG_v \ Yq24 V-RvPNq LXvq H|X FHBlv@7>q :'A6Kv74!1 .qvq/vqvq*+v' % !q vq3 v: /qvq8 1vK CqL >QXPoplar Language Manual 6Conditional ExpressionsCertain primitive functions islist, isnull, and isstring, return the special value fail if their input isnot as they describe it and return the input otherwise.[2, 3]/islist = [2, 3]"2,3"/islist = fail[]/isnull = [][3, 4]/isnull = fail"a"/isstring = "a"[5]/isstring = failThe operation of matching, described fully below, can also return fail. This simplest case ofmatching is a test for string equality written as string1/{string2}."abc"/{"abc"} = "abc""abc"/{"a"} = fail The value fail may be used to select between different values. The relevant operators for doing thisare | and >.The operator | (otherwise) has the following behavior.V | F = V if V is not fail (F is not evaluated at all.)fail | F = FThusx/isstring | "x is not a string"will be x if x is a string, but will be "x is not a string" otherwise. Operationally, E | F means:Evaluate E; if the value, V, is not fail, forget about F and take V value of the entire expression.Otherwise, evaluate F and take its value (fail or not) as the value of the whole expression. Theotherwise operator has a lower precedence than most other operators so thatx/y | t/u = (x/y) | (t/u) The operator > (then) has the following behaviorfail > F = fail(F is not evaluated at all.)V > F = Fif V is not fail!@fsiG ^t Zqvuvuquvuq vq X7TvRPz NFLI Fquq)vq C2vq?v= 9q vq(0 7fvqvq 3 vquq/vqvqvqvq-zv )q%v! !qvqvqvqvq vqvqvqvq vq }vq vq3 IKmv q vquqv$qvq v$qvqv& :>QZPoplar Language Manual 7Thusx/{"abc"} > "xyz" | "def"will be "xyz" if x is "abc", but will be "def" otherwise. Operationally, E>F means: Evaluate E; ifthe value is not fail, forget the value of E and evaluate F for the value of the whole expression. Ifthe value of E is fail return fail as the value of the whole expression. The then operator has a lowerprecedence than most other operators (save |), so thatx>y | t/v > l/k = (x>y) | ((t/v) > (l/k)) The expressionP > E | Fis almost, but not quite, equivalent to the Algol if P then E else F. It differs when E=fail.The not operator ~ maps fail into the empty string and everything else into fail~ fail = ""~ "" = fail~ "abc" = failIteration on ListsAll the binary string operations may be applied to lists. If one of the operands is not a list then it iscombined with every element of the other list.4 + [-2, 3, 8] = [2, 7, 12]"foo." ["bcd", "mesa"] = ["foo.bcd", "foo.mesa"]"" ["form", "eval", "comp"] ".mesa" = ["form.mesa", "eval.mesa", "comp.mesa"]If both operands are lists then they must be the same length and the operation is applied element byelement. ["abc", "def"] ["xyz", "123"] = ["abcxyz", "def123"][5, 6] + [7, 8] = [12, 14][5, 6] + [7, 8, 14] is an error!@fsiG _q[:v W^qvqvqvq vqvqvq U*vq vq vq+ R vqvqvqB P6Lv* I q E-v ARqxqvqxqvqxqvqvq =vuq vqvq0v9 7f 51 .t *q91 (.$v!07)D 'qN v4 gq  >Q[Poplar Language Manual 8If a list follows an application operator, the result is the same as applying each element of the list tothe preceding value and forming a list of the results.[12, 7]/[length, conc, plus] = [2, 127, 19]["a", "b", "c"]/[2, 1] = ["b", "a"][10, 20, 30, 40, 50, 60]/(2--5) = [20, 30, 40, 50]The operator // (maplist) will apply the following function to every member of the preceding listand create a new list of the results.["a", "bcd", ""]//length = [1, 3, 0][[3,4], [6,9], [-4,7]]//times = [12, 54, -28][["a","b"], ["c", "d"], ["x", "Y"]]//2 = ["b", "d", "Y"][]//f = [] for any fIf the value of an application is fail it is omitted from the result list.["a", ["x"], "b", ["t", "c"]]//isstring = ["a", "b"] It is often useful to process all the items in a list while accumulating some information. This can beaccomplished using the operator /// (gobble).[x1, ... , xn] /// f.applies f to pairs of items. It starts with x1 and x2 to produce y1; then it combines y1 with x3 andso on.[1, 4, 9, 20]///plus = 1+4+9+20 = 34[2, 4, 8]///minus = 2-4-8 = -10["The ", "quick ", "brown ", "fox "]///conc = "The quick brown fox " More generally, [x]///f = x[x1, x2, x3, x4, ...] /// f = [[x1, x2]/f, x3, x4, ...]///f[]///f is an error!@fsiG _qa \6Yv+V#T2 Pq vququqG N%Jv$H|-FH8D qv @7q"vq$<\v5 8q.8 6Kuvququ2pv .qvqvqvq vqvqvq ,_(v$&O$+ ?qcv /;q  >QTzPoplar Language Manual 9Variables, Assignment, and SequencingA variable is either a single letter or a sequence of letters including at least one capital letter. Thusvariables can always be distinguished from special Poplar names, like conc. One can assign valuesto variables with the assignment operator _.x _ "A long string I would rather not type repeatedly"BlankLine _"^M^M"Subsequently evaluated expressions containing the variable will use the value in place of thevariable. The value of x _ e is e. x BlankLine x ="A long string I would rather not type repeatedlyA long string I would rather not type repeatedly"Expressions may be evaluated solely for their side effects; in which case the are called statements.When this the case it is desirable to combine them into sequences and ignore the values theyproduce. The semicolon is used to separate such items.(x _ 1; y _ 3; x+y) = 4Thus the value of such an expression is the value of the last sub-expression.The semicolon and _ have precedence lower than |.x _ y _ a | b; z _ a-y = (x _ (y _ (a | b))); (z _ (a-y))Programmer-defined functionsA function can be described by writing a variable followed by a colon followed by any expressioninvolving the variable. The expression following the colon is called the body of the function. x: x "O" xThe effect of applying a such a function to a value is to substitute the value for the correspondingnames."W" / x: x "O" x!@fsiG ^t% ZquqF XFvuq V*vqRv6Pz LqV JjvqvqFvB1>J1 :nqXu q 89D 672)v .MqM *r1&v9 t qE Juq v qE  v y?Q]Poplar Language Manual 10yields"W" "O" "W"which eventually yields"WOW"A list of variables may appear before the colon. In that case the function must be applied to a listof values with the same length. Each value is substituted for the corresponding variable.It is often convenient (or perhaps only amusing) to use an in-line function to name values, ratherthan an assignment statement. For example, the previous sequencex _ "A long string I would rather not type repeatedly";BlankLine _"^M^M";x BlankLine xcould be re-written"A long string I would rather not type repeatedly" / x:"^M^M" / BlankLine:x BlankLine xThe operators // and /// may be used with programmer-defined functions["a", "bc", "ttt"] // (x: x "@" x) = ["a@a", "bc@bc", "ttt@ttt"][[1, 2], [3, 8], [5, 2]] // ([x, y]: [x+y, x-y]/times) = [-3, -55, 21]["a", "b", "c", "d]///([x, y]: y x) = "dcba"["a"]/([x,y]: x y y) is an error because the length of the lists differ. A function may be assigned to a variable and then that variable may be referenced like a primitivefunction.F _ (x: x x x); "a"/F = "aaa"(x: x x x)/F: "a"/F = "aaa"The symbol : considered as an operator has unique precedence properties: It has the highestprecedence of all when viewed from the left, and the lowest precedence of all when viewed from the!@fsiF _q[:v W^qSv Oq14 MrZ IN GbACv7AR? ;Aq7fv7512 /!q vqvq.+EvA'iF#,q3v q,6 v q&5 ^ >R\xPoplar Language Manual 11right. This is so the variables introduced on its left have a scope limited only by closing parentheses.a+b/x: t _ x/conc; x+1 = (a+b)/(x: (t _ x/conc; x+1))Successor _ x: x+1; Predecessor _ x: x-1;is, surprisingly, the same asSuccessor _ (x: x+1; Predecessor _ (x: x-1));Thus one will usually enclose programmer defined functions by parentheses.Patterns and MatchingPatterns are functions used to analyze strings. In general, a pattern is denoted by any expressionenclosed in braces {}. Applying a pattern to a string is called matching. The result is equal to thestring if the match succeeds; otherwise it is equal to fail. Any string can become a pattern. The match succeeds if the strings are equal. Upper- and lower-case characters are always different."abc"/{"abc"} = "abc""abc"/{"aBc"} = failPatterns may be combined with the operator | to form a new pattern which matches either the firstor second component."ab"/ {"ab"|"c"} = "ab""cd"/ {"a"|"cd"} = "cd""cd"/ {"a"|"b"|"d"} = failIt is permissible, but not required, to put braces around sub-patterns in patterns, e.g.{{"a"|{"b"}}|"d"}is a legal pattern.Patterns may be concatenated to form a new pattern that matches the concatenation of any stringsthat match the individual patterns."ad"/ {("a"|"c") ("b" | "d")} = "ad""xcd"/ {"x" ("a"|"cd")} = "xcd"!@fsiF _quqL[:v7V) RqOv- K>qJ Dt @q/4 >vquq <\7vq 8` 6K%2pv0; ,_qR *+&Ov$!  qX/v Sq w7) C# gv$ 3@ >Q^Poplar Language Manual 12The patternP!matches an arbitrarily long sequence of one or more P's. For example,"aaa" / {"a"!} = "aaa"The pattern P?matches an optional P; if the match succeeds, fine; if not, fine too."abc"/ {"a" "b"? "c"} = "abc""ac"/ {"a" "b"? "c"} = "ac"The idiom P!? can be used to indicate zero or more repetitions of P.The pattern # (wild card) matches any single character."abc"/{"a" # "c"} = "abc"The pattern ... (ellipsis) matches any sequence of zero or more characters whatsoever. The matcherendeavors to make the substring that it matches as short as possible, subject to the item followingthe ... matching successfully. A ... at the end of a pattern matches everything to the end of thestring."abc" / {... "c"} = "abc""abc,def,ghi,bbb," / {(... ",")!} = "abc,def,ghi,bbb,""abcxyzsss" / {... "xyz" ...} = "abcxyzsss"16/{"-"...} = fail-16/{"-"...} = -16The operator ~ may occur in patterns. As before, it changes fail into the empty string and anythingelse into fail."abc" / {~"abc"} = fail"abc" / {~"x"} = fail"abc" / {~"x" "abc"} = "abc"The idiom {~P ...} matches anything which does not begin with a P.!@fsiF _q [:v W^q4vqSv Mrq Iv Eqvq0Av? ;q vq5vq 7 vquq4v 0;q vququqG .Y +vqvq 2 )%v#6!Y+% q vq/vq  vqv q vq.vql y>Q]Poplar Language Manual 13The following are some useful, pre-defined patterns:digit = {0|1|2|3|4|5|6|7|8|9}integer = {"-"? digit!}number = {"-"? ("." digit! | (digit! ("." digit!?)?))}smallletter = {"a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" |"n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"}bigletter = {"A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"| "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"}letter = {smallletter | bigletter}word = {letter!}item = {word | number}thing = {(letter|digit)!}space = {" " | "^I"} (blank or tab)Two other patterns can be modified by a numberblanks 5 = "^ ^ ^ ^ ^ "len 3 = ### Matching Combined with EvaluationIt is usually desirable to extract more information from the matching process. This can beaccomplished by adding structure to patterns with the normal set of operations available for strings,lists, and functions. The strings that match individual components of a pattern are then recombinedunder control of those operations.For example, the expression"How many times"/{ [word, " " word, " " word] }evaluates to become["How", " many", " times"]Operationally, the string was broken into five pieces by the pattern: "How", " ", "many", " ", and"times". Then the concatenation of the spaces onto "many" and "times" was performed, and thenthe three pieces were made into a list.The deletion operator * when suffixed to an expression forces it to evaluate to be the empty stringunless it is fail. It is useful for discarding portions of a matched string.!@fsiF _q4[:vYV8T<Rh1P4<M=K"IGbE-Br ?q.;Av9 2t! .qO ,E *rJ (=" $a v/ qv q-vq vq-vqvq ' uq vqE y vq<R 2?Q]Poplar Language Manual 14"How many times"/{[word " "* word*, " "* word)]} = ["How", "times"]"56,89"/ {number ","* + number} = 145The patternP,!with a comma just before the ! behaves just like P! except that the individual items that match P arecombined into a list rather than being re-concatenated into a string."aaa"/ {"a",!} = ["a", "a", "a"]"The quick brown fox" / {(word " "?*),!} = ["The", "quick", "brown", "fox"]The application operators (/, //, ///, %) and > are also permitted in patterns, but are treated unlikethe other binary operators in that their right operands do not participate in the match, but arecombined, as is, with whatever matches the left operand.The conditional operator > can be used to replace a (non-fail) value with something else."abc"/{...("b">"x")...}= "axc"Month _ {"Jan" > 1 | "Feb" > 2 | "Mar" > 3 | "Apr" > 4 | "May" > 5 | "Jun" >6 | "Jul" > 7 | "Aug" > 8 | "Sep" > 9 | "Oct" > 10 | "Nov" > 11 | "Dec" > 12}"Apr"/Month = 4When an application operator appears inside a pattern the function that follows it is applied towhatever matches the subpattern before it."abc-def-hijk-n-"/{(word "-"* / length),!} = [3, 3, 4, 1]Operationally, this could have happened in two stages. First the matching process yields[("abc" "-"*/length), ("def" "-"* /length), ("hijk" "-"* /length), ("n" "-"*/length)]Then the evaluation process throws away the "-"'s and computes the lengths."abcd" / {("ab" / x: x x x) ...} = "abababcd""23-Jan-78" / {[integer, "-"* word, "-"* integer] / [d, m, y] : m " " d ", 19" y}= "Jan 23, 1978"!@fsiF_v0[:% W^q Sv Oqvq vq,vq MrEIvGb A ARqv q> ?>" <8 9 vqvq51v0qvqvqvqvqvqvqvqvqvqv.qvqvqvqvqvqvqvqv qvqv qvqv *+ &OqU $* ?v9 cqYv@ q,vqv-1 g. 3 >Q^Poplar Language Manual 15Using the pattern Month from above,"23-Jan-78" / {[integer, "-"* Month, "-"* integer] / [d, m, y] : m "/" d "/" y}= "1/23/78"The idiom {...(P > S)...} means replace the first occurrence of P with S. (That is: the value of thematch will be a new string derived from the old by replacing P with S).The idiom {(...(P > S))!...} means replace all occurrences of P with S.The Matching ProcessIn simple situations the matcher usually does the expected thing. Occasionally, however, it willsurprise you by failing to match something you thought it should. That is because the matcherfollows a rather simple, left-to-right, matching rule and doesn't usually back up in the string it istrying to match. Specifically, given a pattern likes/{P1 P2}it finds a prefix of s which matches P1, then tries to match P2 against the remainder of the string.If P2 fails to match the remainder the entire match fails. There might be a different way to matchP1 against s that consumes more or fewer characters so that P2 would match the remainder.Nevertheless, the matcher does not bother trying new ways to match P1 (unless P1 is an ellipsis; seebelow.). For example,"abc" / {("a" | "ab") "c"} = failbecause the first alternative, "a", was chosen to match the "a" in the subject string, and the matcherdid not back up to try the "ab" alternative when "c" fails to match "b". On the other hand"abc" / {("ab" | "a") "c"} = "abc"This suggests that if one alternative is a prefix of another you should put the longer one first.Another example: the matcher finds the longest sequences it can so"aaabc" / {"a"! "abc"} = failbecause the third "a" was used up by the "a"!.!@fsiF _qvq [:v2Y+V Rqvq'vqvq P=vqvq L vq"vqvq FHt Blquq; @79uq >e ;uq"7v 4qvqvqvq% 1vq6( /vqvqvquq -zCvqvq +Eu 'iq #v! qvqvq }vqvq vqv" q<% Bv 3qvqvq ?Q^Poplar Language Manual 16The only situation in which the matcher backs up involves the ellipsis pattern. If, in {P1 P2}, P1 isan ellipsis or ends with an ellipsis the matcher begins by assuming the ellipsis matches the emptystring and extends the ellipsis match, one character at a time, until P2 matches the remainder of thestring. Thus the ellipsis pattern ... is quite different from the apparently similar pattern #!?. Thesecond one is fairly useless (except for signifying expletives) since it uses up the entire string it isapplied to."aaaab"/{... "b"} = "aaaab""aaaab"/{#!? "b"} = failThe use of ellipsis can be surprisingly expensive occasionally. For example,"abcd def wddf: x"/{... (word ":") ...}will cause the pattern word to match seven different substrings ("abcd", "bcd", "cd", "d", "def","ef", "f") before coming to rest on "wddf". General Iteration and RecursionIf you want to do something repeatedly and it doesn't correspond to marching down a list you canuse the operator %.E % f applies f to E repeatedly, calling the result the new E, until E is fail, then returns the previous valuefor E. -10 % (x: x+4/{"-" ...}) = -6 % (x: x+4/{"-" ...})= -2 % (x: x+4/{"-" ...})= -2In general,E % f = E/f > E/f % f | EYou can write recursive functions, if you like.Blanks _ (n: n/{0} > "" | "^ " (n-1/Blanks))generates a string of n blanks.!@fsiF _qTvqvq \O Z7vq Xx$vq5vq VD(@ T P4vM J#qMFHv( Blqvq$v @7qvqv 9t 5q5+ 3vq/v +qvqvqvqvqvq! )vq %v?$!$  /q Sv wq/v, qX y>Q]Poplar Language Manual 17You can also write recursive patterns.AE _ {integer | "(" AE ("+" | "-") AE ")" }matches strings like "(5-(6+2))".AE suggests a fairly succinct evaluator for fully parenthesized arithmetic expressionsEval _ {integer | "("* Eval "+"* + Eval ")"* | "("* Eval "-"* - Eval ")"*};"(5-(6+2))"/Eval = -3Equality AssertionsEquality assertions are intended to be an aid to program development, documentation, andmaintenance. They provide a means of interleaving an example with a program. An assertion is aphrase of the form= Ewhere E is any expression (in practice, a constant). Any programmer defined function may bedecorated with equality assertions. One uses premise assertions after the input variables andconclusion assertions in the body of the function to describe the value of intermediate results.Consider the function([x, y]: [x,y]/marry//times///plus)We can add assertions to it to produce the following, equivalent program([x,y] := [[1,4,8], [2,-9,3]]; [x,y]/marry = [[1,2],[4,-9],[8,3]]//times///plus = -9)This says: If x happens to be [1,4,8] and y happens to be [2,-9,3] then the value of [x,y]/marry is[[1,2],[4,-9],[8,3]] and the final value is -9. In general, one may add a conclusion assertion to any expression, as long as it occurs inside afunction which has premise assertions for its variables.!@fsiF _q&[:v+ W^qv q SvqTOvMr(K>'Gb ?t ;Aq8 9 M 62v /!qvq.' ,# uq *uq ? &#v# %qHIvA"9 1q vqvqvqvq v q vqvq A 8P y>Q]Poplar Language Manual 18Normally, these assertions are regarded as comments, but one can have the evaluator check them,too. Given a function with premise assertions, it substitutes the values for the variables andevaluates the body checking that each conclusion assertion is true.When a function occurs within a function, things are a little more complicated. The problem is thateach conclusion assertion should be checked only once, even if the inner function is used repeatedly.Consider the following function(x:=["abc", "z"]; x // (y: [y/length, y])//sort//2 = ["z", "abc"])If we want to attach an assertion to the result of the inner function, which should we use: = [3,"abc"] or = [1, "z"]? The answer is "neither"; we invent an independent premise assertion for theinner function.(x:=["abc", "z"]; x // (y="gh": [(y/length), y] = [2, "gh"])//sort//2 = ["z", "abc"])The checking evaluation proceeds as follows:1. Start the check of the outer function: Substitute the premise value for x.2. Start the check of the inner function: Substitute the premise value for y, and check theresult of the inner function. The inner function is now checked.3. Apply the inner function to "abc" and "z".4. Sort the list, discard the lengths and check the final result.It might be helpful to a reader to choose the examples for inner functions to correspond to aparticular case based upon the outer function; e.g. use "ab" rather than "gh" in the above program. File, Display, and Keyboard FunctionsThe expression"com.cm"/fileevaluates to a string which is the contents of the file name com.cm. If the file does not exist thevalue is fail.The function write can be used to write a string onto a file."Hello there.^M" / write "comment.cm"!@fsiF _q'8 \/0 ZC W); Up05 S<O`v)M, J#q6'v Gqv q3 EBv<? ;q,7Kvq5@ vq3@1Uvqvq/!A +EJ )3vq vq %5 !t% 7q [v q X Kvq o uvq+ v% L>Q\Poplar Language Manual 19stores the string on the file. It is not possible to write on a file that has been read previously in thesame Poplar session.The function listout can be used to store any value on a file.["a", "b"] / listout "f.pl"stores ["a", "b"] on the file, including brackets and quote marks.The expression"f.pl"/listinreads in the file f.pl and evaluates it as a Poplar expression. The file should have been created withthe listout function.The function print allows one to display a string."HI." / printDisplays HI. on the screen. The value is the input string.The function key evaluates to a string which is the sequence of characters typed on the keyboard upto a RETURN. It prompts with its input string. Thus"Type something, turkey!"/ key / printechoes a line. Typing DEL to key will cause it to return fail.The function dir produces a list of the file names currently in the system's directory. It ignores itsinput.The function exec may be used to cause a command to be executed by the resident operatingsystem command processor."ftp ivy st/c *.mesa" / execcauses the command to be executed. Control should eventually return to the Poplar evaluator.The Poplar ExecutiveThe executive executes commands or evaluates expressions and prints their values. Input lines are!@fsiF _q)A \ Y uvq*U*v QNqv q1 Mr Iv Eqf Cvq ? vq;v 7qvq/ 4 vq= 1wq*.v& *+qwqvqvq &O vq< $ ? vq"&  /v  qH ot qC L>Q\Poplar Language Manual 20terminated with RETURN, M; if you wish to include a RETURN in the input line, precede it with aCTRL-V. For example,"abc"Mis a valid (though trivial) program. Its value, "abc", will be printed. Common editing characterswork during type-in. Backspace erases the previous character, and DEL cancels the input. HittingESC at the beginning of a line repeats the previous line typed; you can use backspace to change it.Hitting ESC followed by RETURN will repeat the previous command.Most binary operators can omit their first operand and they will use the last value printed which weshall call the current value. For example1Mprints the value "1". Then+ 2Mprints "3".Often, the previous value is wanted.unMthrows away the current value and replaces it with the previous one. Only one value is saved. In theexample above, the "1" would be displayed again. The effects of assignments or file writes are notundone. The current value may be designated by @. For example,Wind _ @Mwill assign the displayed value to Wind.After a certain number of lines of the current value are printed the message "... more ..." is typedat the bottom. If you want to see more typemoreMand then type y' when subsequently prompted with "More?". If you type &' to the More?question, it will print the entire string with no more pauses.!@fsiF _qwqyqwq% \wqYvy U*q2vq, RCwq PwqD Nwq wq" JO H|u q Dvy @qvq@ :?QZPoplar Language Manual 21As you proceed, the cursor, which is in the shape of a square, will fill up to indicate how muchmemory space has been consumed. When it is mostly black, there will be a slight pause as thesystem "garbage collects" space not used any more. A smaller area on the left edge of the cursorindicates paging activity. A small mark moves each time the contents of a page buffer is changed.If you've had enough typequitMOften, Poplar programs will be prepared using Bravo. The approved extension for such files is ".pl".Typing$MyProgramMwill read in the filename and run it. It is shorthand for"MyProgram.pl"/file/runMThe function run takes a string, analyzes it and evaluates it as a Poplar expression."1+2"/run = 3"x _ ^"a^"; x x"/run = "aa"and x assumes the value "a".Often one saysMP _ "MyProgram.pl"/file; MP/runMbecause it is useful to keep the program around as a string so that it can be editted using Poplar.This is slightly less painful than going back to Bravo, and a lot more fun. The most frequent kindof thing one types isMP/{...("bad, old code" > "good, new code")...}Mor you may use subst:MP/substMwhich will prompt you for the new code and the old code (terminate by RETURN, as usual).When you forget the above options, type !@fsiF _qC \] ZB XxG TPvy Lq'= JFv y Bq:?vy ;Aq vqE7fv 51 1Uqvqvq -z )vy %qL #S !Y}v/y qvqvy ]qFwq M( ?Q]Poplar Language Manual 22?Mto print out the user commands.During type-in, the single ASCII quote (') can be used to enter strings:'name/file means "name"/fileThe string is terminated by any character not a letter, digit, period, or ^.A running program may be interrupted by typing CTRL-DEL. The expression currently underevaluation is printed and you are talking to teh debugging executive which prompts with a $'. Youare then given an opportunity to examine things further by the following mechanism: the debuggingexecutive will evaluate any expression typed in the context of the evaluation. Thus local variablesmay be examined just by typing their names. If you just type a RETURN the interrupt message isrepeated and a slightly larger expression context is displayed. If you type prM the computationresumes right where it left off. If you type DEL, the current computation is aborted and you returnto the normal executive.Input characters may be delivered to Poplar via the command line. Poplar starts by reading thecommand line (starting with the first blank) as if it were being typed in. When the command line isexhausted it begins to take its input from the keyboard.If a command file containspoplar "Running ex1"/print'$ex1'"Running ex2"/print'$ex2'quitThe effect of executing it will be to run the programs ex1 and ex2 and exit Poplar.ErrorsThere are three kinds of errors - syntax errors, run-time errors, and unforeseen errors (Poplar bugs).A syntax error will give the line and character on that line near (but always after) where the erroroccurred, and will print the line involved. Lines are counted by counting carriage returns. Thestatement count is the number of semicolons passed in the entire program being compiled.Run-time errors occur during the execution of programs and will print out the smallest expressionbeing evaluated. You may then interact with the evaluator in the manner described above in the!@fsiF_vy [:q W^(vqSv OqJvq K/wq I1uq  GbP E-O B)wq @Lvyvq >.wq & <\ 8K 6K,8 48 0;,_v*+'%# qS u qX H a ]F 6+ MN ?Q]Poplar Language Manual 23paragraph on interrupts. However, typing prM will restart the computaion with the expression mostrecently displayed, rather than precisely where the error occured. This gives you the opportunity tofix things up a little and continue. Because it is not possible undo all the effects of a error thisfacility will not always yield the expected results. A Poplar bug, is a "can't happen" error message which indicates some internal inconsistency. It istreated just like a run-time error. Such errors should be reported to the Poplar implementors.Poplar maintains various fixed-size storage areas which may overflow. Errors from storage overflowcan be programmed around by breaking the program or its input into smaller pieces.Odds and EndsPoplar will create some temporary files beginning with "Poplar ..." and ending with "$". They maybe removed and they will reappear when Poplar runs.All transactions are recorded on the "Mesa.TypeScript" file.!@fsiF _q*vyq! \V Z7. Xx6 T/4 RhN NK LXR Du @qS >3 :< :m>Q-fPoplar Language Manual 24Appendix A: ExamplesThe following examples are biased towards the kind of tasks Mesa programmers find themselvesdoing. This is more a function of the examples that come to our minds naturally, rather than theintent of the language.Example 1. A pattern to eliminate Bravo format trailersP _ {(...("^Z" ...)* "^M")! ...}P says: Find all occurrences of "^Z" ... "^M" and delete the "^Z" ... part.To transform old.bravo into new.text one types"old.bravo"/file/P/write"new.text"Example 2. Find all the mesa files for which a bcd file does not exist.""/dir//tolower//{... (".bcd" | ".mesa")}/RelevantFiles := ["a.bcd", "foo.bcd", "ajax.mesa", "foo.mesa", "ed.mesa", "al.bcd","zug.bcd", "al.mesa"];RelevantFiles//{... ".mesa"*} = ["ajax", "foo", "ed", "al"]/MesaFiles:RelevantFiles//{... ".bcd"*} /// ([x, y]: {y | x}) = {"zug" | {"al" | {"foo" | "a"}}}/BcdPattern:MesaFiles//{~BcdPattern ...} = ["ajax", "ed"]The tolower maplist is required since Poplar considers "bcd" and "Bcd" distinct.!@fpiqXFp ^r ZqQ Xxrq? U Os q,Lt H6qt qtq DZ.@~t" :ns q< 6t 4 1T/! ,; *+ 'U %5 "- qtq,tqtq  >QMPPoplar Language Manual 25Example 3. Finding substrings in files.FindAndShow _ (Pat: f: f/file/lines//{... Pat .../t: f ": " t/print; fail});FindAndShow is a function that, given a string Pat, produces another function which takes a filename f and displays the lines f which contain Pat. Each line is prefixed with the file name. Thefinal value is the empty list; the fail at the end is used to assure that printed lines are not saved.Here is a program which searches mesa files a.mesa, b.mesa, and c.mesa."pattern:"/key/p ="PUBLIC":p/FindAndShow = (f: f/file/lines//{..."PUBLIC".../t: f ": " t/print; fail})/FindPat:["a", "b", "c"] ".mesa" // FindPat Here is a program that prompts for the file names as well."pattern:"/key/FindAndShow/FindPat:"" % (x: "file:"/key/FN: FN >FN/FindPat) The prompt "file:" appears on the screen, and key returns the filename, FN. If the user types DEL,FN will be fail and everything stops. Example 4. Print a set of files ending in ".pl" using Bravo, but save paper by combining them intoone file and inserting headers.Files _ ""/dir // tolower // {... ".pl"} / sort;~(Files/isnull) >(Text _ Files // file "^Z^M^L^M";(("File: " Files "^M^M^M") Text) / conc / (x: x "^Z^M") / write "out.out$";"Hardcopy out.out$" / exec;"out.out$" / delete)Files is a list of the files to be printed. If Files is not the null list, it continues the computation.Text is a list of the contents of each of the files, appended with some Bravo formatting informationto print each file on a new page. The third expression generates a list of headers for the beginningof each file, with carriage returns between the header and the file. That list is concatenated into astring, a final bit of Bravo formatting is added, and it is written on a dummy file out.out$. TheHardcopy command is executed, and then the file out.out$ is deleted.!@fpiqXFp _s q [:t sqst>q W^t qtq. U*tqtqtq0 Rtq? OG Jt H|O FH D# @7q: ;t# 9w) 5q tqtqtquq 3gtqtq /s q tq3 -V (t0 &s$!!LZ ~q'tq4 JtqI J :, ] xD@ ?Q\Poplar Language Manual 26Example 5. Automate the programming cycle.Files _ ""/dir // tolower // {... ".errlog"*};~(Files/isnull) >"Bravo/m " Files "; "/conc " del " (Files ".errlog "/conc)"; compile " (Files " "/conc) / quitFiles is a list of Mesa filenames for which a .errlog file exists. If Files is not the null list, each Mesafile and its .errlog are brought in with the Bravo m' macro, each of the .errlogs is deleted, and allthose files are recompiled.Example 6. The function takes a list as input, prints each list element and a question markafterwards. If the letter y' is typed, that element will be an element in the resulting list, otherwise itwill not.Confirm _ (x: x//e: e "?"/key/{"y"}> e )!@fpiqXFp _s q Zt. XxVD:T$ P4qBtq MF K Ds q7 Atq7 ?;t( 7>Q0__Poplar Language Manual 27Example 7. Programs to add carriage returns to a paragraphAssume that the input, Paragraph, contains spaces but no carriage returns. To make the exampletypographically tractable we shall limit lines to 20 characters. All spaces and carriage returns areinside strings are written explicitly. The algorithm goes as follows:Initialize In to be Paragraph, and Out to be the empty string. As long as In is non-empty, Juggle Inand Out so as to put another line on Out. Finally, return Out..AddCrs1 _ (Paragraph := "0123^ 5678901^ 34^ 6789^ 1234567^ 9012^ 4567^ 9""01^ 3456789^ 123^ 56^ 89^ 1^ 345^ 789^ 12345^ 789""01^ 345^ 7^ 901^ 3456^ 8901^ 34^ 678^ 0123^ 56789""01^ 345^ 7";[Paragraph, ""] % ([In, Out]: In/{# ...} > [In, Out]/Juggle)/[In, Out]: Out= "0123^ 5678901^ 34^ ^M""6789^ 1234567^ 9012^ ^M""4567^ 901^ 3456789^ ^M""123^ 56^ 89^ 1^ 345^ ^M""789^ 12345^ 78901^ ^M""345^ 7^ 901^ 3456^ ^M""8901^ 34^ 678^ 0123^ ^M""5678901^ 345^ 7" );Juggle chops 19 characters off In, producing Line and RestOfIn. Then it breaks Line intoeverything up through the final blank, Most, and the remainder, Stub. The new value of Inbecomes the Stub followed by RestOfIn. The new Out becomes, Out followed by Most followedby a carriage return. If there are not 80 characters, In is set to be the empty string and Out to Outfollowed by In.!@fpiqXFp _s q/ [:tq? Y@sq# VF SX tqtqtq%tqtqt Qqtqtqtq NtqtqtqtqtqtqtqtLXqtqtqtqtqtqtqtqtqtJ#qtqtqtqtqtqtqtqtqtGqtqtEC,AR>Jqtqtqt<qtqtqt9qtqtqt7qtqtqtqtqt5xqtqtqt3Cqtqtqtqt1qtqtqtqt.qtqt, (qtq tqtqtq &tqtqt $aq tq tq tq tq tq "-3tq$tqt q tqJ >QKb6Poplar Language Manual 28Juggle _ ([In, Out ]: := ["0123^ 5678901^ 34^ 6789^ 1234567^ 9.....", "\\\"] In/{[len 19, ...] = ["0123^ 5678901^ 34^ 678", "9^ 1234567^ 9....."]/[Line, RestOfIn]:Line/{[(... " ")!, ...]} = ["0123^ 5678901^ 34^ ", "678"];/[Most, Stub]:[Stub RestOfIn = "6789^ 1234567^ 9.....", Out Most "^M"= "\\\0123^ 5678901^ 34^ ^M"] }| ["", Out In] );The following recursive program is an alternative.AddCrs2 _(Paragraph:Paragraph/{[len 80, ...]/[Line, RestOfLine]:Line/{[(... " ")!, ...]}/[Most, Stub]:Most "^M" (Stub RestOfLine/AddCrs2)}| Paragraph)!@fpiqXFp _tqtqtqtqtqtZXxqtqtqt)zVDqtqtTQ!qtqtqt O MrqtqtK>qtqtqtI FD ?dq2 :'tX7 5 3 1U$/!&$,#*( &O: #1)D7Poplar Language Manual 29Example 8. A program print all the files on the JuniperX directory which were written after the 9th ofAugust. We assume that the file ftp.log has already been created as shown below. (The FTP subsystemwill not execute a list command from the command line.)Month _ {"Jan" > 01 | "Feb" > 02 | "Mar" > 03 | "Apr" > 04 | "May" > 05 | "Jun" > 06| "Jul" >07 | "Aug" > 08 | "Sep" > 09 | "Oct" > 10 | "Nov" > 11 | "Dec" > 12};Date _ {[integer "-"* , Month "-"* , integer] / [d, m, y] : y m (d/length/{2} > d | 0 d)};File _ {(..."")* (word ">")!? word ".mesa" ("!" number)*};Line _ {[File " "!* , Date (... "^M")*]};Later _ ([f, d] : "9-Aug-78"/Date - d/{"-"...}>f);"ftp.log"/file /f := ".... defs>BTreeDefs.mesa!3 8-Aug-78 18:05:13 defs>FileSystemDefs.mesa!3 8-Aug-78 18:05:07 defs>FileSystemDefs.mesa!4 8-Aug-78 18:05:15 defs>triconprivatedefs.mesa!3 11-Aug-78 11:22:49 hes>nelsonenv.mesa!3 4-Aug-78 13:59:26 progs>CommonPineCold.mesa!3 11-Aug-78 17:36:24 progs>eventmanager.mesa!2 11-Aug-78 17:41:41 progs>eventmanager.mesa!3 11-Aug-78 11:40:39 progs>eventmanager.mesa!4 11-Aug-78 11:44:17 progs>wdisk.mesa!3 11-Aug-78 18:01:41 ...."; f / {Line,! ...*} = [ ["defs>BTreeDefs.mesa", 780808], ["defs>FileSystemDefs.mesa", 780808], ["defs>FileSystemDefs.mesa", 780808], ["defs>triconprivatedefs.mesa", 780811], ["hes>nelsonenv.mesa", 780804], ["progs>CommonPineCold.mesa", 780811], ["progs>eventmanager.mesa", 780811], ["progs>eventmanager.mesa", 780811], ["progs>eventmanager.mesa", 780811], ["progs>wdisk.mesa", 780811] ]!@fpiqXFp _s q[ \sq\ Z7 VDtqtqtqtqtqtqtqtqtqtqtqtTqtqtqtqtqtqtqtqtqtqtqt O1 Mr5 I F D/ @73 ;957f:5192=04.;,_9*+9'9%1# !Yqtqt%qtqtqtqtqtqt qtqtSqtqtqtqtqtqtqtqt qtqt M <]Poplar Language Manual 30// Later = [ "defs>triconprivatedefs.mesa", "progs>CommonPineCold.mesa", "progs>eventmanager.mesa", "progs>eventmanager.mesa", "progs>eventmanager.mesa", "progs>wdisk.mesa" ]/usort = [ "defs>triconprivatedefs.mesa", "progs>CommonPineCold.mesa", "progs>eventmanager.mesa", "progs>wdisk.mesa" ]/ fileList :"ftp ivy di/c juniperx ret/c " (fileList " " / conc) "^M"(fileList // { (word ">")!?* ... }/ fileList: "bravo/h " fileList "^M" / conc) ="ftp ivy di/c juniperx ret/c progs>CommonPineCold.mesaprogs>eventmanager.mesa defs>triconprivatedefs.mesa progs>wdisk.mesabravo/h CommonPineCold.mesabravo/h eventmanager.mesabravo/h triconprivatedefs.mesabravo/h wdisk.mesa" /execDate produces numerical dates like 780809 for "9-Aug-78". The file is read in and broken up intoa list of file-date pairs. All the things after the given date are filtered out and sorted, eliminatingduplicates. This produces fileList. Then a giant Alto command is created which fetches the filesand prints them using a Bravo macro.!@fpiqXFp _t qtqt\qtqZtqtqXxtqtqVDtqtqTtqtqQt O qtqtMrqtqK>tqtqI tqtqFt D Bl> @7. >&;977fD5120.,_q *+t ' !qtqt q! C% }tq8 I#s: >QO=Poplar Language Manual 31Example 9. A cross reference programThe following program produces a cross reference listing for the files a.mesa, b.mesa, and c.mesa. Itassumes that all the imported references begin with the prefix "P.".Xref _ (FileList: FileList //(FileName := "a.mesa"; FileName/file ="..A1:PUBLIC ...P.B1...P.C2....A2: PUBLIC .. P.B1.....P.B4..." /{(((... "P.")* thing),! | []) ...*} = ["B1", "C2", "B1", "B4"] /usort = ["B1", "B4", "C2"] //(x: [x, FileName]) = [["B1", "a.mesa"], ["B4", "a.mesa"], ["C2", "a.mesa"]] /Imports: FileName/file /{((... / LastWord "PUBLIC"*),! | []) ...*} = ["A1", "A2"] //(x: [x, FileName "*"]) /Exports:Exports,, Imports = [["A1", "a.mesa*], ["A2", "a.mesa"*], ["B1", "a.mesa"],["B4", "a.mesa"], ["C2", "a.mesa"]])///([x,y]: x,,y) = [["A1", "a.mesa*"],["A2", "a.mesa*"],["B1", "a.mesa"],["B4", "a.mesa"],["C2", "a.mesa"],["B1", "b.mesa*"],["A2", "c.mesa"]]/factor =[["A1", ["a.mesa*"]],["A2", ["c.mesa"], ["a.mesa*"]],["B1", ["b.mesa*"], ["a.mesa"]],["B4", ["a.mesa"]],["C2", ["a.mesa"]]]//(x: x/1 " " (x/-1//1 " "/conc))/(x: x "^M"/conc) ="A1 a.mesa*A2 c.mesa a.mesa*B1 b.mesa* a.mesaB4 a.mesaC2 a.mesa");!@fpiqXFp _s q [:F YD TtX Rh P4# M] KN I* Gb\ E- B @I >' <\:'K$7$5&31U/!,*(&O$!}I! wC  >Q\xPoplar Language Manual 32LastWord _ (s ="...A2 : ": s/reverse/{Sp* ":"* Sp* thing ...*}/reverse = "A2");Sp _ {" "!?};["a.mesa", "b.mesa", "c.mesa"]/Xref!@fpiqXFp \tO Y Up# P;K$Poplar Language Manual 33Appendix B: Primitive FunctionsThe following primitive functions can be used in Poplar programs. A function is said to take asinput the value it is applied to. It returns a value. A few functions take a parameter, which followsits name.append filenameAppends its string argument to the file.asortLike sort (see below) but uses the ASCII collating sequence for all strings, including stringsof numbers.cfileFunctionally exactly like file, but copies the file into virtual memory. This allows onesubsequently to overwrite the original file.chopTakes a string, breaks the string into single characters, and returns a list of strings of onecharacter each."abc"/chop = ["a","b","c"]checkHas the same effect as run, but checks the program as described in the section on equalityassertions.concTakes a list of strings as input and returns a string which is the concatenation of the listelements from first to last. A string as input will be returned as is. Thus, x///conc isequivalent to x/conc.["a","b","c"]/conc = "abc"daytimeReturns the day and time in a string.""/daytime = "December 1, 1978 9:12 AM"deleteTakes a string which is a file name on the local disk and deletes that file.""/dir//{... "$"}//delete!@fpiqXFp ^r Zfq!? X2sq!sqsq U O`vtM,q( HvFqtqEDZ ?v=q8!;, 7v4q-120t .Mv,qtq%) %|v#Gq5'!Gt Av q%t( ov ;qL t >Q]LPoplar Language Manual 34deletes all files whose names end in "$", equivalent to "delete *$"/exec.differTakes a list of two strings and compares them character by character. It returns a list of thetwo strings with any common prefix removed.["abcX","abcy"]/differ = ["X","y"]dirReturns a list of file file names in the local directory. Ignores its input.displayPrints its input on the screen. The input may be any Poplar value, e.g. a string, list, pattern.Returns its argument. See also print.divideTakes a list of two numbers [a,b] as input. Returns [a/b, a mod b]. If b is 0 it returns[a,a].editTakes a filename as input, quits Poplar and executes Bravo, then after the user quits fromBravo, invokes Poplar executing the editted file.execTakes any command, saves the current environment (via a Mesa checkpoint), has the AltoOperating System execute the command, and re-invokes Poplar in its saved state. execreturns its input.factorTakes a list of lists, sorts it according the the method of sort and then merges all adjacentsub-lists which have the same first element.[[1,2,3], [3,4,6], [1,7], [3,8], [1,6,9], [9,0]]/factor =[[1,[2,3],[7],[6,9]], [3,[4,6],[8]], [9,[0]]]This function turns out to be quite useful for adding structure to data. See Example 9.fileIts input is a string which is the name of a file. It returns a string with the contents of thatfile for future processing. See also listin.ident!@fpiqXFp_q%tqtq ZvXxq7(VD+Tt" QvOqM K>vI q4,Ftq Blv@7qtqtqtqtq >tq 9v7fqU511 0v.q0&,_5t*+q %v#q;tq!Y,Qt9-qM vwqCC&tq v :[\xPoplar Language Manual 35Does nothing and simply returns its input (the identity function).islistReturns its input if its input is a list, returns fail otherwise.isnullReturns its input if its input is the null list [], returns fail otherwise.isstringReturns its input if its input is a string, returns fail otherwise.keyPrompts the typist with its input string. Waits for him to type in a sequence of charactersterminated by RETURN. Returns the string without the RETURN. The MesaReadEditedString routine is used so the usual control characters can be used. If DEL istyped it returns fail.lengthIts input must be a string or a list. If its input is a string, returns the length of the string. Ifits input is a list, returns the number of list elements.linesBreaks the incoming string into a list of strings, one for each "line" or sequence ofcharacters separated by carriage return. It is equivalent to{((... "^M"),! | []) ,, [...]}listinIts argument is the name of a file created by listout. Returns the parameter to listout whenthe file was created, or fail if the file can't be processed.listin = (x: x/file/x:x>x/run)listout filenameTakes as input a Poplar expression, such as a list or string, and writes it in a special form onfile filename. The expression may be recovered using listin.marryTakes a list of two lists of equal length. Each element of one list is paired with itscorresponding element in the other list, and marry returns that list. See also zip. [["a","b",1],["c","d",2]]/marry = [["a","c"],["b","d"],[1,2]]!@fpiqXFp_qB ZvXxq2tq TvQqq4tq FvDqN Blk uq"uql @7Nuq>tq 9v7fq W519 0v.qI ,_=*+t %v#qtq(!Y=%t vqtqXStq)tq vq8 -tqtq Mt= :$]Poplar Language Manual 36maxReturns the maximum element of its input, which must be a list of numbers. Thus x///maxis equivalent to x/max.micasA pattern which matches a single character and returns the number of micas it would takein Times Roman 10 pt. font."a"/{micas} = 165"aA"/{micas,!} = [165, 265]One can use scaling factors to get approximate answers for other fonts. minLike max, but the minimum.minusTakes a list of two numbers [a,b] as input. Returns a-b.plusTakes a list of two numbers [a,b] as input. Returns a+b.printIs like display but prints only strings. It prints them with no quotes. See display.quitTakes a string as input, executes the string as a command. Does not return to Poplar. Seealso exec.reverseTakes a list or string and reverses the order of its elements or characters.["a","b","c"]/reverse = ["c","b","a"]"abc"/reverse = "cba"runTakes a string, treats it like a Poplar program, and evaluates it, returning the value.stopExits poplar like quit, but does not attempt to execute a command.!@fpiqXFp \vZq2tXxqtq TvQqOOMrK>I H DvBlqtq >v;qtqtq 7fv51qtqtq 0v.qtq$tq *+v'qD%tq !Yv%qLt% Svq9 v qtq, 9[]Poplar Language Manual 37substTakes as input a string and performs substitutions for occurrences of a string (the patternstring). The pattern and the substitution string ("new" string) are prompted from theterminal. Typing DEL for either will abort the substitution. This function is similar infunction to the Bravo Substitute command. It returns the input string with all occurrencesof the pattern replaced by the substitution string. Typing/subst M P M Q Mis equivalent to typing/{(...("Q">"P"))!...} MsortTakes a list and returns its sorted permutation. If all the items are numbers the result isordered by numerical value.See also usort and asort.symbolReturns a list of all variables referenced or defined (sans primitives). Ignores its input.timesTakes a list of two numbers [a,b] as input. Returns a*b.tolowerTakes a string as input. Returns the string with all upper case letters [A-Z] changed to theirlower case equivalents [a-z].toupperTakes a string as input. Returns the string with all lower case letters [a-z] changed to theirupper case equivalents [A-Z].usortUses asort to sort the incoming list, which must be a list of strings, and returns a sorted listwith duplicate strings removed. See also asort, sort.!@fpiqXFp _v\qKZ sqsq%XxuqBVD9"T;P4twtwtwLXqH|tw Dv@7q\>:'tqtq 5v3qH /!v,qtqtq (v&Oq P$ v}q?I vqtqSw*t q 9[XPoplar Language Manual 38write filenameTakes the incoming string and writes it on file filename. If file filename exists, it will beoverwritten. An error will occur if the file is open for reading. The simplest way to avoidsuch errors is to never write on a file which as previously been the input to a file or listin.See also listout.zipTakes a list of two lists. Elements in the two lists are interleaved in the resulting list.[[1,2],[3,4]]/zip = [1,3,2,4]The following functions are used in debugging Poplar and are not normally useful or necessary.garbageForces a garbage collection. Ignores its input.snapGives a snapshot of the storage allocator. Ignores its input.!@fpiqXFp _vt\q0tq tqZ9$Xx4tqtqVDtq QvOqMMrt Fq4* Blv@7q0 ;v9q> 0=Q7pPoplar Language Manual 39Appendix C: Syntax EquationsThis grammar describes how the Poplar parser treats a program. Therefore it describes many illegalprograms whose illegality does not come to light until the program runs. Don't be confused by thenames given to grammatical categories. They are meant to be suggestive of the first one or twoalternatives, but not all of them. Thus a Function can, degenerately, be a Sequence which can be aStatement, etc. Non-terminals are in italic, literal characters are in boldPoplarProgram ::= Function end-of-fileFunction ::= Variable : Function| [ VariableList ] : Function| Prelude Function| SequencePrelude ::= Statement ;| Variable _| ChoiceExp || ThenExp >| BinaryExp BinOpSequence ::= Statement ; Sequence| Statement ;| StatementStatement ::= Variable _ Statement| ChoiceExpChoiceExp ::= ChoiceExp | ThenExp| ThenExpThenExp ::= ThenExp > BinaryExp| BinaryExpBinaryExp ::= BinaryExp BinOp PrefixExp| BinaryExp PrefixExp| PrefixExpBinOp ::= / | // | /// | % | + | - | ,, | --!@fpiqXFp ^r ZqL XH VG TV#sqsq R"sq NFsqv Jjs xsqv FsqsxvqsDZqxqs qvxvqsB%qs?qs <qsqv9qsv7qsqv5xqsxv3Cqsqs /hqsqvxs-3qsqv*qs '#vs $qs !qsqvqsqs qsxvqsqs qsqsxsqsqs qvqvqvqvqvqvqvqv g>Q[Poplar Language Manual 40PrefixExp ::= UnaryFunction PreFixExp| - PrefixExp| ~ PrefixExp| PostFixExpPostFixExp ::= PostFixExp !| PostFixExp ,!| PostFixExp ?| PostFixExp *| SimpleExpSimpleExp ::= String| Variable| PrimitiveFunction| @| #| fail| ...| [ List ]| [ ]| { Function }| ( Function )List ::= List , Function| FunctionVariableList ::= VariableList , Variable| VariableVariable ::= a single letter | any sequence of letters and digits including one capital letterUnaryFunction ::= len | blanks | write | listoutString ::= " any sequence of characters in which a ^ precedes every " "PrimitiveFunction ::= a sequence of two or more small letters (see Appendix B.)Poplar uses these literal symbols:; / // /// % | > : + - ,, -- ~ ! ,! ? * " @ # ... [ ] { } ( ) , !@fpiqXFp _sqs\qyvxsZqvxsXxqs T qs qvRhqs qvP4qs qvMqs qvKqs GqsEqsCqsARqv?qv C" gv@ =Q[Poplar Language Manual 41Appendix DGetting StartedGet [maxc]poplar.image and run it.On [maxc]pl> is a set of files ex1.pl - ex9.pl for each of the examples in Appendix A.Please send comments to Morris.!@fpiqXFp ^r Z Vq* RB O N=Q91 HELVETICA TIMESROMAN  TIMESROMAN TIMESROMAN  TIMESROMAN  TIMESROMAN  HELVETICA  HELVETICA TIMESROMAN  MATH  TIMESROMAN  TIMESROMAN  TIMESROMAN  TIMESROMAN  HELVETICA  HELVETICA HELVETICA MATH  TIMESROMAN   HELVETICA J' ? Ec<Q!Q%e)`-O1<6 ;@ADMH4MTQ.UWY,^ad#ilqnty>}V=-,KB"P:Z"i6P* Z :#='J#%$P:C%P=##:C:#=#B"Py:C:C"i rZ ( B "=i#B " 9eB: ;Z":#j/*"Y Poplar.PressSchmidt23-Aug-82 10:46:01 PDT