Shishir,
You've already gotten some excellent descriptions.
As a recovering OO programmer, I get to the same answer by a slightly different path, offered below for what it's worth.
When I read the first line:
let add_cps x y = \k -> k (x+y)
I see a definition of a function (add_cps) with two arguments (x and y) whose evaluation yields a function (\k -> k (x+y)).
I started to write "an anonymous function" out of habit, but stopped myself. I don't think of functions as having names or not having names, any more than I think of expressions as having names or not. Variables are bound to (refer to) values, and a function is just another kind of value to which a variable can refer. (And multiple variables can refer to the same value, by the way, so none of them is really "the name" of the value, regardless of whether that value happens to be a function.)
So at this point, I can think of using the name add_cps in another expression, such as:
add_cps 3 4
which (by the substitution principle) must be equivalent to:
\k -> k (3+4)
That expression is clearly a function (because of the lambda) that takes a single argument and applies it to the expression (3+4) (which isn't yet evaluated, by the way, but when it is I expect it to yield 7). So the argument to that function expression must itself be a function.
When I get to the second line:
add_cps 3 4 $ print
I confess to cheating a bit (and the experts may want to offer me some correction). I mentally rewrite that as:
(add_cps 3 4) print
because the precedence rules tell me to evaluate the left argument of $ before combining that with what follows.
So I can apply the substitution principle to get
(\k -> k (3+4)) print
and then apply it again to get
print (3+4)
Hope this helps,
-jn-