|Ned Batchelder : Blog | Code | Text | Site|
» Home : Blog
> ['10', '10', '10', '10', '10'].map(parseInt)
parseInt('10', 0, ['10', '10', '10', '10', '10'])
Working in more than one language, it's frustrating dealing with their differences. New Python learners chafe at the fact that Python names work differently than C variables. They want to know if function arguments are call by value or call by reference (neither). I saw a person on IRC once who was upset that Python lists were called lists instead of arrays.
Languages are different, that's why we have more than one of them. Language designers have to strike a balance between familiarity and innovation. We'd be pretty suprised by a language that used something other than "+" for adding numbers together, for example. Eventually though, the new language will diverge from the old, or what was the point?
This isn't to say that all languages are equal, there are better and worse, of course. But too often I hear people ranting about a language being stupid for some decision, without bothering to find out why it was done that way, and what benefit they might get from it.
To which, I say: WAT!?
I started a new side project this month, called Byterun. It's a pure-Python implementation of Python bytecode execution. That is, it runs Python bytecode.
I did it because Coverage.py has some bugs in its branch coverage. It analyzes your program for potential branches by reading the bytecode rather than the source, and I think some of the bugs are due to subtle misunderstandings on my part about how Python bytecode works.
So I figured if I could have a working implementation of bytecode in Python, it would be a good way to be sure I understood how they work. I found a ten-year-old implementation called pyvm2.py by Paul Swartz, and started refurbishing it, fixing bugs, adding missing opcodes, and bringing it up to 2.7 and 3.3.
It isn't finished yet, and supporting Python 2 and Python 3 might be a bit difficult, but already it has helped me understand a few things better, such as how generators are suspended and resumed: when the generator function yields, instead of discarding the stack frame as a normal function's return does, the frame object is held by the generator object, so the next time a value is needed, the frame can be resumed just where it was.
Closure cells make more sense now too, and I know how to create them by hand. I was creating Python function objects with types.FunctionType. But one of its arguments is "closure", which must be a tuple of cell objects. The types module has ways of making functions, generators, classes, and so on, but has no way to make a cell.
Turns out you can do it by creating a closure and grabbing its cells:
A fine bit of Python haiku there...
Coverage.py version 3.6 is ready. It has a few new features since 3.5.3:
There have also been more than 20 bugs fixed, take a look at the change history for details.
I heartily recommend that everyone upgrade to coverage.py 3.6 right away. Happy New Year!
In the decade I've been running this blog, I've accumulated 30 or so draft posts. I'm sick of looking at them, so I'm getting rid of them. Here are a few links in those drafts that still seemed interesting:
Wrapping up vacation time today, getting ready for the year ahead. The food project over the last few days, mostly captained by Max and his girlfriend Marie, was a gingerbread "house". It's actually Castle Black from Game of Thrones, a major interest in the family these days.
Castle Black is a rough castle built at the foot of a massive wall meant to keep the primitives to the north from coming south. It's situated in a harsh icy environment:
This is a pretty involved construction, we quintupled the gingerbread recipe. And there are plenty of details, like the chocolate elevator running on graham cracker rails, and a pretzel stick portcullis. The castle is manned by gummy bears with chocolate chip hats to keep them warm.
There was a phase after it was built where it had only minimal icing and no candy, for a more realistic bleak look, but everyone knows the eating phase is better with icing and candy, so it was soon festooned as you see here.
The key transition was when Max was applying M+M's to the roof, and I asked what they were meant to represent, and he smirked and said, "it's candy on gingerbread!"