6 ms·
SICP is about deeply understanding computation. Scheme is a good language for SICP because it's simple. You can build a Scheme interpreter as a class project.
by woofie11 7y ago
SICP is about deeply understanding computation.
Scheme is a good language for SICP because it's simple. You can build a Scheme interpreter as a class project. You can analyze it formally. Etc.
Python is a good language because it's readable and writeable. But it doesn't work for SICP since it's too complex for that. Python also intentionally omits things critical to SICP (like tail recursion).
Calling this book "SICP in Python" would be like taking your favorite poem, releasing it into a different language, and finding that the translators wrote a completely different book, with a different theme, to make it rhyme and the rhythm hold. Just something different with the same name.
- wolfgke 7y ago> Python is a good language because it's readable and writeable. https://github.com/satwikkansal/wtfpython https://github.com/satwikkansal/wtfpython
- deleted 7y ago[deleted]
- theamk 7y agoYep, python is probably one of the most human-readable and writable languages out there. There are some dark corners, like the site above illustrates, but it is pretty easy to avoid them. (It is still not the good fit for SICP, but that’s a different conversation)
- kazinator 6y agoYou can only avoid dark corners as a writer. As a reader, you may have to peer into dark corners. Most of the issues given on the linked-to page are not simple issues of readability; they are real pitfalls. A lot of the examples are actually readable. You will not easily avoid every single one of those pitfalls if you're coding in Python, even if you lint the code.
- kazinator 6y agoPython contains semantic cluster-fumbles. For instance: def fun(listarg = []) listlocal = [] listarg.append(3) listlocal.append(3) It turns out listarg is bound to a list which is not freshly instantiated each time the function is called (with no corresponding argument), unlike listlocal. The expression is evaluated at the time the function is defined, not at call time. The value is stashed somewhere and that value is used for initializing listarg by default. I learned about this from ... running pylint3 on some code which found a buggy use of such a list. This is probably that way for performance because Python doesn't have true literals. [1] is more like (list 1) in Lisp; it's a constructor that has to be executed, producing a newly allocated object; it is not like '(1) which is just a literal object that can be embedded into the compiled program image. Python literature incorrectly refers to [] as a literal, which is bad education: a disservice to newbies who deserve to understand what is a literal. The fact that you can do "x = []" and then safely append to to it proves that it's not a literal, because literal is an abbreviation of "literal constant", which is also something newbies should be taught. Students of CS must absolutely learn the crucial difference between variable initialization and assignment. Python conflates the two. x = 42 def fun(): x = 43 # defines and binds local x. This was not even fixed in Python for a long time; now you can assign to the global one with a global statement. The concept is bad here and damaging to newbie brains.
- theamk 7y agoAgreed! After taking a course which used SICP, I was so inspired I wrote a functioning Scheme interpreter in a couple of evenings - in C, with no external libraries. It was pretty limited (no tail recursion), but could run examples from the book. That is not going to work with python - even just parsing the program will need a whole bunch of extra knowledge.
- StreamBright 7y agoExcept that 90% of Python programmers fail to answer simple questions like: Given: def extendList(val, list=[]): list.append(val) return list What do the following print: print(extendList(1)) print(extendList(1)) print(extendList(2)) print(extendList(3,[])) I do not blame them. This sort of behavior is error-prone. You can make sure that you do not use such a code in production with code reviews but it would be also great to not having such things in the language.
- czzr 7y agoFor what it’s worth, I’m not a Python programmer and I got that correct. The answer is: [1] [1, 1] [1, 1, 2] [3] It relies on knowing something about how python applies default arguments. I’ve only written about a hundred lines of python in my life, so possibly I just got lucky - still, I would have thought an actual Python programmer should get this?
- pstuart 7y agoTIL: https://docs.python-guide.org/writing/gotchas/ https://docs.python-guide.org/writing/gotchas/
- goatlover 7y agoIt is different from how Ruby and Javascript handle default arguments. I'm surprised Python does that, since I would expect function arguments to be reset to their defaults each call. That's a major side effect.
- kadoban 7y agoIt's pretty odd behavior, yeah. It's easy to work around (set the default to None and then set the actual default in the function body), but I don't know if I've _ever_ seen anyone want it to behave as it does now.
- nitroll 7y agoIt does make sense to evaluate the default value for the parameter at the point of definition for serveral reasons. First of all, the default value does not have to be a literal value, and if you wanted it to be evaluated at call time the function would need to capture all of the default values in a closure. default = 10 def foo(x=default): return x default = 20 assert foo() == 10 I think tat makes a lot of sense. It could also be that the default value is a more ocmplex expression, we could use a function to generate a default argument. def foo(x=create_default(y, z)) By evaluating it at definition time we only have to evaluate the expression once and not have this weird lazy expression. And yes it is used, for example the fastapi Dependency Injection system has been build quite cleverly using the ability to construct default values https://fastapi.tiangolo.com/tutorial/query-params-str-validations/ https://fastapi.tiangolo.com/tutorial/query-params-str-valid... Yes it is one of those things you just have to learn, but there are tons of stuff like that in most programming languages.