• Handouts
automaton macro to define a predicate that
tests whether a given list of symbols (a) consists entirely of the symbols
foo and bar and (b) contains a sublist of three adjacent
symbols in which the first is foo and the last is bar.automaton macro actually expands to a
procedure that returns true when given any prefix of a list
that the automaton should accept. For instance, in his very first example,
his macro produces an automaton that accepts '(0 1 0), which is not
of the form (01)*. Extend the macro to provide a mechanism
for the programmer to specify which states of the automaton are "accepting"
states. The predicate derived from the macro application should still return
true if the automaton is in an accepting state when it reaches the
end of the list, but should return false if it is in a non-accepting
state at that point.(in preparation)
!-expression ("cut") might be implemented
in terms of continuations.type relation to accommodate nil-, ifnil-, newpair-, opencar-, and opencdr-expressions, imposing the
the restrictions that the cdr of a pair must be a list and that all of the
elements of a list must be of the same type.X,
Y, and Z if, and only if, Z is a common ancestor of
X and Y in the "academic family tree" that Krishnamurthi
describes in section 33.1. Then define a binary relation that holds
between X and Y if they have a common ancestor.type
relation to accommodate +-expressions and with-expressions,
as in FWAE. Does Prolog automatically support let-based
polymorphism?let-based" polymorphism? What data must a type closure
contain in order to make this work?let-based polymorphism
prohibit the use of side effects in connection with identifiers that have
polymorphic types?map on page 282. Then execute the
unification algorithm to infer the types of those subexpressions,
confirming or refuting Krishnamurthi's identification of the inferred type
of map.
<type> ::= "number"
| "(" <type> "->" <type> ")"
and the corresponding abstract syntax is represented by the datatype
definition
(define-type TFAE-Type (number-type) (function-type (parameter-type TFAE-Type?) (return-type TFAE-Type?)))How might we modify these syntax rules to add
list as
a type constructor? (Note: We wouldn't have to use the concrete syntax
that Krishnamurthi uses in chapter 29; we're building onto TFAE,
whereas he's building onto Scheme, so whatever we come up with won't look
exactly like his syntax anyway.)malloc, fopen, and scanf in
order to detect failures in their execution.t0 and t1, the type t0*t1 will be the type of ordered pairs in
which the car is of type t0 and the cdr of type t1. Extend the syntax and semantics of TFAE to include
expressions and values of product types.datatype-expressions, as Krishnamurthi
appears to be using them in chapter 27. You may need to adjust the BNF for
the <type> syntax category as well.rec-expressions
redundant, like the return-type annotation in fun-expressions? What
reason might there be to require it?rec-expressions to our
interpreter for the TFAE language to get an interpreter for TRCFAE. Be
sure to modify the parse, interp, and type-check
procedures to handle them correctly.TFWAE-Type of which each
individual value represents a data type of TFWAE. Then write a
procedure type-check that takes an abstract syntax object of TFWAE
and returns its type, if it satisfies the typing rules Krishnamurthi
proposes, or #f if it does not.type-check would be to add one more
value to the TFWAE-Type data type: TypeError, which would
represent the pseudo-type of a syntactically correct expression of TFWAE
that does not satisfy the typing rules. Then type-check could
always return a TFWAE-Type. Implement this design and compare its
strengths and weaknesses with those of the type-check procedure you
wrote in the preceding exercise.
{fun {x : number} : (number -> number)
{fun {y : number} : number
{+ x y}}}
of TFWAE.with-expressions in TFWAE. Justify
your rule by deriving it from the typing rules for fun-expressions
and applications, together with the syntactic rule for preprocessing with-expressions.with-expressions and show how it is
related to the rules for fun-expressions and applications.fun-expressions and
applications to accommodate functions of all (fixed) arities?{{fun {augend} {+ augend 3}} {+ base 5}}, in
an environment that maps base to 9, is 17.{{C {{J I}
C}} {J I}} would more usually be written as C(JIC)(JI). Write a
Scheme procedure that takes an object of the CL datatype and outputs
it in this more concise concrete syntax.
{with {fact {lam f {lam n {if {iszero n}
one
{{prod n} {f {pred n}}}}}}}
{with {factorial {make-recursive-procedure fact}}
{factorial {{sum three} one}}}}
first in the simpler implementation of combinatory logic (without the B and C combinators), then in the implementation with those
combinators. Is the difference significant? Could adding more primitive
combinators improve performance?I combinator in our implementation of
combinatory logic is theoretically superfluous by defining an equivalent
function, using only the K and S combinators.
{with {fact {lam f {lam n {if {iszero n}
one
{{prod n} {f {pred n}}}}}}}
{with {factorial {make-recursive-procedure fact}}
{factorial {{sum three} one}}}}
in our eager interpreter for the untyped lambda-calculus leads to runaway
recursion. How could we modify the interpreter to keep that from
happening?yes if the first denotes a number greater than the number that the second
denotes, and no otherwise. (Hint: Use recursion.)alt and
range operators analogous to the | and to ... by operators in Icon. The file ends with seven commented-out test cases.
Write down what you expect the results of running those test cases would
be, then uncomment and run them, then compare the actual results to your
expected results and write up an explanation of any differences that you
find.&fail that, when evaluated,
fails. Add a similar expression fail to GCFAE.not-expression to GCFAE. It should take one operand,
failing if evaluation of that operand succeeds and succeeding (once, with
the value 0) if evaluation of the operand fails.throw-expression to the KCFAE language, and remove the possibility of
using a continuation-valued expression in the operator position of an
application.until-expression evaluates its body once immediately, then
tests to see whether its exit condition is true, terminating if so and
repeating if not. The value of an until-expression is the result of
the last evaluation of the body. Give two definitions of until, one
as a Scheme procedure that takes its body and exit-condition as
(procedure-valued) arguments, analogous to Krishnamurthi's definition of
for on page 201, and the other as new Scheme syntax (introduced
through define-syntax).web-read in terms of let/cc and web-read/k.send) to each
of the non-negative powers of 2, in ascending order. This producer body
will probably contain an infinite loop. Why doesn't this matter?/home/stone/courses/languages/examples/Eratosthenes.hs, then define mark, sieve, intsFrom, and primes as Scheme
procedures. The Haskell type declarations are a useful guide -- if you
read "[Integer]" as "generator of integers"!)((lambda (x) (+ (web-read "Augend: ") x)) 42)to continuation-passing style.
(lambda (final-k)
(web-read/k "Augend: " (lambda (l-val)
((lambda (x dyn-k)
(dyn-k (+ l-val x)))
42
final-k))))
or perhaps even into
(lambda (final-k)
(web-read/k "Augend: " (lambda (l-val)
(final-k (+ l-val 42)))))
What simple optimization could convert the output of the Fischer
transformation into this last version?web-read is (-> string? number?) and the
contract for web-display is (-> number? any).FORM element transmit a user-supplied string to
a program that it invokes? How does it transmit a "hidden" string?arr[0] := 42;, where arr has
been declared to be an array of seventeen ints, does the
expression arr[0] have an l-value? Justify your answer. Similarly,
consider the C fragment p = &arr[0]; *p = 42;, where arr is
an array of seventeen ints and p is of type [int *]. Does
the expression *p have an l-value?swap function to exchange their
contents, and finally computes the sum of the the contents of the first box
and double the contents of the second box.
> (test (interp (parse '{with {x 3}
{fun {y}
{+ x y}}})
(mtSub))
(closureV 'y (add (id 'x) (id 'y)) (aSub 'x (numV 3) (mtSub))))
(list 'bad
(closureV 'y (add (id 'x) (id 'y)) (lambda (a1) ...))
(closureV 'y (add (id 'x) (id 'y)) (lambda (a1) ...))
"at line 165")
What's the explanation?
<CFAE/L> ::= "true"
| "false"
| "{" "<=" <CFAE/L> <CFAE/L> "}"
| "{" "if" <CFAE/L> <CFAE/L> <CFAE/L> "}"
| "{" "&&" <CFAE/L> <CFAE/L> "}"
| "{" "||" <CFAE/L> <CFAE/L> "}"
The literals true and false should simply evaluate to the
Boolean values they name, regardless of context. The less-than-or-equal-to
expression should evaluate to the true Boolean value if both of its
CFAE/L subexpressions evaluate to numbers and the one on the left is less
than or equal to the one on the right; it should evaluate to the false
Boolean value if both of its CFAE/L subexpressions evaluate to numbers and
the one on the right is less. The test in the if-expression should always
be Boolean; the if-expression should have the same value as the consequent
if the test is true and the same value as the alternate if the test is
false. Both of the CFAE/L subexpressions of an &&-expression should
be Boolean, and the whole expression should be true if both subexpressions
are true and false otherwise. Similarly, an ||-expression should be
true if either of its CFAE/L subexpressions is true, false if neither
subexpression is true.&&-expressions and ||-expressions use "short-circuit" evaluation? If not, modify the
implementation to guarantee this property.
<FAE/L> ::= "{" "if0" <FAE/L> <FAE/L> <FAE/L> "}"
and the semantics that the value of the entire expression is the value of
the second <FAE/L> when the value of the first <FAE/L> is zero and the
value of the third <FAE/L> when the value of the first <FAE/L> is non-zero.
What should happen if the value of the first <FAE/L> is a function closure
rather than a number?powers that takes a positive
integer as argument and returns an infinite list containing the powers of
that integer, in ascending order, starting from 1. (For instance, the
value of take 5 (powers 7) should be the list [1, 7, 49, 343,
2401].)1 + (length ones))?interp and faeLookup are lazy
-- the arguments are not evaluated unless and until their values are
actually needed in a computation. From the point of view of the FAE user,
does this make application in FAE lazy as well? How can you tell?with-expression
is equivalent to an application in which the operand is a fun-expression, so that it's unnecessary to have a with-variant in
the data type that expresses FAE's abstract syntax. Is it also possible to
reverse this process and replace every fun-expression with an
equivalent with-expression, perhaps in combination with other
constructs of FAE? If so, show how a preprocessor might do the conversion;
if not, explain the nature of the difficulty.qsort function. Describe
its interface and explain how it is shaped by the absence of first-class
functions from C.my and
local as ways of declaring variables that are local to a function?DefrdSub structures, as Krishnamurthi proposes in
Exercise 5.3.3.FunDef data type? How is
the appropriate number of variants determined?with would supersede any function definitions. Could this be done
in the substitution framework that we're currently using? If so, how? If
not, what's the obstacle?
(test (interp (parse '{f 5})
(list (parse-fundef '{function f {n} {g {+ n 5}}})
(parse-fundef '{function g {m} {- m 1}})))
9)
This test failed, because interp raised the "function not found"
error. Why?
(let loop ((index count))
(if (zero? index)
'()
(cons repetend (loop (- index 1)))))
Are there any binding instances of identifiers in this expression? If so,
where do they occur?calc procedure for WAE, the clause
that is supposed to compute the value of an identifier simply invokes error, which interrupts the computation. Why? Shouldn't calc look
back to the point at which the identifier was bound and recover the value
of the identifier from the value of the named-expr that occurred
there?parse, subst, and calc procedures for WAE if we wanted it to use lazy
evaluation?begin-statement consists
of the keyword begin, zero or more statements, and the keyword end. Any two otherwise adjacent statements must be separated by a
semicolon, and a semicolon may optionally be placed between the last
statement, if there is one, and the end keyword. Taking the <statement> category as given, write a description of the syntax of begin-statements in Pascal in extended Backus-Naur form.<syntactic category> and <literal
token> as primitives. Write a BNF for (our version of) Extended BNF.read procedure,
using read-char and peek-char as the only available
operations on input ports. How would you go about it? At what points, if
any, would you use recursive calls to read? What problems would you
encounter?
<?xml version="1.0" encoding="ISO-8859-1"?>
<java:class access="public" name="HelloWorld">
<java:method access="public" per="static" return="void" name="main">
<java:parameter name="args">
<java:arraytype>
<java:type name="String" />
</java:arraytype>
</java:parameter>
<java:block>
<java:statement>
<java:expression>
...
</java:expression>
</java:statement>
</java:block>
</java:method>
</java:class>
## is ill-formed in Scheme. Give another example of a character sequence
that is likely to cause an error in scanning.42?
<unary-expression> ::= <postfix-expression>
| ++ <unary-expression>
| -- <unary-expression>
| <unary-operator> <cast-expression>
| sizeof <unary-expression>
| sizeof <type-name>
Construct a PLAI-style type definition that expresses the corresponding
abstract syntax.