[Python-ideas] Inline Functions - idea

Ed Kellett edk141 at gmail.com
Wed Feb 5 21:45:13 CET 2014


On 5 February 2014 18:38, yoav glazner <yoavglazner at gmail.com> wrote:
>
> How about:
>
> Def somefun():
>   a = 5
>   b = 7
>   return fmt('{a} is not {b}')
>
> inline def fmt(fmtstr):
>   return fmtstr.format_map(locals())
>

I wrote a tiny module that did almost exactly what you've just described
using stack inspection. I hardly ever use it - not because it's too hacky
(although it is) - it's just not something I commonly need to do. Format
strings are about the only case I can think of where this makes sense,
and since I've had the option to do it, I haven't found it useful.

When I wrote the module I ran into a slight problem with closures. Given:

    def foo():
        a = 5
        b = 7
        def bar():
            return fmt('{a} is not {b}')
        return bar()

    print foo()

you'll an error. bar() doesn't refer to 'a' anywhere, so it's not closed
over and not accessible from bar's scope. This will be a problem with
inline functions too; closures will need to refer to *everything* in
their enclosing scope, in case it calls an inline function at some point
during its life. Maybe that's not a problem, but having looked at a few
bits and pieces using closures that I've written recently, I'm concerned
that a significant amount of garbage would end up sticking around in
memory for a long time.


On 5 February 2014 19:48, Alex Rodrigues <lemiant at hotmail.com> wrote:
> Use an inline def - This is very modular and maintainable with an absolute
> minimum of boilerplate. The main downside being that it is not explicit what
> is available in the namespace once you initialize the simulation.
>

I think the existence of inline functions would significantly diminish
maintainability. If you do:

    a = 4
    b = frobnicate("xyz")

you have a pretty good idea of the value of 'a' after the call to
frobnicate(). If frobnicate's an inline function, who knows what a might
be? Maybe frobnicate() deliberately sets it to something, or accidentally
leaks a temporary variable named 'a' into the calling scope.


One solution to both problems might be a new operator for inline function
calls - closures wouldn't need to be bloaty unless they included at least
one such operation, and it would be immediately obvious to a maintainer
that they couldn't make any assumptions about the state of the namespace
where it appeared.

On 5 February 2014 19:48, Alex Rodrigues <lemiant at hotmail.com> wrote:
> I'm not under any illusions about how hard it is to actually get something
> added to standard python . But I thought this would be a fun and informative
> undertaking that possibly even helps people. Thank you for your kind words.
> After some consideration I have come up with another use case that
> demonstrates a little more of how this might be useful:
> Let's say that I am a weather forecaster and I maintain a large library of
> different simulation techniques. All the techniques need to get their
> initial data from some database. Let's take a look at some way of writing
> this code and their advantages/disadvantages:
>
> Hard code the startup code into each simulation - This works, but it will
> lead to lots of code re-use and all the problems that come with that (i.e.
> if I later need to change how the startup values are downloaded, now I have
> to change every single function)
> Use a closure - This isn't really an option, both because there are multiple
> functions and because closure cannot create variables in their containing
> scope
> Return the values from a function - This will add lots of unnecessary typing
> at the top of each function to list out all of the variables and if I wish
> to add a new input to one simulation (maybe UV just became important) I must
> now modify all of the functions to have that value passed in.
> Classes - This is probably the best option currently available. Make a
> simulation class that has a initialize function and have each simulation
> inherit from it. This also has some drawbacks though, since I must now
> instantiate a copy of the object to find the output of the simulation, which
> makes calling the function harder (especially on a one time basis).
> Use an inline def - This is very modular and maintainable with an absolute
> minimum of boilerplate. The main downside being that it is not explicit what
> is available in the namespace once you initialize the simulation.
>
> Here's how it might look:
>
> inline def start_simulation():
>     date = datetime.utcnow()
>     date.replace(tzinfo=utc)
>     start_data =
> urllib2.urlopen('http://www.source.com/seed_sims').read().split()
>     num_clouds = int(start_data[0])
>     temp = float(start_data[1])
>     grid = []
>     for a in range(int(start_data[2])):
>         grid.append([])
>         for b in range(int(start_data[3])):
>             grid[a].append(0)
>
> def sim_basic():
>     start_simulation()
>     return temp
>
> def sim_iterative():
>     start_simulation()
>     for row in grid:
>         for cell in row:
>             cell = temp+random.random()
>     for i in range(10):
>         for row in grid
>             for cell in row:
>                 cell += random.random()-0.5
>     return average([cell for row in grid for cell in row])
>
> def sim_clouds():
>     start_simulation()
>     return temp - numclouds/10.
>
>
>> Date: Wed, 5 Feb 2014 08:57:35 -0700
>> Subject: Re: [Python-ideas] Inline Functions - idea
>> From: ericsnowcurrently at gmail.com
>> To: lemiant at hotmail.com
>> CC: python-ideas at python.org
>
>>
>> On Feb 5, 2014 7:34 AM, "Alex Rodrigues" <lemiant at hotmail.com> wrote:
>> >
>> > Hi everyone,
>> >
>> > This is my first time on the Python mailing lists.
>>
>> Welcome!
>>
>> > I've been learning a lot about how python is run recently and today I
>> > thought I ran across an idea which might create in interesting discussion.
>> > Today I was writing a piece of software where I had a block of code that
>> > would take a bunch of local variables, apply some transformations to them
>> > and then output them as a a string to a log. Then I realized that I actually
>> > wanted to reuse this code in multiple locations - there were multiple cases
>> > where I might need to do this. My natural inclination was to write a
>> > function in order to maintain DRY programming. This was prohibitively
>> > challenging, however, since the code itself interacted with lots of
>> > variables in the namespace. The number of arguments to the function would
>> > have to be very large and possibly would change on a fairly regular basis.
>> > This seems like a fairly common problem in programming, having a piece
>> > of code which is both reused and heavily integrated with the namespace
>> > making it necessary to use copy-paste. As a solution to this I propose the
>> > idea of an inline function. An inline function would run in it's parent's
>> > namespace instead of creating a new one.
>>
>> This sounds like one aspect of Ruby's blocks. Nick Coghlan (one of
>> the more active Python committers) wrote up a nice block post that
>> describes them:
>>
>>
>> http://www.curiousefficiency.org/posts/2011/10/correcting-ignorance-learning-bit-about.html
>>
>> > What do you think?
>>
>> You've described an interesting idea. I think Paul is right that it's
>> a bit of a code smell that the function is so complex as to make
>> "inlining" desirable. Yet, it seems like there is a practical idea
>> hiding in there. Keep at the core idea and see if anything more
>> focused, including a better use case, pops out.
>>
>> To be honest the end result will likely be no changes to Python (see
>> this list's archives and the list of deferred/rejected PEPs).
>> However, you and others will probably learn a thing or two in the
>> process. Unlike some traffic on this list, your idea and the
>> discussion of it are well within the realm of not wasting people's
>> time.
>>
>> -eric
>>
>>
>> [1] Though not exactly applicable to your "inline" functions, aother
>> Ruby blocks-like idea is statement local namespaces. See PEPs 403 and
>> 3150 (at http://www.python.org/dev/peps/).
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/


More information about the Python-ideas mailing list