Looking for the best way to translate an idiom

Discussion in 'Python' started by Paul Moore, Dec 14, 2008.

  1. Paul  Moore

    Paul Moore Guest

    I'm translating some code from another language (Lua) which has
    multiple function return values. So, In Lua, it's possible to define a
    function

    function f()
    return 1,2,3
    end

    which returns 3 values. These can then be used/assigned by the caller:

    a,b,c = f()

    So far, much like Python, but the key difference is that in Lua,
    excess arguments are ignored - so you can do

    a = f()
    or even
    a = f() + 1

    where in the latter, a is 2 (as addition only needs 1 argument, so the
    extra ones are discarded).

    This results in the code which I'm trying to translate having
    functions which return multiple arguments, the first of which is the
    "main" result, and the following values are "extra" results
    (specifically, the position at which a match is found, followed by the
    "captured" values of the match).

    I'm trying to find a natural equivalent in Python. So far, I've
    considered the following:

    - return a tuple (pos, captures). This is messy, because you end up
    far too often unpacking the tuple and throwing away the second value
    - return an object with pos and captures attributes. This is better,
    as you can do match(...).pos to get the position alone, but it doesn't
    really feel "pythonic" (all those calls with .pos at the end...)
    - have 2 calls, one to return just the position, one to return both.
    This feels awkward, because of the 2 method names to remember.

    To make things worse, Lua indexes strings from 1, so it can use a
    position of 0 to mean "no match" - so that a simple "did it match?"
    test looks like if (match(....))... - where in Python I need if
    (matchpos(...) != -1)... (Although if I return a match object, I can
    override __nonzero__ to allow me to use the simpler Lua form).

    Can anyone suggest a good idiom for this situation? At the moment, I'm
    returning a match object (the second option) which seems like the
    least bad of the choices (and it mirrors how the re module works,
    which is somewhat useful). But I'd like to know what others think. If
    you were using a pattern matching library, what interface would you
    prefer?

    I suspect my intuition isn't accurate here, as most of the use I've
    made of the library is in writing tests, which isn't typical use :-(

    Thanks for any assistance.

    Paul
     
    Paul Moore, Dec 14, 2008
    #1
    1. Advertising

  2. Paul Moore a écrit :
    > I'm translating some code from another language (Lua) which has
    > multiple function return values. So, In Lua, it's possible to define a
    > function
    >
    > function f()
    > return 1,2,3
    > end
    >
    > which returns 3 values. These can then be used/assigned by the caller:
    >
    > a,b,c = f()
    >
    > So far, much like Python, but the key difference is that in Lua,
    > excess arguments are ignored - so you can do
    >
    > a = f()
    > or even
    > a = f() + 1
    >
    > where in the latter, a is 2 (as addition only needs 1 argument, so the
    > extra ones are discarded).
    >
    > This results in the code which I'm trying to translate having
    > functions which return multiple arguments, the first of which is the
    > "main" result, and the following values are "extra" results
    > (specifically, the position at which a match is found, followed by the
    > "captured" values of the match).
    >
    > I'm trying to find a natural equivalent in Python. So far, I've
    > considered the following:
    >
    > - return a tuple (pos, captures). This is messy, because you end up
    > far too often unpacking the tuple and throwing away the second value


    if you only want the first returned value, you can just apply a slice:

    def f():
    return 1,2,3

    a = f()[0] + 1

    > - return an object with pos and captures attributes. This is better,
    > as you can do match(...).pos to get the position alone, but it doesn't
    > really feel "pythonic" (all those calls with .pos at the end...)


    FWIW, Python 2.6 has NamedTuple objects...

    > - have 2 calls, one to return just the position, one to return both.
    > This feels awkward, because of the 2 method names to remember.


    You forgot one solution: passing a flag to the function to specify if
    you want only the main result or the extra ones as well, and give this
    flag the appropriate default value depending on most common use case.

    > To make things worse, Lua indexes strings from 1, so it can use a
    > position of 0 to mean "no match" - so that a simple "did it match?"
    > test looks like if (match(....))... - where in Python I need if
    > (matchpos(...) != -1)... (Although if I return a match object, I can
    > override __nonzero__ to allow me to use the simpler Lua form).
    >
    > Can anyone suggest a good idiom for this situation? At the moment, I'm
    > returning a match object (the second option) which seems like the
    > least bad of the choices (and it mirrors how the re module works,
    > which is somewhat useful). But I'd like to know what others think. If
    > you were using a pattern matching library, what interface would you
    > prefer?


    The one that happens to be the most simple for the most common usecase,
    while still providing support for more advanced stuff.

    > I suspect my intuition isn't accurate here, as most of the use I've
    > made of the library is in writing tests, which isn't typical use :-(


    So perhaps you should start writing some real-life code ?

    > Thanks for any assistance.


    Not sure I've been that helpful. Sorry...
     
    Bruno Desthuilliers, Dec 14, 2008
    #2
    1. Advertising

  3. Paul  Moore

    Paul Moore Guest

    On 14 Dec, 16:22, Bruno Desthuilliers
    <> wrote:
    > if you only want the first returned value, you can just apply a slice:
    >
    > def f():
    >     return 1,2,3
    >
    > a = f()[0] + 1


    Hmm, true. I'm not sure it's any less ugly, though :)

    > FWIW, Python 2.6 has NamedTuple objects...


    I know, but I want to target 2.5+ (I still have a number of systems
    running 2.5)

    > > - have 2 calls, one to return just the position, one to return both.
    > > This feels awkward, because of the 2 method names to remember.

    >
    > You forgot one solution: passing a flag to the function to specify if
    > you want only the main result or the extra ones as well, and give this
    > flag the appropriate default value depending on most common use case.


    True, that's another option. It might work, I'll think about it.

    > The one that happens to be the most simple for the most common usecase,
    > while still providing support for more advanced stuff.


    Exactly. I'll have to think some more about real use cases.

    > > I suspect my intuition isn't accurate here, as most of the use I've
    > > made of the library is in writing tests, which isn't typical use :-(

    >
    > So perhaps you should start writing some real-life code ?


    :) Once I have a library that's functional enough to do so, I may
    well. Chicken and egg situation, to some extent... And I don't really
    feel like switching to Lua just to get a feel for how the library gets
    used!

    > > Thanks for any assistance.

    >
    > Not sure I've been that helpful. Sorry...


    Any feedback helps. Thanks for taking the time.

    Paul.
     
    Paul Moore, Dec 14, 2008
    #3
  4. Paul  Moore

    Steve Holden Guest

    Bruno Desthuilliers wrote:
    [...]
    > if you only want the first returned value, you can just apply a slice:
    >
    > def f():
    > return 1,2,3
    >
    > a = f()[0] + 1
    >

    <nit>That isn't a slice, it's indexing</nit>

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    Holden Web LLC http://www.holdenweb.com/
     
    Steve Holden, Dec 14, 2008
    #4
  5. Steve Holden a écrit :
    > Bruno Desthuilliers wrote:
    > [...]
    >> if you only want the first returned value, you can just apply a slice:
    >>
    >> def f():
    >> return 1,2,3
    >>
    >> a = f()[0] + 1
    >>

    > <nit>That isn't a slice, it's indexing</nit>


    Yeps, sorry - and thanks for the correction.
     
    Bruno Desthuilliers, Dec 14, 2008
    #5
  6. Paul  Moore

    Fuzzyman Guest

    On Dec 14, 5:51 pm, Paul Moore <> wrote:
    > On 14 Dec, 16:22, Bruno Desthuilliers
    >
    > <> wrote:
    > > if you only want the first returned value, you can just apply a slice:

    >
    > > def f():
    > >     return 1,2,3

    >
    > > a = f()[0] + 1

    >
    > Hmm, true. I'm not sure it's any less ugly, though :)
    >
    > > FWIW, Python 2.6 has NamedTuple objects...

    >
    > I know, but I want to target 2.5+ (I still have a number of systems
    > running 2.5)
    >


    There is a Python implementation of NamedTuple on the Python cookbook
    that is compatible with Python 2.5.

    Michael Foord
    http://www.ironpythoninaction.com/
     
    Fuzzyman, Dec 14, 2008
    #6
  7. Paul  Moore

    James Stroud Guest

    Paul Moore wrote:
    > I'm translating some code from another language (Lua) which has
    > multiple function return values. So, In Lua, it's possible to define a
    > function
    >
    > function f()
    > return 1,2,3
    > end
    >
    > which returns 3 values. These can then be used/assigned by the caller:
    >
    > a,b,c = f()
    >
    > So far, much like Python, but the key difference is that in Lua,
    > excess arguments are ignored - so you can do


    py> class mytuple(tuple):
    def magic(self, astr):
    names = astr.split()
    for name, val in zip(names, self):
    globals()[name] = val
    ....
    py> t = mytuple((1,2,3))
    py> t.magic('a b')
    py> a
    1
    py> b
    2

    James
     
    James Stroud, Dec 14, 2008
    #7
  8. Paul  Moore

    James Stroud Guest

    James Stroud wrote:
    > py> class mytuple(tuple):
    > def magic(self, astr):
    > names = astr.split()
    > for name, val in zip(names, self):
    > globals()[name] = val
    > ...
    > py> t = mytuple((1,2,3))
    > py> t.magic('a b')
    > py> a
    > 1
    > py> b
    > 2
    >
    > James



    In case its not obvious:

    def f():
    return mytuple((1,2,3))

    f().magic('a b')

    You can parameterize lobbing off values, or use more magic:

    py> class mytuple(tuple):
    .... def magic(self, astr):
    .... names = astr.split()
    .... for name, val in zip(names, self):
    .... globals()[name] = val
    .... def __add__(self, other):
    .... if isinstance(other, tuple):
    .... return mytuple(tuple.__add__(self, other))
    .... else:
    .... return mytuple(self[other:])
    ....
    py> t = mytuple((1,2,3))
    py> t + 1
    (2, 3)
    py> def f():
    return mytuple((1,2,3))
    ....
    py> (f() + 1).magic('a b')
    py> a
    2
    py> b
    3

    It's not as bad as a lot of the cynics are about to tell you it is. If
    it has any badness at all, it's because of the need (according to what I
    infer from your specification) to use the global namespace. If you want
    to modify a "more local" namespace, you can use some stack frame
    inspection to do some real magic:

    py> import inspect
    py> class mytuple(tuple):
    def magic(self, astr):
    names = astr.split()
    for name, val in zip(names, self):
    inspect.stack()[1][0].f_locals[name] = val
    def __add__(self, other):
    if isinstance(other, tuple):
    return mytuple(tuple.__add__(self, other))
    else:
    return mytuple(self[other:])
    ....
    py> def f():
    return mytuple((6,7,8))
    ....
    py> (f() + 1).magic('a b')
    py> a
    7
    py> b
    8

    James
     
    James Stroud, Dec 15, 2008
    #8
  9. Paul  Moore

    Guest

    On Dec 14, 11:19 am, Paul Moore <> wrote:
    > I'm translating some code from another language (Lua) which has
    > multiple function return values. So, In Lua, it's possible to define a
    > function
    >
    >     function f()
    >         return 1,2,3
    >     end
    >
    > which returns 3 values. These can then be used/assigned by the caller:
    >
    >     a,b,c = f()
    >
    > So far, much like Python, but the key difference is that in Lua,
    > excess arguments are ignored - so you can do
    >
    >     a = f()
    > or even
    >     a = f() + 1
    >
    > where in the latter, a is 2 (as addition only needs 1 argument, so the
    > extra ones are discarded).
    >
    > This results in the code which I'm trying to translate having
    > functions which return multiple arguments, the first of which is the
    > "main" result, and the following values are "extra" results
    > (specifically, the position at which a match is found, followed by the
    > "captured" values of the match).
    >
    > I'm trying to find a natural equivalent in Python. So far, I've
    > considered the following:
    >
    > - return a tuple (pos, captures). This is messy, because you end up
    > far too often unpacking the tuple and throwing away the second value
    > - return an object with pos and captures attributes. This is better,
    > as you can do match(...).pos to get the position alone, but it doesn't
    > really feel "pythonic" (all those calls with .pos at the end...)
    > - have 2 calls, one to return just the position, one to return both.
    > This feels awkward, because of the 2 method names to remember.
    >
    > To make things worse, Lua indexes strings from 1, so it can use a
    > position of 0 to mean "no match" - so that a simple "did it match?"
    > test looks like if (match(....))... - where in Python I need if
    > (matchpos(...) != -1)... (Although if I return a match object, I can
    > override __nonzero__ to allow me to use the simpler Lua form).
    >
    > Can anyone suggest a good idiom for this situation? At the moment, I'm
    > returning a match object (the second option) which seems like the
    > least bad of the choices (and it mirrors how the re module works,
    > which is somewhat useful). But I'd like to know what others think. If
    > you were using a pattern matching library, what interface would you
    > prefer?
    >
    > I suspect my intuition isn't accurate here, as most of the use I've
    > made of the library is in writing tests, which isn't typical use :-(
    >
    > Thanks for any assistance.
    >
    > Paul


    I'm baffled by this discussion.
    What's wrong with
    a, dontcare, dontcare2 = f()
    a = a + 1

    Simple, clear, and correct.
     
    , Dec 15, 2008
    #9
  10. Paul  Moore

    James Stroud Guest

    wrote:
    >
    > I'm baffled by this discussion.
    > What's wrong with
    > a, dontcare, dontcare2 = f()
    > a = a + 1
    >
    > Simple, clear, and correct.


    1. This can't apply to a generalized f() that may return an arbitrary
    number of arguments >= len(num_assignments_you_care_about).
    2. The example chosen was misleading. You don't want to add 1 to the
    first element of the tuple, you want to move the "start" of the returned
    tuple up 1 and start assignment on the left from there.

    James
     
    James Stroud, Dec 15, 2008
    #10
  11. Paul  Moore

    James Stroud Guest

    James Stroud wrote:
    > inspect.stack()[1][0].f_locals[name] = val


    I just double checked this. Because of the way locals are implemented in
    cPython, this won't have the desired affect.

    James
     
    James Stroud, Dec 15, 2008
    #11
  12. Paul  Moore

    Aahz Guest

    In article <gi4834$lap$>,
    James Stroud <> wrote:
    >
    >In case its not obvious:


    Ah, so that's where Bruno's extra apostrophe came from! ;-)


    (Sorry about the spelling flame, but seeing three posts in quick
    succession with incorrect spelling of its/it's pushed me into making a
    public comment.)
    --
    Aahz () <*> http://www.pythoncraft.com/

    "It is easier to optimize correct code than to correct optimized code."
    --Bill Harlan
     
    Aahz, Dec 15, 2008
    #12
  13. Paul  Moore

    James Stroud Guest

    Aahz wrote:
    > In article <gi4834$lap$>,
    > James Stroud <> wrote:
    >> In case its not obvious:

    >
    > Ah, so that's where Bruno's extra apostrophe came from! ;-)
    >
    >
    > (Sorry about the spelling flame, but seeing three posts in quick
    > succession with incorrect spelling of its/it's pushed me into making a
    > public comment.)


    Yes. I think it was the British who decided that the apostrophe rule for
    "it" would be reversed from normal usage relative to just about every
    other noun. I'm not sure the purpose--maybe it was to give compulsive
    proofreaders a raison d'etre.
     
    James Stroud, Dec 15, 2008
    #13
  14. Paul  Moore

    I V Guest

    On Sun, 14 Dec 2008 21:08:33 -0800, James Stroud wrote:
    > Yes. I think it was the British who decided that the apostrophe rule for
    > "it" would be reversed from normal usage relative to just about every
    > other noun. I'm not sure the purpose--maybe it was to give compulsive
    > proofreaders a raison d'etre.


    It's because "it" is a pronoun; you don't put an apostrophe in "his,"
    either.
     
    I V, Dec 15, 2008
    #14
  15. Paul  Moore

    James Stroud Guest

    Re: alt.possessive.its.has.no.apostrophe

    Ben Finney wrote:
    > James Stroud <> writes:
    >
    >> Yes. I think it was the British who decided that the apostrophe rule
    >> for "it" would be reversed from normal usage relative to just about
    >> every other noun.

    >
    > Remember that “it†is a pronoun. I see no reversal:


    Ok. Pronouns are reversed.

    Bob's
    Its
     
    James Stroud, Dec 15, 2008
    #15
  16. Paul  Moore

    James Stroud Guest

    I V wrote:
    > On Sun, 14 Dec 2008 21:08:33 -0800, James Stroud wrote:
    >> Yes. I think it was the British who decided that the apostrophe rule for
    >> "it" would be reversed from normal usage relative to just about every
    >> other noun. I'm not sure the purpose--maybe it was to give compulsive
    >> proofreaders a raison d'etre.

    >
    > It's because "it" is a pronoun; you don't put an apostrophe in "his,"
    > either.


    Its called humor.
     
    James Stroud, Dec 15, 2008
    #16
  17. Aahz a écrit :
    > In article <gi4834$lap$>,
    > James Stroud <> wrote:
    >> In case its not obvious:

    >
    > Ah, so that's where Bruno's extra apostrophe came from! ;-)


    Err... Which one exactly ?

    >
    > (Sorry about the spelling flame, but seeing three posts in quick
    > succession with incorrect spelling of its/it's pushed me into making a
    > public comment.)
     
    Bruno Desthuilliers, Dec 15, 2008
    #17
  18. Paul  Moore

    James Stroud Guest

    Re: alt.possessive.its.has.no.apostrophe

    Ben Finney wrote:
    > James Stroud <> writes:
    >
    >> Ben Finney wrote:
    >>> James Stroud <> writes:
    >>>
    >>>> Yes. I think it was the British who decided that the apostrophe
    >>>> rule for "it" would be reversed from normal usage relative to
    >>>> just about every other noun.

    >
    > It also seems an indefensible claim to say that anyone “decided†it
    > would be that way, especially “the Britishâ€.
    >
    >>> Remember that “it†is a pronoun. I see no reversal:

    >> Ok. Pronouns are reversed.

    >
    > Or, more generally: Pronouns, which are different in just about every
    > other way from other nouns, are different in this way also. Is that
    > about right?
    >


    Can we start talking about python again?

    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095

    http://www.jamesstroud.com
     
    James Stroud, Dec 15, 2008
    #18
  19. Paul  Moore

    MRAB Guest

    James Stroud wrote:
    > Aahz wrote:
    >> In article <gi4834$lap$>,
    >> James Stroud <> wrote:
    >>> In case its not obvious:

    >>
    >> Ah, so that's where Bruno's extra apostrophe came from! ;-)
    >>
    >>
    >> (Sorry about the spelling flame, but seeing three posts in quick
    >> succession with incorrect spelling of its/it's pushed me into making a
    >> public comment.)

    >
    > Yes. I think it was the British who decided that the apostrophe rule for
    > "it" would be reversed from normal usage relative to just about every
    > other noun. I'm not sure the purpose--maybe it was to give compulsive
    > proofreaders a raison d'etre.
    >

    No possessive pronoun has an apostrophe.

    Contractions of "is", etc, do, whether for nouns or pronouns.
     
    MRAB, Dec 15, 2008
    #19
  20. Paul  Moore

    Aahz Guest

    In article <494611c2$0$21934$>,
    Bruno Desthuilliers <> wrote:
    >Aahz a écrit :
    >> In article <gi4834$lap$>,
    >> James Stroud <> wrote:
    >>>
    >>> In case its not obvious:

    >>
    >> Ah, so that's where Bruno's extra apostrophe came from! ;-)

    >
    >Err... Which one exactly ?


    Don't remember, it was a post I read about five minutes earlier that had
    something like, "...has it's place..."
    --
    Aahz () <*> http://www.pythoncraft.com/

    "It is easier to optimize correct code than to correct optimized code."
    --Bill Harlan
     
    Aahz, Dec 15, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Connett

    Best pattern/idiom

    Chris Connett, Aug 9, 2004, in forum: Python
    Replies:
    7
    Views:
    311
    Austyn Bontrager
    Aug 16, 2004
  2. Guest
    Replies:
    2
    Views:
    347
    Guest
    Aug 17, 2007
  3. ram
    Replies:
    2
    Views:
    426
    Duncan Booth
    Dec 18, 2007
  4. Replies:
    1
    Views:
    256
    Fredrik Lundh
    Aug 26, 2008
  5. Johannes Bauer

    Looking for right idiom

    Johannes Bauer, Aug 23, 2012, in forum: C++
    Replies:
    8
    Views:
    358
    Jorgen Grahn
    Aug 24, 2012
Loading...

Share This Page