Search code examples
pythonpython-3.xschemelispsicp

Evaluation allows for combinations whose operators are compound expressions


I find the amazing power of scheme in sicp

Exercise 1.4. Observe that our model of evaluation allows for combinations whose operators are compound expressions. Use this observation to describe the behavior of the following procedure:

 #+BEGIN_SRC scheme
(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))
(a-plus-abs-b 9 4)
 #+END_SRC

 #+RESULTS:
 : 13

I try to mimic it but have no ideas how to deal with symbol operators

In [13]: 1 eval("+") 1                 
  File "<ipython-input-13-74042a5242a6>", line 1
    1 eval("+") 1
         ^
SyntaxError: invalid syntax


In [14]: 1 exec("+") 1                 
  File "<ipython-input-14-deabdb544acb>", line 1
    1 exec("+") 1
         ^
SyntaxError: invalid syntax

Is there a solution to use the symbol operator "+" directly as the scheme does?


Solution

  • In Python we can't pass + or - directly and we need to wrap them in functions, because they are operators and not procedures as in Scheme, and hence need to be treated differently by the interpreter.

    However, we can do a pretty straightforward translation of the Scheme code to Python, simply by importing the correct operators from the operator module, and invoking them as any normal function:

    from operator import add, sub
    
    def a_plus_abs_b(a, b):
        return (add if b > 0 else sub)(a, b)
    
    a_plus_abs_b(9, 4)
    => 13
    

    The operator module "exports a set of efficient functions corresponding to the intrinsic operators of Python". Another (less efficient) alternative would be to use lambda:

    my_add = lambda x, y: x + y
    my_sub = lambda x, y: x - y
    
    def a_plus_abs_b(a, b):
        return (my_add if b > 0 else my_sub)(a, b)
    
    a_plus_abs_b(9, 4)
    => 13