F28PL Study Class
For basic drill, work your way through
- tutorial 6 and
- tutorial 7.
If and when you get stuck, you can
- ask a labhelper for help, or
- look up the slides, or
- check out this webpage and this webpage, which I just discovered while writing this page, and they are great.
Now for more interesting questions. Don’t worry if you can’t do these … but try:
(If you spot errors, e-mail me and I’ll fix it.)
I. Some stuff on functions
- Write the type of
fn x => fn y => x andalso y
.
(Answer)bool -> bool -> bool
Make sure you understand why. - In ML,
andalso
andorelse
need not evaluate their second argument. When, and why?
(Answer)exp1 andalso exp2
will not evaluateexp2
ifexp1
evaluates tofalse
, for implementational efficiency because the overall result of the computation will not depend on the result of evaluatingexp2
(see Short-circuit evaluation).
What’s the corresponding property oforelse
? - What’s the type of
fn x => 42
? Describe this type in words.
(Answer)'a -> int
In words: “$\alpha$ to int”, or more sexily: a parametric polymorphic function to integers. - (Hard) What do you think the implementational difference might be between
fn x => 42
andfn _ => 42
?
(Answer)fn x => 42
evaluates its argument, then ignores the result and returns42
.
fn _ => 42
ignores its argument and returns42
. - Write a deliberately implementationally inefficient function called
myand
in ML of typebool -> bool -> bool
that implements logical $and$, and always evaluates both arguments. Use thefun
construct to name it—-I showed you this in class, or see page 7 of Lecture 12, or see this page.
(Answer)fun myand true true = true | myand true false = false | ...
- Write your own implementation
myandalso
ofandalso
, complete with implementational efficiency.
(Hint)A good start might befun myandalso false _ =>
.
II. Higher-order functions
- Recall question I.1 above. Now write the type of
fn y => fn x => y x
. Why the difference?
(Answer)('a -> 'b) -> 'a -> 'b
. Function applicationy x
is polymorphic, whereasx andalso y
requiresx
andy
to have typebool
thus imposing constraints on the overall type. - What’s the difference between the types
'a -> 'b -> 'c
and'a * 'b -> 'c
?
(Answer)The type'a -> 'b -> 'c
is inhabited by programs that input an argument of type'a
and return a value of type'b -> 'c
.
'a * 'b
is inhabited by programs that input an argument of type'a * 'b
and return an argument of type'c
. - (Hard) Write a program of type
('a -> 'b -> 'c) -> ('b -> 'a -> 'c)
.
(Answer)fn f => fn y => fn x => f x y
. - (Harder) Write programs of type
('a -> 'b -> 'c) -> ('a * 'b) -> 'c
and('a * 'b -> 'c) -> ('a -> 'b -> 'c)
.
(Answer)I’m looking for this:
-fn f => fn (x,y) => (f x y)
and
-fn f => fn x => fn y => f (x,y)
.
It’s simple, provided you understand what the types are. - (Even harder) Write your own implementation
mycompose
of functional composition. This should have type('a -> 'b) -> ('b -> 'c) -> ('a -> 'c)
and should input $f$ and $g$ and output $g \circ f$ the function which inputs $x$ and outputs $g(f(x))$.
(Answer)fun mycompose f g x = g(f(x))
. If you can’t kick yourself yourself, get your neighbour to kick you for you. In nameless notation:fn f => fn g => fn x => g(f(x))
- (Bloody hard) Write a program of type
int -> ('a -> 'a) -> ('a -> 'a)
which inputs an integer $n$ and a function $f$ and returns $f^n$ (the composition of $f$ with itself $n$ times). You’ll need to use recursion (see below).
III. Strings, numbers, and recursion
- (Trick question) Write a program to output World Peace. What’s its type?
(Answer)"World Peace":string
. Sorry; couldn’t resist. - Write a program to input two strings
x
andy
and output their concatenationx^y
. What’s its type?
(Answer)fn x => fn y => x^y : string -> string -> string
- (Highly examinable) Write a program
myfact
that inputs $x$ and outputs $x$ factorial, which is $x!=x(x{-}1)(x{-}2)\dots 1$. We do not care what happens if $x$ is negative. What is the type ofmyfact
?
(Answer)fun myfact 0 = 0 | myfact 1 = 1 | myfact x = x*(myfact (x-1))
myfact:int → int
- (Highly examinable) Find the Fibonacci function and Ackermann’s function online and write them in ML.
IV. Discussion questions
- Discuss two advantages of using ML over using Java and give two concrete examples which illustrate those advantages in a “real-life” scenario.
- Discuss two advantages of using Java over using ML and give two concrete examples which illustrate those advantages in a “real-life” scenario.
(Answer)The usual obvious things: it’s easier to find a Java programmer than an ML programmer. Better industry and library support. Possibly faster.
However (skipping to partially answer the previous question) the ML program will be smaller and more maintainable than its Java equivalent so you get more productivity out of your programmer per man-hour—-possibly a factor of ten or more, if they’re good. It’s by no means clear that Java is “better” in any reliable sense than a modern functional language such as OCaml, Haskell, or Erlang.
Check out a company like Jane Street (see “The OCaml difference”).
- Give one concrete example where using assembly code would be more appropriate than using either ML or Java.
(Answer)An embedded control chip with limited (e.g. 1k) of memory. Or a boot sector (that’s the first tiny fragment of code on a hard drive).
But, as always in such questions, there are arguments for and against: check out Embedded C and somebody who wrote a boot sector in C. - (Possibly hard) I promise to give you an ML program which will input a Java program and tell you whether it outputs “Hello world”. Explain why I’m lying.
- The Met office has just invested in a new supercomputer to model the weather. Give one good reason why it might be programmed in ML, and one good reason why we might prefer to use C.
(Answer)C will probably run faster on a per-thread basis, but ML will be much easier to parallelise to many threads (and modelling the weather is a highly parallel task). In practice they’ll probably use a special-purpose language that combines a language like C with powerful parallelism constructs.
Conclusion
If you’ve worked your way through all these questions in two hours then you’re probably not human. To fill time so you’re not found out, read this great essay on beating the averages by Paul Graham, who made a mint out of functional programming and went on to found Y Combinator.