To reuse or not to reuse

Discussion in 'C Programming' started by jacob navia, Nov 5, 2006.

  1. jacob navia

    jacob navia Guest

    There is an interesting discussion running in Slashdot now, about code
    reuse.

    The thema of the discussion is here:

    < quote >
    Susan Elliot Sim asks: "In the science fiction novel, 'A Deepness in the
    Sky,' Vernor Vinge described a future where software is created by
    'programmer archaeologists' who search archives for existing pieces of
    code, contextualize them, and combine them into new applications. So
    much complexity and automation has been built into code that it is
    simply infeasible to build from scratch. While this seems like the
    ultimate code reuse fantasy (or nightmare), we think it's starting to
    happen with the availability of Open Source software. We have observed a
    number of projects where software development is driven by the
    identification, selection, and combination of working software systems.
    More often than not, these constituent parts are Open Source software
    systems and typically not designed to be used as components. These parts
    are then made to interoperate through wrappers and glue code. We think
    this trend is a harbinger of things to come. What do you think? How
    prevalent is this approach to new software development? What do software
    developers think about their projects being used in such a way?"

    < end quote >

    I think it would be an interesting discussion for us. We all do code
    reuse, but somehow, it is supposed that code reuse is only done with
    "advanced" languages with OO programming and what have you.

    C, as a language, we are being told, doesn't encourage code reuse, it is
    too "low level".

    But I am anticipating. I have actually read "A deepness in the Sky",
    and it made a lasting impression, it is a wonderful novel.

    That part about software reuse made me think that actually this has
    already happened a LONG time ago already since actually nobody starts
    from scratch. We all reuse what other people have created for us.

    When I start writing a new software in C, I reuse the compiler system,
    the editor, and obviously all the software and hardware needed to create
    the processor, the computer, etc. Nobody starts from scratch.

    That scene in the book made also realize the LAYERED nature of
    software. When we reuse a bit of software we make a new LAYER of
    code, hopefully a layer that allows us getting higher quicker and
    doesn't represent a risk of letting us down and crumbling when we climb
    to it :)

    Code reuse in C takes many approaches, but probably the most common is
    cut/paste.

    We take a piece of software from some other software, that doesn't even
    have an explicit interface and wasn't even intended to be reused at all.
    We just reuse the algo.

    Mostly we reuse a function, or a piece of a function doing a simple
    task. For instance today I was wondering if I could write a rationals
    package (numbers like 2/3, 3/4 etc), specifically a least common
    multiple algorithm (lcm). So I started looking around
    (software archeology) and remembered that I wrote already such a package
    for a lisp interpreter back in 1989 that already did that. After several
    hours looking around in the pile of old floppy disks, I found it, and
    it seemed reusable.

    But I wasn't satisfied, there are maybe errors, even if the tests back
    then never showed any errors in it.

    Google.

    Google has a feature called

    http://www.google.com/codesearch

    that will allow you search an extensive data base of public domain
    software. I searched for lcm algorithm and found a hit in

    gnc-numeric.c -- an exact-number library for accounting use
    * Copyright (C) 2000 Bill Gribble

    In the package "gnotime". I looked at the algorithm and it did almost
    the same thing as I did, what was kind of reassuring.

    Reuse today is done more or less like that. You search ("archeology")
    a data base of old software and take pieces out of that software
    incoporating them into the new one, more or less always with
    some modifications.

    Obviously there are many hidden assumptions when reusing software.
    The most crucial one is that you can only reuse something if the
    software environment that you are using is compatible with the old
    software.

    In the novel, Vernor Vinge supposes a stable society/environment of
    millions of years, with human beings living several thousands of years.
    Obviously that is an ideal reuse environment, what couldn't be absent
    from the mind of Vinge, a software expert.

    Software reuse can be done in this way in C since C offers a stable
    software environment taht is now quite old, even if our whole field
    (data processing) is comparatively new.

    Other languages, due to their more recent origins, offer less
    opportunities for software reuse in this way. C#, for instance,
    being just a few yers old at most, will never have the same database
    of code as C. A search with the same parameters yielded not a
    single match for C#.


    Here are the results for some languages:
    C 9
    C++ 3
    Java 1
    Ada zero
    C# zero
    Asm zero
    Lisp zero
    Smalltalk zero
    Fortran zero
    Delphi zero

    Obviously there must be other algorithms where this is different,
    because some languages are specialized in numerical calculations,
    others in IA algorithms, etc etc.

    These are just some thoughts to start a discussion.

    jacob
     
    jacob navia, Nov 5, 2006
    #1
    1. Advertising

  2. jacob navia

    cloverman Guest

    [{snip]
    >
    > C, as a language, we are being told, doesn't encourage code reuse, it is
    > too "low level".

    Languages in them selves do not encourage re-use - programmers (or a
    group of programmers) with an eye to saving extra work, in development
    and future maintenance, will isolate and re-use common functionality in
    whatever language they write.
    [snip]
    > Code reuse in C takes many approaches, but probably the most common is
    > cut/paste.

    Cut and paste is rare. Good programmers - and most C programmers are
    good ;-) - in any language know why not to, and do not cut and paste -
    they call existing functions or refactor existing functions so that the
    bits they want are callable as re-usable functions.

    > Reuse today is done more or less like that. You search ("archeology")
    > a data base of old software and take pieces out of that software
    > incoporating them into the new one, more or less always with
    > some modifications.

    Your use of "archeology" is not quite right - because archeology is not
    finding things to re-use - it is looking at the artefacts of an older
    civilization, and trying to work out what they were thinking - I, as a
    maintenance analyst/programmer, have often used the term "doing the
    archeology" in a different (and I think clearer) sense as trying to
    find out what an (insufficiently documented) system was intended to to
    do.
    I also have a particular interest in the ancient henges of England -
    these henges (earth works) have been reused by different civilizations
    over thousands of years - the focus of their rites change from focus on
    the moon to focus on the sun - the original work was used for a
    completely different purpose to its construction - that's true
    re-usability :)
     
    cloverman, Nov 5, 2006
    #2
    1. Advertising

  3. jacob navia <> writes:
    [...]
    > C, as a language, we are being told, doesn't encourage code reuse, it is
    > too "low level".


    Told by whom? I don't recall anyone making such a claim.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Nov 5, 2006
    #3
  4. jacob navia

    jacob navia Guest

    cloverman a écrit :
    > [{snip]
    >
    >>C, as a language, we are being told, doesn't encourage code reuse, it is
    >>too "low level".

    >
    > Languages in them selves do not encourage re-use - programmers (or a
    > group of programmers) with an eye to saving extra work, in development
    > and future maintenance, will isolate and re-use common functionality in
    > whatever language they write.
    > [snip]
    >
    >>Code reuse in C takes many approaches, but probably the most common is
    >>cut/paste.

    >
    > Cut and paste is rare. Good programmers - and most C programmers are
    > good ;-) - in any language know why not to, and do not cut and paste -
    > they call existing functions or refactor existing functions so that the
    > bits they want are callable as re-usable functions.
    >

    That works only if the code was intended to be reused in that fashion.
    Most often than not, you find code that within some function does
    something similar to what you want to do. For instance in the code
    I found in the internet, the lcm algorithm is embedded within
    a larger function that does a lot of other things.

    Code reuse with cut/paste can be just snipping a couple of lines
    from an example or from another software that builds a pipe,
    for instance, or does eomething specific.
     
    jacob navia, Nov 5, 2006
    #4
  5. jacob navia

    jacob navia Guest

    Keith Thompson a écrit :
    > jacob navia <> writes:
    > [...]
    >
    >>C, as a language, we are being told, doesn't encourage code reuse, it is
    >>too "low level".

    >
    >
    > Told by whom? I don't recall anyone making such a claim.
    >


    I have in mind the OO crowd with their continuos emphasis that
    "only OO" allows for real code reuse.
     
    jacob navia, Nov 5, 2006
    #5
  6. jacob navia

    CBFalconer Guest

    jacob navia wrote:
    >

    .... snip ...
    >
    > That works only if the code was intended to be reused in that
    > fashion. Most often than not, you find code that within some
    > function does something similar to what you want to do. For
    > instance in the code I found in the internet, the lcm algorithm
    > is embedded within a larger function that does a lot of other
    > things.


    Then, IMNSHO, the original programmer was not very good. An lcm
    routine is easily separated out into an independent entity, and
    reused as necessary.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
     
    CBFalconer, Nov 5, 2006
    #6
  7. jacob navia

    Eric Sosman Guest

    jacob navia wrote:
    > Keith Thompson a écrit :
    >
    >> jacob navia <> writes:
    >> [...]
    >>
    >>> C, as a language, we are being told, doesn't encourage code reuse, it is
    >>> too "low level".

    >>
    >>
    >>
    >> Told by whom? I don't recall anyone making such a claim.
    >>

    >
    > I have in mind the OO crowd with their continuos emphasis that
    > "only OO" allows for real code reuse.


    Wasn't it Java that introduced the word "deprecated" into
    the programming vocabulary? Amusing, isn't it, that an object-
    oriented language defines an official compiler-supported means
    to *discourage* code re-use?

    (Some programmers express their distaste for re-use by
    refusing to re-use the standard spelling of "deprecated," instead
    writing "depreciated" or "depricated." Can "decrapated" be
    far off?)

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 5, 2006
    #7
  8. jacob navia said:

    <snip>

    > We all do code
    > reuse, but somehow, it is supposed that code reuse is only done with
    > "advanced" languages with OO programming and what have you.


    You're right. I agree. We all re-use code, but it doesn't count as "code
    re-use" if it's not object-oriented - *if* you listen to the OO folks.

    > C, as a language, we are being told, doesn't encourage code reuse, it is
    > too "low level".


    And yet, as you know, we do re-use C code. We do it all the time. We shove
    our code into libraries, and use those libraries constantly.

    <snip>

    > Nobody starts from scratch.


    Right again. And nobody throws away good general-purpose libraries.

    > That scene in the book made also realize the LAYERED nature of
    > software. When we reuse a bit of software we make a new LAYER of
    > code, hopefully a layer that allows us getting higher quicker and
    > doesn't represent a risk of letting us down and crumbling when we climb
    > to it :)


    If I understand you aright, this is what Douglas Hofstadter calls
    "chunking", and it's an essential part of manageable complexity. Note,
    however, that there are times when we need to "de-chunk" - to take a long
    hard look at our chunks, and decide whether they really reflect the problem
    at hand. For an excellent discussion of this, see the spam filtering
    analysis in K&P's "The Practice of Programming".

    > Code reuse in C takes many approaches, but probably the most common is
    > cut/paste.


    That is probably the most common, but not necessarily the best! If a piece
    of code is useful enough to be used /twice/, it's probably useful enough to
    go into a library.

    <snip>

    > Obviously there are many hidden assumptions when reusing software.
    > The most crucial one is that you can only reuse something if the
    > software environment that you are using is compatible with the old
    > software.


    Often this is irrelevant to C code, since C is inherently portable (mostly!)
    if you stay within the bounds of the Standard. A more important factor, I
    think, is that of modularity: whether the code was originally *designed* to
    be re-used, or whether it has been nailed to its application by, say, tight
    coupling (e.g. use of non-standard libraries for which the source is not
    available, or by use of file scope objects).

    <snip>

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Nov 5, 2006
    #8
  9. Eric Sosman said:

    <snip>

    > Wasn't it Java that introduced the word "deprecated" into
    > the programming vocabulary?


    No. I certainly recall encountering and indeed using the term on a fairly
    frequent basis in the early 1990s, well before the introduction of Java in
    May 1995.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Nov 5, 2006
    #9
  10. In article <>,
    Eric Sosman <> wrote:

    > Wasn't it Java that introduced the word "deprecated" into
    >the programming vocabulary?


    No.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Nov 5, 2006
    #10
  11. jacob navia

    Eric Sosman Guest

    Richard Heathfield wrote:

    > Eric Sosman said:
    >
    > <snip>
    >
    >>Wasn't it Java that introduced the word "deprecated" into
    >>the programming vocabulary?

    >
    >
    > No. I certainly recall encountering and indeed using the term on a fairly
    > frequent basis in the early 1990s, well before the introduction of Java in
    > May 1995.


    Of course the word was around in ordinary English (he said,
    with a deprecating sneer), but I don't recall hearing it used much
    by programmers until Java came along. Can you recall whether the
    early programming-related uses you encountered were connected to
    any particular language or technology? I seem to recall a man page
    for "as" that had some deprecatory remarks about writing one's own
    assembly instead of leaving it to the compiler, but I can't recall
    whether it actually used the word "deprecate."

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 5, 2006
    #11
  12. In article <>,
    Eric Sosman <> wrote:

    > Of course the word was around in ordinary English (he said,
    >with a deprecating sneer), but I don't recall hearing it used much
    >by programmers until Java came along.


    Do a Google groups search for "deprecated" in comp.lang.c with a date
    restriction (or even net.lang.c). You will see plenty of discussion
    from the 1980s about what features should be deprecated in ANSI C.

    I believe the FORTRAN 90 standard had a list of deprecated features,
    but I can't find an online copy to verify that it used that word.

    But having checked, I must admit that you seem to be right that
    Java was responsible for a great increase in the use of the word.
    The number of articles in comp.lang.* using the word "deprecate"
    jumped from 161 in 1996 to 753 in 1997, and 531 of those 753 were
    in comp.lang.java.*.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Nov 5, 2006
    #12
  13. On Sun, 05 Nov 2006 17:59:05 -0500, Eric Sosman
    <> wrote:

    >jacob navia wrote:
    >> Keith Thompson a écrit :
    >>
    >>> jacob navia <> writes:
    >>> [...]
    >>>
    >>>> C, as a language, we are being told, doesn't encourage code reuse, it is
    >>>> too "low level".
    >>>
    >>>
    >>>
    >>> Told by whom? I don't recall anyone making such a claim.
    >>>

    >>
    >> I have in mind the OO crowd with their continuos emphasis that
    >> "only OO" allows for real code reuse.

    >
    > Wasn't it Java that introduced the word "deprecated" into
    >the programming vocabulary? Amusing, isn't it, that an object-
    >oriented language defines an official compiler-supported means
    >to *discourage* code re-use?


    IIRC the computed goto was deprecated in the fortran 77 standard.

    >
    > (Some programmers express their distaste for re-use by
    >refusing to re-use the standard spelling of "deprecated," instead
    >writing "depreciated" or "depricated." Can "decrapated" be
    >far off?)
    >
    >--
    >Eric Sosman
    >
     
    Richard Harter, Nov 6, 2006
    #13
  14. jacob navia:

    > C, as a language, we are being told, doesn't encourage code reuse, it is
    > too "low level".



    Contrast:

    memcpy(&a,&b,sizeof a);

    with:

    {
    char unsigned *p = (char unsigned*)&a;
    char unsigned const *q = (char unsigned const*)&b;

    char unsigned const *const pover = p + sizeof a;
    while (pover != p) *p++ = *q++;
    }

    This is what my idea of "re-use" is. Instead of verbosely typing out an
    algorithm step by step, we call a little function. Not only that, but we do
    on to archive the function for future use in other programs.


    > Obviously there are many hidden assumptions when reusing software.
    > The most crucial one is that you can only reuse something if the
    > software environment that you are using is compatible with the old
    > software.


    I think another assumption is that the "re-used" code works perfectly. For
    example, one of the reasons a lot of C++ programmers advocate the use of
    "std::string" rather than null-terminated char arrays is that you can get
    things done quicker, but the other reason is that it's harder to make
    mistakes and to introduce bugs. The second argument, however, only makes
    sense if we assume that the "re-used" code works perfectly all the time.

    --

    Frederick Gotham
     
    Frederick Gotham, Nov 6, 2006
    #14
  15. jacob navia:

    > I have in mind the OO crowd with their continuos emphasis that
    > "only OO" allows for real code reuse.


    Sounds like the inventor of the lightbulb thinks that candles never did
    their job.

    Honestly though, I've never understood the whole OO hype. I myself have
    been programming in C++ for a few years now, and, having a decent enough
    knowledge of C aswell, it strikes me that most OO facilities are little
    more than syntactical sugar. Yes, it's nice to be able to write:

    FancyType obj;

    instead of:

    FancyType obj;
    InitFancyType(&obj);

    , but I wouldn't go so far as to think that OO is the revolution that some
    people make it out to be.

    Take "polymorphism" for instance. It's a ridiculously pretentious name for
    something very simple. "virtual function" strikes me as a very stupid term
    too, a bit of a misnomer. You put a V-Table pointer within each object, and
    all of a sudden the programming world has been revolutionised?! Please.

    I can understand how maybe the "less proficient than thou" programmers
    might benefit from the widespread dumbed-down-ness that OO has brought to
    the fore, and how they might think that OO is the best thing since sliced
    bread, but I just don't get the hype.

    --

    Frederick Gotham
     
    Frederick Gotham, Nov 6, 2006
    #15
  16. "jacob navia" <> wrote in message
    news:454e3098$0$27368$...
    > Code reuse in C takes many approaches, but probably the most common is
    > cut/paste.


    I dont recall copy/pasting SetWindowText or any other of the thousands of
    Win32 functions to my own projects. Or is that not code reuse? Also the
    win32 functions are a good example where data abstraction is used in C,
    which is one of the principles of OO. It's just amazing how anybody could
    say code reuse isnt possible in a structured language, OO programmer or not.
    I also wouldnt say "the whole OO crowd" says that of course
     
    Serve Laurijssen, Nov 6, 2006
    #16
  17. jacob navia

    Eric Sosman Guest

    Richard Tobin wrote:
    > In article <>,
    > Eric Sosman <> wrote:
    >
    >
    >> Of course the word was around in ordinary English (he said,
    >>with a deprecating sneer), but I don't recall hearing it used much
    >>by programmers until Java came along.

    >
    >
    > Do a Google groups search for "deprecated" in comp.lang.c with a date
    > restriction (or even net.lang.c). You will see plenty of discussion
    > from the 1980s about what features should be deprecated in ANSI C.
    >
    > I believe the FORTRAN 90 standard had a list of deprecated features,
    > but I can't find an online copy to verify that it used that word.
    >
    > But having checked, I must admit that you seem to be right that
    > Java was responsible for a great increase in the use of the word.
    > The number of articles in comp.lang.* using the word "deprecate"
    > jumped from 161 in 1996 to 753 in 1997, and 531 of those 753 were
    > in comp.lang.java.*.


    Let me change the observation just a little. The claim in
    question was offered by Jacob Navia

    > I have in mind the OO crowd with their continuos emphasis that
    > "only OO" allows for real code reuse.


    (from context, it's clear he's not an enthusiastic backer of
    the claim). I pointed to Java's popularization of "deprecated"
    as a possible counter-indication, but may have been giving
    Java too much credit.

    But there's another thing: The Java language defines a
    formal mechanism for deprecation, a mechanism supported not
    only by the documentation tools but also by the compiler and
    the "object file" format. The language has an officially-
    sanctioned mechanism whose only function is to *discourage*
    code re-use! Is this a fly in the object-oriented ointment?

    (No, of course not, not really, but we're nearing the end
    of an election campaign where I live, and the spirit of fatuous
    argument is abroad in the land. Besides, silly sloganeering
    is kinda fun!)

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 6, 2006
    #17
  18. Frederick Gotham <> writes:

    > Honestly though, I've never understood the whole OO hype. I myself have
    > been programming in C++ for a few years now, and, having a decent enough
    > knowledge of C aswell, it strikes me that most OO facilities are little
    > more than syntactical sugar.


    Well, yes, just as most structured-language facilities are little more
    than syntactic sugar. Heck, C is just a fancy bit of sugar that hides
    what's *really* going on at the assembly language level!

    Part of your problem is that C++ is a real dog's breakfast of an
    object-oriented language. It has all the things that are virtues in C
    and all the things that are virtues of object orientation, but when
    you mash them together, the whole turns out to be a lot less than the
    sum of its parts.

    > I can understand how maybe the "less proficient than thou" programmers
    > might benefit from the widespread dumbed-down-ness that OO has brought to
    > the fore, and how they might think that OO is the best thing since sliced
    > bread, but I just don't get the hype.


    Paul Graham has an article on comparing the expressive power of
    languages, and his argument runs something like this. Suppose you
    have a BASIC programmer (think Applesoft BASIC here, not Visual Basic)
    and a C programmer. The C programmer looks at BASIC and sees no
    functions, no recursion, no variable scoping -- obviously it's a less
    expressive language. The BASIC programmer looks at C and sees a lot of
    weird features; because he's not accustomed to having things like
    functions, recursion, and variable scoping in his tools, he hasn't
    learned how to use them to solve his problems, and so they look like
    weird features.

    (Graham's example had to do with LISP and C, as I recall, but the
    analogy still applies.)

    That's how it works in general: when you're accustomed to working with
    a more expressive set of formalisms, you see the lack in less
    expressive sets; when you are accustomed to working with a less
    expressive set of formalisms, the extra bits in more expressive sets
    seem like useless fripperies.

    My advice, in that context, is to get away from C and learn something
    completely different: Scheme, or Haskell, or ML. Even if you come
    back to C in the end, you'll have a very different appreciation of its
    strengths and weaknesses.

    Charlton
     
    Charlton Wilbur, Nov 6, 2006
    #18
  19. jacob navia

    John Bode Guest

    jacob navia wrote:
    > Keith Thompson a écrit :
    > > jacob navia <> writes:
    > > [...]
    > >
    > >>C, as a language, we are being told, doesn't encourage code reuse, it is
    > >>too "low level".

    > >
    > >
    > > Told by whom? I don't recall anyone making such a claim.
    > >

    >
    > I have in mind the OO crowd with their continuos emphasis that
    > "only OO" allows for real code reuse.


    Obviously, that's a silly position; however I will allow that in my
    experience, code reuse was usually a little easier in an OO framework
    than a traditional C framework.
     
    John Bode, Nov 6, 2006
    #19
  20. On Mon, 06 Nov 2006 00:02:31 GMT, (Richard Harter) wrote:

    > On Sun, 05 Nov 2006 17:59:05 -0500, Eric Sosman
    > <> wrote:

    <snip>
    > > Wasn't it Java that introduced the word "deprecated" into
    > >the programming vocabulary? Amusing, isn't it, that an object-
    > >oriented language defines an official compiler-supported means
    > >to *discourage* code re-use?

    >
    > IIRC the computed goto was deprecated in the fortran 77 standard.
    >

    No. In 77 it was still useful and occasionally necessary.

    In Fortran _95_ it is marked obselescent -- they don't use the word
    deprecated, but this has the same meaning = it is still legal and
    supported, but the standard-writers think it's a poor idea and there
    is a better way to use instead, here F90's SELECT CASE.

    And Fortran does require that a compiler be able to diagnose most
    obsolescent usages including this, although it needn't be the default.

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Dec 18, 2006
    #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. walala
    Replies:
    1
    Views:
    494
  2. tshad
    Replies:
    5
    Views:
    549
    Steve C. Orr [MVP, MCSD]
    May 17, 2005
  3. Hylander

    To reuse or not to reuse....

    Hylander, Feb 26, 2004, in forum: Java
    Replies:
    0
    Views:
    427
    Hylander
    Feb 26, 2004
  4. Rushi
    Replies:
    4
    Views:
    465
    Magnus Henriksson
    Dec 5, 2005
  5. code reuse and design reuse

    , Feb 7, 2006, in forum: C Programming
    Replies:
    16
    Views:
    1,040
    Malcolm
    Feb 12, 2006
Loading...

Share This Page