0

I'm learning sicp 1.3(Formulating Abstractions with Higher-Order Procedures).The scheme code can compute the sum of the cubes of the integers from a to b.

(define (sum term a next b)
  (if (> a b)
      0
      (+ (term a)
         (sum term (next a) next b))))
(define (inc n) (+ n 1))
(define (cube x) (* x x x))
(define (sum-cubes a b)
  (sum cube a inc b))

And i want to do it by php,here is the code.

function sum($term,$a,$next,$b){
    if ($a>$b){
        return 0;
    }else{
        return $term($a) + sum($term,$next($a),$next,$b);
    }
}
function inc($n){
    return $n + 1;
}
function cube($x){
    return $x*$x*$x;
}
function sum_cubes($a,$b){
    return sum(cube,$a,inc,$b);   // line 15
}

it works,but i received

PHP Notice: Use of undefined constant cube - assumed 'cube' in Command line code on line 15 PHP Notice: Use of undefined constant inc - assumed 'inc' in Command line code on line 15.

Is it ok and any better way to achieve it?

Shadow C
  • 5
  • 2
  • Can you point out which is line 15 - is it the line where you return the sum inside the sum_cubes function? – Kalin Varbanov Mar 06 '16 at 11:30
  • `return sum(cube,$a,inc,$b);` ... you can`t pass the function name... – ka_lin Mar 06 '16 at 11:32
  • You can pass the result of the functions as parameters, ex :`return sum(cube($a),$a,inc($b),$b);` – ka_lin Mar 06 '16 at 11:41
  • it does't work,i received PHP Fatal error: Function name must be a string in Command line code on line 5( return $term($a) + sum($term,$next($a),$next,$b) – Shadow C Mar 06 '16 at 11:47

3 Answers3

0

From what I see here the return statement calls the cube and inc functions, but they require input parameters. If you are not calling them here(which I think is the case), then you should be passing the forwards, but with a $ in front of their names.

EDIT: Keep in mind though that this requires PHP 5.3.0 or higher. See the manual for more info.

Kalin Varbanov
  • 363
  • 3
  • 13
0

I solved it,just enclosed function name in quotes.

function sum_cubes($a,$b){
    return sum('cube',$a,'inc',$b);
}
Shadow C
  • 5
  • 2
0

Your implementation is a little incomplete.

'cube'($x) is valid PHP, but not really a good way to call a function in PHP. (It's also really scary that it even works.)

By using call_user_func, you can successfully apply any callable

function sum($term, $a, $next, $b) {
  if ($a > $b)
    return 0;
  else
    return call_user_func($term, $a)
      + sum($term, call_user_func($next, $a), $b);
}
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • why is not a good way?'cube'($x) sounds like [Variable functions](http://php.net/manual/en/functions.variable-functions.php) . I know the call_user_func,but it's more ugly than my way,and it is hard to read. – Shadow C Mar 10 '16 at 10:09
  • @ShadowC because it allows for any [callable](http://php.net/manual/en/language.types.callable.php) to be called. For example, if you had `Math::square` you could pass `['Math', 'square']` and it would still work, whereas 'Math::square' will not. "it's more ugly ..." is not a valid argument. I mean, I agree with you, PHP is anything but pretty. It just is what it is. – Mulan Mar 10 '16 at 10:12
  • i don't understand your example clearly,can't you make another example?thank you ^-^ – Shadow C Mar 10 '16 at 10:21