Fortran (Was: The "does Python have variables?" debate)

Steven D'Aprano steve at pearwood.info
Tue May 13 05:34:48 EDT 2014


On Tue, 13 May 2014 15:56:50 +1000, Chris Angelico wrote:

> On Tue, May 13, 2014 at 3:48 PM, Steven D'Aprano <steve at pearwood.info>
> wrote:
>> Self-modifying code is a nightmare inside the head of a Lovecraftian
>> horror. There's a reason why almost the only people still using self-
>> modifying code are virus writers, and the viruses they create are
>> notorious for being buggy.
> 
> Hmm... what counts as self-modifying, though? 

Code that modifies itself, as opposed to code that modifies other code.


> When you decorate a
> function to modify its behaviour (eg add caching around it), all the
> modification happens at compile time, 

Not in Python it doesn't. Functions are created at runtime -- def is a 
statement, and it runs at runtime. But that's actually irrelevant.


> but it's still executing something
> other than what you see as the bald code. 

I don't think so. Whether I write:

@cache
def function(args):
    ...


or even the old pre-decorator style:

def function(args):
    ...

function = cache(function)


there's no *self-modification* going on. The trickiest thing about this 
is that the code for function is now split over two places, cache and 
function itself. But that's not much trickier than:

def cache(x):
    ...

def function(x):
    cache(x)
    ...

or similar. You can write obfuscated code with decorators, but you can 
shoot yourself in the foot with just about any tool. Fundamentally, 
decorators are more or less just a way of doing function composition.


> What about a microkernel that
> can load altered code from the disk, compile it into memory, and replace
> portions of itself? 

Now we're talking self-modification. But of course there are degrees of 
self-modification. This isn't too bad, because it's relatively simple to 
follow what happens next:

def foo(x):
    global foo  # Change me.
    foo = new_foo
    return bar(x)

This is to self-modifying code what break and continue are to GOTO -- 
tamed, trained, on a leash, and pretty safe.



> I've done that a number of times (not in Python as
> it has little support for it, but in Pike it's easy); is that
> self-modifying code? 

Yes.


> Or a JIT compiler. As you run something, it gets
> changed in form to be more streamlined. 

I wouldn't call that self-modifying code, because the compiler isn't 
modifying itself. It's modifying the code being run.

But note that JIT compilers are optimizing compilers (there's little 
point, otherwise), and highly optimized code is notorious for being hard 
to debug and containing subtle, hard to find, harder to fix, bugs. Why 
are they hard to debug? Because the code that you read is not necessarily 
the same as the code being run.


> None of these is as horrible as
> the loop that fiddles with its own code on the fly, but any of them, if
> buggy, will have the same effect. And all are useful.

Many things are potentially useful, nevertheless we mostly avoid them 
because the cost is greater than the benefit.



-- 
Steven



More information about the Python-list mailing list