is implemented with id ?

Discussion in 'Python' started by Franck Ditter, Sep 5, 2012.

  1. Hi !
    a is b <==> id(a) == id(b) in builtin classes.
    Is that true ?
    Thanks,

    franck
     
    Franck Ditter, Sep 5, 2012
    #1
    1. Advertising

  2. On Tue, Sep 4, 2012 at 11:30 PM, Franck Ditter <> wrote:
    > Hi !
    > a is b <==> id(a) == id(b) in builtin classes.
    > Is that true ?
    > Thanks,
    >
    > franck


    No. It is true that if a is b then id(a) == id(b) but the reverse is
    not necessarily true. id is only guaranteed to be unique among objects
    alive at the same time. If objects are discarded, their ids may be
    reused even though the objects are not the same.
     
    Benjamin Kaplan, Sep 5, 2012
    #2
    1. Advertising

  3. On Wed, 05 Sep 2012 08:30:31 +0200, Franck Ditter wrote:

    > Hi !
    > a is b <==> id(a) == id(b) in builtin classes. Is that true ?


    Not just for builtin classes, for any objects, provided that they are
    alive at the same time.

    There is no guarantee whether IDs will be re-used. Some versions of
    Python do re-use IDs, e.g. CPython:

    steve@runes:~$ python
    Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
    [GCC 4.4.5] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> a = ["some", "object"]
    >>> id(a)

    3074285228L
    >>> del a
    >>> b = [100, 200]
    >>> id(b)

    3074285228L

    but others do not, e.g. Jython and IronPython:

    steve@runes:~$ jython
    Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19)
    [OpenJDK Client VM (Sun Microsystems Inc.)] on java1.6.0_18
    Type "help", "copyright", "credits" or "license" for more information.
    >>> a = ["some", "object"]
    >>> id(a)

    1
    >>> del a
    >>> b = [100, 200]
    >>> id(b)

    2


    steve@runes:~$ ipy
    IronPython 2.6 Beta 2 DEBUG (2.6.0.20) on .NET 2.0.50727.1433
    Type "help", "copyright", "credits" or "license" for more information.
    >>> a = ["some", "object"]
    >>> id(a)

    43
    >>> del a
    >>> b = [100, 200]
    >>> id(b)

    44


    CPython especially has the most complicated behaviour with IDs and object
    identity:

    >>> a = 99.99
    >>> b = 99.99
    >>> a is b

    False
    >>> a = 99.99; b = 99.99; a is b

    True


    In general, you almost never need to care about IDs and object identity.
    The main exception is testing for None, which should always be written as:

    if x is None


    --
    Steven
     
    Steven D'Aprano, Sep 5, 2012
    #3
  4. On Wednesday, 5 September 2012 14:44:23 UTC+5:30, Steven D'Aprano wrote:
    > On Wed, 05 Sep 2012 08:30:31 +0200, Franck Ditter wrote:
    >
    >
    >
    > > Hi !

    >
    > > a is b <==> id(a) == id(b) in builtin classes. Is that true ?

    >
    >
    >
    > Not just for builtin classes, for any objects, provided that they are
    >


    Seeing this thread, I think the is statment should be removed.
    It has a replacement syntax of id(x) == id(y) and "a==True" should be automatically changed into memory comparison.
    > alive at the same time.
    >
    >
    >
    > There is no guarantee whether IDs will be re-used. Some versions of
    >
    > Python do re-use IDs, e.g. CPython:
    >
    >
    >
    > steve@runes:~$ python
    >
    > Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
    >
    > [GCC 4.4.5] on linux2
    >
    > Type "help", "copyright", "credits" or "license" for more information.
    >
    > >>> a = ["some", "object"]

    >
    > >>> id(a)

    >
    > 3074285228L
    >
    > >>> del a

    >
    > >>> b = [100, 200]

    >
    > >>> id(b)

    >
    > 3074285228L
    >
    >
    >
    > but others do not, e.g. Jython and IronPython:
    >
    >
    >
    > steve@runes:~$ jython
    >
    > Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19)
    >
    > [OpenJDK Client VM (Sun Microsystems Inc.)] on java1.6.0_18
    >
    > Type "help", "copyright", "credits" or "license" for more information.
    >
    > >>> a = ["some", "object"]

    >
    > >>> id(a)

    >
    > 1
    >
    > >>> del a

    >
    > >>> b = [100, 200]

    >
    > >>> id(b)

    >
    > 2
    >
    >
    >
    >
    >
    > steve@runes:~$ ipy
    >
    > IronPython 2.6 Beta 2 DEBUG (2.6.0.20) on .NET 2.0.50727.1433
    >
    > Type "help", "copyright", "credits" or "license" for more information.
    >
    > >>> a = ["some", "object"]

    >
    > >>> id(a)

    >
    > 43
    >
    > >>> del a

    >
    > >>> b = [100, 200]

    >
    > >>> id(b)

    >
    > 44
    >
    >
    >
    >
    >
    > CPython especially has the most complicated behaviour with IDs and object
    >
    > identity:
    >
    >
    >
    > >>> a = 99.99

    >
    > >>> b = 99.99

    >
    > >>> a is b

    >
    > False
    >
    > >>> a = 99.99; b = 99.99; a is b

    >
    > True
    >
    >
    >
    >
    >
    > In general, you almost never need to care about IDs and object identity.
    >
    > The main exception is testing for None, which should always be written as:
    >
    >
    >
    > if x is None
    >
    >
    >
    >
    >
    > --
    >
    > Steven
     
    Ramchandra Apte, Sep 5, 2012
    #4
  5. Thanks to all, but :
    - I should have said that I work with Python 3. Does that matter ?
    - May I reformulate the queston : "a is b" and "id(a) == id(b)"
    both mean : "a et b share the same physical address". Is that True ?
    Thanks,

    franck

    In article <>,
    Benjamin Kaplan <> wrote:

    > On Tue, Sep 4, 2012 at 11:30 PM, Franck Ditter <> wrote:
    > > Hi !
    > > a is b <==> id(a) == id(b) in builtin classes.
    > > Is that true ?
    > > Thanks,
    > >
    > > franck

    >
    > No. It is true that if a is b then id(a) == id(b) but the reverse is
    > not necessarily true. id is only guaranteed to be unique among objects
    > alive at the same time. If objects are discarded, their ids may be
    > reused even though the objects are not the same.
     
    Franck Ditter, Sep 5, 2012
    #5
  6. Franck Ditter

    Dave Angel Guest

    On 09/05/2012 08:48 AM, Ramchandra Apte wrote:
    > On Wednesday, 5 September 2012 14:44:23 UTC+5:30, Steven D'Aprano wrote:
    >> <snip>
    >>

    > Seeing this thread, I think the is statment should be removed.
    > It has a replacement syntax of id(x) == id(y) and "a==True" should be automatically changed into memory comparison.


    You didn't read the whole message carefully enough. Id's can be reused,
    so there are many ways to mess up comparing id's. One is if the two
    items x and y are expressions (eg. function calls). You call a
    function, and say it returns a new object, you call id() on that object,
    and then the object gets discarded. You now have a stale id, and you
    haven't even evaluated the second expression yet.

    It's id() which is superfluous. But it's useful for debugging, and for
    understanding.



    --

    DaveA
     
    Dave Angel, Sep 5, 2012
    #6
  7. Franck Ditter

    Hans Mulder Guest

    On 5/09/12 15:19:47, Franck Ditter wrote:
    > Thanks to all, but :
    > - I should have said that I work with Python 3. Does that matter ?
    > - May I reformulate the queston : "a is b" and "id(a) == id(b)"
    > both mean : "a et b share the same physical address". Is that True ?


    Yes.

    Keep in mind, though, that in some implementation (e.g.
    Jython), the physical address may change during the life
    time of an object.

    It's usually phrased as "a and b are the same object".
    If the object is mutable, then changing a will also change b.
    If a and b aren't mutable, then it doesn't really matter
    whether they share a physical address.

    Keep in mind that physical addresses can be reused when an
    object is destroyed. For example, in my Python3,


    id(math.sqrt(17)) == id(math.cos(17))

    returns True, even though the floats involved are different,
    because the flaots have non-overlapping lifetimes and the
    physical address happens to be reused.


    Hope this helps,

    -- HansM
     
    Hans Mulder, Sep 5, 2012
    #7
  8. Franck Ditter

    Dave Angel Guest

    Please don't top-post. Now your message is out of order, and if I have
    to delete the part Benjamin said.

    On 09/05/2012 09:19 AM, Franck Ditter wrote:
    > Thanks to all, but :
    > - I should have said that I work with Python 3. Does that matter ?
    > - May I reformulate the queston : "a is b" and "id(a) == id(b)"
    > both mean : "a et b share the same physical address". Is that True ?
    > Thanks,


    No, id() has nothing to do with physical address. The Python language
    does not specify anything about physical addresses. Some
    implementations may happen to use physical addresses, others arbitrary
    integers. And they may reuse such integers, or not. Up to the
    implementation.

    And as others have pointed out, when you compare two id's, you're
    risking that one of them may no longer be valid. For example, the
    following expression:

    flag = id(func1()) == id(func2())

    could very well evaluate to True, even if func1() always returns a
    string, and func2() always returns an int. On the other hand, the 'is'
    expression makes sure the two expressions are bound to the same object.

    If a and b are simple names, and not placeholders for arbitrary
    expressions, then I THINK the following would be true:

    "a is b" and "id(a) == id(b)" both mean that the names a and b are
    bound to the same object at the time the statement is executed.

    --

    DaveA
     
    Dave Angel, Sep 5, 2012
    #8
  9. On Wed, 05 Sep 2012 05:48:26 -0700, Ramchandra Apte wrote:

    > Seeing this thread, I think the is statment should be removed. It has a
    > replacement syntax of id(x) == id(y)


    A terrible idea.

    Because "is" is a keyword, it is implemented as a fast object comparison
    directly in C (for CPython) or Java (for Jython). In the C implementation
    "x is y" is *extremely* fast because it is just a pointer comparison
    performed directly by the interpreter.

    Because id() is a function, it is much slower. And because it is not a
    keyword, Python needs to do a name look-up for it, then push the argument
    on the stack, call the function (which may not even be the built-in id()
    any more!) and then pop back to the caller.

    And worst, *it doesn't even do what you think it does*. In some Python
    implementations, IDs can be reused. That leads to code like this, from
    CPython 2.7:

    py> id("spam ham"[1:]) == id("foo bar"[1:])
    True

    You *cannot* replace is with id() except when the objects are guaranteed
    to both be alive at the same time, and even then you *shouldn't* replace
    is with id() because that is a pessimation (the opposite of an
    optimization -- something that makes code run slower, not faster).


    > and "a==True" should be automatically changed into memory comparison.


    Absolutely not. That would be a backward-incompatible change that would
    break existing programs:

    py> 1.0 == True
    True
    py> from decimal import Decimal
    py> Decimal("1.0000") == True
    True



    --
    Steven
     
    Steven D'Aprano, Sep 5, 2012
    #9
  10. On Wed, 05 Sep 2012 10:00:09 -0400, Dave Angel wrote:

    > On 09/05/2012 09:19 AM, Franck Ditter wrote:
    >> Thanks to all, but :
    >> - I should have said that I work with Python 3. Does that matter ? -
    >> May I reformulate the queston : "a is b" and "id(a) == id(b)"
    >> both mean : "a et b share the same physical address". Is that True ?
    >> Thanks,

    >
    > No, id() has nothing to do with physical address. The Python language
    > does not specify anything about physical addresses. Some
    > implementations may happen to use physical addresses, others arbitrary
    > integers. And they may reuse such integers, or not. Up to the
    > implementation.


    True. In principle, some day there might be a version of Python that runs
    on some exotic quantum computer where the very concept of "physical
    address" is meaningless. Or some sort of peptide or DNA computer, where
    the calculations are performed via molecular interactions rather than by
    flipping bits in fixed memory locations.

    But less exotically, Frank isn't entirely wrong. With current day
    computers, it is reasonable to say that any object has exactly one
    physical location at any time. In Jython, objects can move around; in
    CPython, they can't. But at any moment, any object has a specific
    location, and no other object can have that same location. Two objects
    cannot both be at the same memory address at the same time.

    So, for current day computers at least, it is reasonable to say that
    "a is b" implies that a and b are the same object at a single location.

    The second half of the question is more complex:

    "id(a) == id(b)" *only* implies that a and b are the same object at the
    same location if they exist at the same time. If they don't exist at the
    same time, then you can't conclude anything.



    --
    Steven
     
    Steven D'Aprano, Sep 5, 2012
    #10
  11. Franck Ditter

    Dave Angel Guest

    On 09/05/2012 10:41 AM, Steven D'Aprano wrote:
    > On Wed, 05 Sep 2012 10:00:09 -0400, Dave Angel wrote:
    >
    >> On 09/05/2012 09:19 AM, Franck Ditter wrote:
    >>> Thanks to all, but :
    >>> - I should have said that I work with Python 3. Does that matter ? -
    >>> May I reformulate the queston : "a is b" and "id(a) == id(b)"
    >>> both mean : "a et b share the same physical address". Is that True ?
    >>> Thanks,

    >> No, id() has nothing to do with physical address. The Python language
    >> does not specify anything about physical addresses. Some
    >> implementations may happen to use physical addresses, others arbitrary
    >> integers. And they may reuse such integers, or not. Up to the
    >> implementation.

    > True. In principle, some day there might be a version of Python that runs
    > on some exotic quantum computer where the very concept of "physical
    > address" is meaningless. Or some sort of peptide or DNA computer, where
    > the calculations are performed via molecular interactions rather than by
    > flipping bits in fixed memory locations.
    >
    > But less exotically, Frank isn't entirely wrong. With current day
    > computers, it is reasonable to say that any object has exactly one
    > physical location at any time. In Jython, objects can move around; in
    > CPython, they can't. But at any moment, any object has a specific
    > location, and no other object can have that same location. Two objects
    > cannot both be at the same memory address at the same time.
    >
    > So, for current day computers at least, it is reasonable to say that
    > "a is b" implies that a and b are the same object at a single location.


    You're arguing against something i didn't say. I only said that id()
    doesn't promise to be a memory address. i said nothing about what it
    might mean if the "is" operator considers them the same.

    > The second half of the question is more complex:
    >
    > "id(a) == id(b)" *only* implies that a and b are the same object at the
    > same location if they exist at the same time. If they don't exist at the
    > same time, then you can't conclude anything.
    >
    >

    But by claiming that id() really means address, and that those addresses
    might move during the lifetime of an object, then the fact that the id()
    functions are not called simultaneously implies that one object might
    move to where the other one used to be before the "move."

    I don't claim to know the jython implementation. But you're claiming
    that id() means the address of the object, even in jython. So if a
    garbage collection can occur during the evaluation of the expression
    id(a) == id(b)

    then the comparing of id()'s would be useless in jython. Two distinct
    objects could each be moved during evaluation, (very) coincidentally
    causing the two to have the same addresses at the two times of
    evaluation. Or more likely, a single object could move to a new
    location, rendering the comparison false. Thus you have false positive
    and false negative possible.

    I think it much more likely that jython uses integer values for the id()
    function, and not physical addresses. I doubt they'd want a race condition.


    --

    DaveA
     
    Dave Angel, Sep 5, 2012
    #11
  12. On Wed, 05 Sep 2012 11:09:30 -0400, Dave Angel wrote:

    > On 09/05/2012 10:41 AM, Steven D'Aprano wrote:

    [...]
    >> So, for current day computers at least, it is reasonable to say that "a
    >> is b" implies that a and b are the same object at a single location.

    >
    > You're arguing against something i didn't say. I only said that id()
    > doesn't promise to be a memory address. i said nothing about what it
    > might mean if the "is" operator considers them the same.


    I'm not arguing at all. I'm agreeing with you, but going into more detail.


    >> The second half of the question is more complex:
    >>
    >> "id(a) == id(b)" *only* implies that a and b are the same object at the
    >> same location if they exist at the same time. If they don't exist at
    >> the same time, then you can't conclude anything.
    >>
    >>

    > But by claiming that id() really means address,


    I didn't actually say that. If you re-read Franck Ditter's previous post,
    he doesn't actually say that either.


    > and that those addresses
    > might move during the lifetime of an object, then the fact that the id()
    > functions are not called simultaneously implies that one object might
    > move to where the other one used to be before the "move."


    Well, yes, but I expect that implementations where objects can move will
    not use memory addresses as IDs. They will do what Jython and IronPython
    do and use arbitrary numbers as IDs.

    (Oh how I wish CPython hadn't used memory addresses as IDs.)


    > I don't claim to know the jython implementation. But you're claiming
    > that id() means the address of the object, even in jython.


    Good god no! I'm saying that, *if* a and b exist at the same time, *and*
    if id(a) == id(b), *then* a and b must be the same object and therefore
    at the same address. That doesn't mean that the ID is the address!


    > I think it much more likely that jython uses integer values for the id()
    > function, and not physical addresses.


    That's exactly what it does. It appears to be a simple counter: each time
    you ask for an object's ID, it gets allocated the next value starting
    from 1, and values are never re-used.



    --
    Steven
     
    Steven D'Aprano, Sep 5, 2012
    #12
  13. Franck Ditter

    Hans Mulder Guest

    On 5/09/12 17:09:30, Dave Angel wrote:
    > But by claiming that id() really means address, and that those addresses
    > might move during the lifetime of an object, then the fact that the id()
    > functions are not called simultaneously implies that one object might
    > move to where the other one used to be before the "move."


    Whoa! Not so fast! The id() of an object is guaranteed to not
    change during the object's lifetime. So if an implementation
    moves objects around (e.g. Jython), then it cannot use memory
    addresses for the id() function.

    > I think it much more likely that jython uses integer values for
    > the id() function, and not physical addresses.


    The id() function is guaranteed to return some flavour of integer.

    In Jython, the return values are 1, 2, 3, 4, etc., except, of course,
    if you invoke id() on an object you've id'd before, you get the same
    number as before.

    In current versions of CPython, you do get the (virtual) memory
    address, converted to an int (or a long). But then, CPython does
    not move objects.

    Maybe the next version of CPython should shift id values two or three
    bits to the right, just to make sure people don't misinterpret ids as
    memory addresses.


    Hope this helps,

    -- HansM
     
    Hans Mulder, Sep 5, 2012
    #13
  14. Franck Ditter

    Ian Kelly Guest

    On Wed, Sep 5, 2012 at 8:13 AM, Steven D'Aprano
    <> wrote:
    > You *cannot* replace is with id() except when the objects are guaranteed
    > to both be alive at the same time, and even then you *shouldn't* replace
    > is with id() because that is a pessimation (the opposite of an
    > optimization -- something that makes code run slower, not faster).


    Shouldn't that be "pessimization" for symmetry?
     
    Ian Kelly, Sep 5, 2012
    #14
  15. Franck Ditter

    Dave Angel Guest

    On 09/05/2012 12:47 PM, Hans Mulder wrote:
    > On 5/09/12 17:09:30, Dave Angel wrote:
    >> But by claiming that id() really means address, and that those addresses
    >> might move during the lifetime of an object, then the fact that the id()
    >> functions are not called simultaneously implies that one object might
    >> move to where the other one used to be before the "move."

    > Whoa! Not so fast! The id() of an object is guaranteed to not
    > change during the object's lifetime. So if an implementation
    > moves objects around (e.g. Jython), then it cannot use memory
    > addresses for the id() function.

    Which is equivalent to my point. I had mistakenly thought that Steven
    was claiming it was always an address, and disproving that claim by what
    amounts to reductio ad absurdem.

    >> I think it much more likely that jython uses integer values for
    >> the id() function, and not physical addresses.

    > The id() function is guaranteed to return some flavour of integer.
    >
    > In Jython, the return values are 1, 2, 3, 4, etc., except, of course,
    > if you invoke id() on an object you've id'd before, you get the same
    > number as before.
    >
    > In current versions of CPython, you do get the (virtual) memory
    > address, converted to an int (or a long). But then, CPython does
    > not move objects.
    >
    > Maybe the next version of CPython should shift id values two or three
    > bits to the right, just to make sure people don't misinterpret ids as
    > memory addresses.
    >
    >


    I think i'd prefer if it would put it through one step of a CRC32.

    --

    DaveA
     
    Dave Angel, Sep 5, 2012
    #15
  16. Franck Ditter

    Terry Reedy Guest

    On 9/5/2012 8:48 AM, Ramchandra Apte wrote:

    > Seeing this thread, I think the is statment should be removed.
    > It has a replacement syntax of id(x) == id(y)


    The thread is wrong then.

    If the implementation reuses ids, which CPython does,
    <expression-1> is <expression-2>
    must be implemented as

    internal-tem1 = <expression-1>
    internal-tem2 = <expression-2>
    id(internal-tem1) == id(internal-tem2)

    in order to ensure that the two objects exist simultaneously,
    so that the id comparison is valid.

    > and "a==True" should be automatically changed into memory comparison.


    I have no idea what that means.

    --
    Terry Jan Reedy
     
    Terry Reedy, Sep 5, 2012
    #16
  17. Franck Ditter

    Terry Reedy Guest

    On 9/5/2012 10:41 AM, Steven D'Aprano wrote:

    > True. In principle, some day there might be a version of Python that runs
    > on some exotic quantum computer where the very concept of "physical
    > address" is meaningless.


    You mean like the human brain? When people execute Python code, does 0
    have an address?

    --
    Terry Jan Reedy
     
    Terry Reedy, Sep 5, 2012
    #17
  18. Franck Ditter

    Dave Angel Guest

    On 09/05/2012 02:27 PM, Terry Reedy wrote:
    > On 9/5/2012 8:48 AM, Ramchandra Apte wrote:
    >
    >> Seeing this thread, I think the is statment should be removed.
    >> It has a replacement syntax of id(x) == id(y)

    >
    > The thread is wrong then.
    >
    > If the implementation reuses ids, which CPython does,
    > <expression-1> is <expression-2>
    > must be implemented as
    >
    > internal-tem1 = <expression-1>
    > internal-tem2 = <expression-2>
    > id(internal-tem1) == id(internal-tem2)
    >
    > in order to ensure that the two objects exist simultaneously,
    > so that the id comparison is valid.
    >
    > > and "a==True" should be automatically changed into memory comparison.

    >
    > I have no idea what that means.
    >


    It's probably a response to Steve's comment

    """

    In general, you almost never need to care about IDs and object identity.
    The main exception is testing for None, which should always be written as:

    if x is None
    """

    Somehow he substituted True for None. Anyway, if one eliminates "is"
    then Steve's comment wouldn't apply.

    --

    DaveA
     
    Dave Angel, Sep 5, 2012
    #18
  19. On Wed, 05 Sep 2012 14:31:08 -0400, Terry Reedy <>
    declaimed the following in gmane.comp.python.general:

    > On 9/5/2012 10:41 AM, Steven D'Aprano wrote:
    >
    > > True. In principle, some day there might be a version of Python that runs
    > > on some exotic quantum computer where the very concept of "physical
    > > address" is meaningless.

    >
    > You mean like the human brain? When people execute Python code, does 0
    > have an address?


    I suspect some day in the future various CAT and similar scanners
    will be able to capture the entire brain (3D) in real-time, at which
    point a statistical analysis of many people will be able to assign a 3D
    Cartesian coordinate to the main activity associated with the concept of
    0 (of course, we'll have to differentiate the concept of the glyph 0
    from the concept of the quantity/number zero from the word zero...)
    --
    Wulfraed Dennis Lee Bieber AF6VN
    HTTP://wlfraed.home.netcom.com/
     
    Dennis Lee Bieber, Sep 6, 2012
    #19
  20. On Wed, 05 Sep 2012 14:27:44 -0400, Terry Reedy wrote:

    > On 9/5/2012 8:48 AM, Ramchandra Apte wrote:
    >
    > > and "a==True" should be automatically changed into memory comparison.

    >
    > I have no idea what that means.


    I interpret this as meaning that "a == True" should be special-cased by
    the interpreter as "a is True" instead of calling a.__eq__.



    --
    Steven
     
    Steven D'Aprano, Sep 6, 2012
    #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. Yuancai \(Charlie\) Ye
    Replies:
    0
    Views:
    914
    Yuancai \(Charlie\) Ye
    Jun 7, 2004
  2. Bruce Sam
    Replies:
    9
    Views:
    3,789
    reneske
    Nov 25, 2008
  3. Pravin
    Replies:
    2
    Views:
    504
    Anatoly
    Feb 16, 2004
  4. Yuancai \(Charlie\) Ye
    Replies:
    2
    Views:
    391
    Yuancai \(Charlie\) Ye
    Apr 26, 2004
  5. Yuancai \(Charlie\) Ye
    Replies:
    1
    Views:
    412
    Ken Cox [Microsoft MVP]
    Jun 7, 2004
Loading...

Share This Page