Call-by-name vs call-by-value

With termination . . .

def test(x: Int, y: Int) = x * x

test(2, 3) cbv cbn
2 * 2
4 // 1 steps
  
  
test(3 + 4, 8) cbv
test(7, 8)
7 * 7
49 // 2 steps
  
test(3 + 4, 8) cbn
(3 + 4) * (3 + 4)
7 * (3 + 4)
7 * 7
49 // 3 steps
  
  
test(7, 2 * 4) cbv
test(7, 8)
7 * 7
49 // 2 steps
  
test(7, 2 * 4) cbn
7 * 7
49 // 1 steps
  
  
test(3 + 4, 2 + 4) cbv
test(7, 2 + 4)
test(7, 8)
7 * 7
49 // 3 steps
  
  
test(3 + 4, 2 + 4) cbn
(3 + 4) * (3 + 4) 
7 * (3 + 4) 
7 * 7 
49 // 3 steps

Without termination . . .

def first (x: Int, y: Int) = x
def loop: Int = loop
  
first(1, loop) cbv
// looping and looping and loo...
first(1, loop) cbn
1 // done

Scala defaults to cbv, unless the type is prefixed with => example def first (x: Int, y: => Int) = x