11

I don't have formal knowledge of continuations, and am wondering if someone can help me verify and understand the code I wrote :).

Problem

The general problem I'm trying to solve is to convert expressions like

(2 * var) + (3 * var) == 4

into functions

\x y -> 2 * x + 3 * y == 4 -- (result)

which can be then passed into the yices-painless package.

Motivation

As a simpler example, note that var is translated into \x -> x. How can we multiply two var's (denote them \x -> x and \y -> y) into one expression \x -> \y -> x * y?

I've heard continuations described as the "rest of computation", and thought that's what I need. Following that idea, a var should take a function

f :: α -> E -- rest of computation

whose argument will be the value of the variable var created, and return what we want (code listing marked result), a new function taking a variable x and returning f x. Hence, we define,

var' = \f -> (\x -> f x)

Then, for multiplication, say of xf and yf (which could be equal to var, for example), we want to take a "rest of computation" function f :: α -> E as above, and return a new function. We know what the function should do given the values of xf and yf (denoted x and y below), and define it as so,

mult xf yf = \f -> xf (\x -> yf (\y -> f (x Prelude.* y)))

Code

const' c = \f -> f c
var' = \f -> (\x -> f x) -- add a new argument, "x", to the function
add xf yf = \f -> xf (\x -> yf (\y -> f (x Prelude.+ y)))
mult xf yf = \f -> xf (\x -> yf (\y -> f (x Prelude.* y)))

v_α = var' -- "x"
v_β = var' -- "y"
v_γ = var' -- "z"
m = mult v_α v_β -- "x * y"
a = add m v_γ -- "x * y + z"
eval_six = (m id) 2 3
eval_seven = (a id) 2 3 1

two = const' 2 -- "2"
m2 = mult two v_γ -- "2 * z"
a2 = add m m2 -- "x * y + 2 * z"
eval_two = (m2 id) 1
eval_eight = (a2 id) 2 3 1

quad_ary = (var' `mult` var') `mult` (var' `mult` var')
eval_thirty = (quad_ary id) 1 2 3 5

well, it seems to work.

gatoatigrado
  • 16,580
  • 18
  • 81
  • 143
  • Start [here](http://en.wikipedia.org/wiki/Continuation). –  Jan 15 '12 at 06:26
  • 2
    I've tried reading that a number of times... I dunno, but other people's explanations like the sandwich analogy really don't make sense to me. Maybe they'll make sense _after_ I understand continuations, but then they'll be less useful. – gatoatigrado Jan 15 '12 at 07:31
  • So true. And some people complain that monads are explained badly, sheesh. – Daniel Fischer Jan 15 '12 at 10:28
  • Please don't use `α` or `β` in code! – Vlad the Impala Mar 28 '12 at 00:00
  • @VladtheImpala, I think you're being a little English/US centric. OTOH I usually keep the usage to type variables, to keep those separate from code variables -- this is a little messier, I agree. – gatoatigrado Mar 31 '12 at 23:21
  • 1
    I really grasped continuations after learning Scheme, and having realized that `call/cc` "makes a hole" in the code. This may make sense to you one day. Good luck. – Alexandre C. Aug 29 '12 at 22:27

1 Answers1

3

Yes, this is written in continuation passing style (CPS).

Somebody once explained continuations to me as "callbacks everywhere", which I didn't find particularly useful but maybe you will.

As seems true with so many things, probably the best you can do is to keep working on this to develop more fluency with the style.

John L
  • 27,937
  • 4
  • 73
  • 88