learning from https://github.com/huangz1990/SICP-answers and http://sicp.readthedocs.org/en/latest/