UserLinux chooses Python as "interpretive language" of choice

A

Aahz

The people who have switched don't post here. I'm very active
on the XP mailing list, and I see lots more references to Ruby than
to Python. Maybe the fact that such industry heavy hitters as Robert
Martin, David Thomas, and any number of others have switched
shouldn't count. In fact, the head of this thread should really be a
wakeup call: the *only* reason that Python was chosen instead
of Ruby is the lack of *current* market penetration.

AFAIK, those are all people who were never heavy Python users. We're
still getting plenty of people switching to Python instead of Ruby,
largely because there are more killer applications written in Python.
 
J

John Roth

Oren Tirosh said:
I've always considered the visitor pattern as a rather poor substitute
for generators, not as a something worth having for its own sake. Using
generators instead of visitors+anonymous functions obviously reduces the
need for anonymous functions (not that it's any excuse for not having
something better than Python's lambdas!).

I'm not certain I'm making the connection. The visitor pattern
as I use it doesn't seem to have much to do with generators.
It's a way of disconnecting the sequencing logic from the
processing logic, while a generator seems to encapsulate
both in the same function.

A good case in point is file processing. I've got a class that
encapsulates a directory: instantiate it and it reads the directory
into an internal list. Then if you invoke the .visit(instance)) method,
it calls either the 'file' or the 'directory' method in that instance
for each of the names in the directory. If I need to go down a
directory chain, I simply invoke it recursively.

If I arranged it so I called the visitor instance one last time
(possibly using a 'lastTime' method) I could completely
replace the reduce built-in for any object that had a .visit
method!

Blocks plus the pervasive availibility of a .visit() method is the
overwhelmingly most common thing Ruby users mention for
why they like the language. It seems to be somewhat of a
paradigm shift.

John Roth
 
D

David M. Cook

to Python. Maybe the fact that such industry heavy hitters as Robert
Martin, David Thomas, and any number of others have switched
shouldn't count. In fact, the head of this thread should really be a

I think this has a lot to do with Ruby's greater similarity to Smalltalk.

Dave Cook
 
H

Hans Nowak

Ville said:
Most importantly, why would anyone even care? Ability to optionally
invoke a "call" operation on an object implicitly seems utterly
worthless to me. It has the feel of perl philosophy (regexps in
language syntaxm anyone? ), and it's not the only instance in Ruby. I
don't really like the Perl philosophy (like most of the people who
"get" Python), and I don't really believe a language whose designers
appreciate the perlisms poses a serious threat to Python. Not even if
they got some things right.

Hmm, I looked at Ruby a few months ago, and while it has more similarities to
Python than differences, its design philosophies are indeed very different. As
such, it seems less "clean" to me than Python (but anyone's MMV, of course).
In some places it seems too "pure", in other places it adds a lot of extra
syntax for special cases. It's just different from Python, but I expect that
many people don't care much about that.

The rise of Ruby may not be a good thing for Python, but I think that in the
long run, it's good for scripting/dynamic languages as a whole. Python gets
another competitor, which wouldn't be possible if dynamic (agile?) languages
were not a viable choice. Enough people are interested in dynamic languages
that there's room for another one. So, in a way, it's a sign that people who
use one of these languages (be it Python, Perl, Ruby) are on the right track.

As for switching... I like Ruby's code blocks (although not necessarily the way
they are used), and maybe a few other small things, but I haven't seen anything
that would make me seriously consider switching.
 
S

Skip Montanaro

John> The biggest problem is that I think Python is beginning to sucumb
John> to the "we're better so we don't have to try harder" syndrome.
John> One of these days, someone is going to start chewing up the user
John> base, and for a while it looked like Ruby might have been it.

John> I think the discussion on this thread is a reasonably good example
John> [grin].

John> The responses to my comment about method calls with no arguements
John> should say everything that needs to be said about attitude.

Not really. You're holding this discussion on comp.lang.python, not on
(e-mail address removed). I interpreted your statement about not having to
"try harder" as being aimed at the people who work on the language and the
standard library. Perhaps I was mistaken. In any case, I don't see it as
necessarily a bad thing that there are multiple languages out there with
overlapping features and audiences. They absorb some ideas but not others,
and when they do they don't absorb them in precisely the same way. You can
interpret that as not trying harder, but I don't.

Python's design doesn't admit the option of calling functions without the
parens. Perl's and Ruby's do. On the other hand, functions are first-class
objects in Python. I don't know about Ruby, but in Perl, whether or not a
function is called or treated as a piece of data is very context-dependent,
to the point of near madness for people like myself who don't use it day in
and day out.

John> Let's skip the fluf and get to the crux. There are four languages
John> (not counting minor entries) in the space Python occupies.

John> Larry Wall (Perl): There's more than one way to do it.

John> Guido vanRossum (Python): There should only be one obvious way to
John> do anything significant.

John> Metz (Ruby): I want a language that's both productive and fun to
John> program.

John> John Osterhout (TCL). I want a language I can embed in tools as a
John> common scripting language.

John> Notice that there is only one polarity here: Perl vs Python. Ruby
John> goes meta on the discussion in that it looks at what the customer
John> (the developer) *wants*, rather than what the language designer
John> thinks they should have.

Different design philosophies result in different languages. That's to be
expected. If Ruby floats your boat, use it. Advocate for it if you like,
but don't expect that because you like Ruby's philosophy better that Python
necessarily ought to move in that direction. I happen to think Python is
both productive and fun to use. But that's just me.

John> Most businesses would look at a competitor who is stealing
John> customers as an opportunity to figure out what those customers
John> want that they aren't getting.

Who's stealing customers? This is open source. We have no shareholders or
board of directors to appease. We scratch our own itches. If Ruby relieves
itching for more people than Python, so be it. Nobody's going to go out of
business because of it.

John> The jihad against the "functional" builtins is a good case in
John> point. The replacements for apply, map and filter seem to be
John> adequate, and in the case of list comprehensions, pretty darned
John> useful although I think that it's a rather baroque addition to an
John> otherwise very clear and comprehensible language.

Why do you call it a "jihad"? Guido has stated on multiple occasions that
he regretted adding functional constructs to the language. I still can't
get to the Python website (have to wait another two hours for my ISP to
reload its tables), but here's a Google pointer to an HTML-ized version of
his OSCON 2002 Powerpoint slides:

http://216.239.41.104/search?q=cach...ets.ppt+OSCON+"python+regrets"&hl=en&ie=UTF-8

John> On the other hand, claiming that sum() is an adequate replacement
John> for reduce() is so silly that it borders on the absurd.

No, operationally that's a correct statement. People have looked at the use
of reduce() in a number of different contexts. In all but the rarest of
cases, reduce() was used to sum a list of numbers. sum() is a perfectly
adequate replacement in all but those rare cases and is easier to read as
well. As Guido mentioned in the talk I referenced above:

reduce()
nobody uses it, few understand it
a for loop is clearer & (usually) faster

John> The only explanation I can come up with for that level of
John> absurdity is a desire to get rid of a feature, regardless of what
John> it looks like. In other words, a jihad (holy war.)

No, it's simply not used very much. Python never has been a very strong
functional language. It's always been a very strong object-oriented
language. Use it the way it's strongest.

John> There is no replacement for lambda in sight, even though lambda is
John> arguably the ***largest single*** one of the functional constructs
John> that needs work, and has obviously needed work for a long time.

Once again, you desire Python to be something it is not. If you want a
strong functional language, program in Lisp or Haskell.

John> The obvious replacement for lambda, which is some form of inline
John> block, has not been seriously discussed, with proposed syntax and
John> examples, anywhere I've seen it. Clearly, I'm not ominiscient, so
John> that doesn't mean it hasn't, though.

Anonymous blocks are not a replacement for lambdas, named functions are.
How do you pass parameters to an anonymous block?

John> The PEP 308 mess has left a rather sour taste in a lot of people's
John> mouths: there was a clear majority in favor of doing *something*,
John> but the voting was rigged (although I doubt if it was done
John> deliberately) to make certain that no single proposal would get a
John> majority.

Again, it's something that doesn't fit easily into Python's design. There
were several ternary operator proposals advanced, but none was a clear
winner. Guido's a conservative language designer for the most part. It's
better to leave it out than to put something in you'll regret later. PEP
308 wasn't the first time the ternary operator discussion has come up, by
the way. Functional programming, ternary operators, anonymous code blocks.
They've all been issues for a long time.

You seem to have a burr under your saddle about this stuff. I'm not sure
why. Maybe it's time to get out the curry comb...

Skip
 
O

Oren Tirosh

I'm not certain I'm making the connection. The visitor pattern
as I use it doesn't seem to have much to do with generators.
It's a way of disconnecting the sequencing logic from the
processing logic,

You mean like this?

def generator(...):
sequencing logic, yield stuff

for object in generator(...):
processing logic
while a generator seems to encapsulate both in the same function.

Can you give any specific reasons why you believe this to be the
case?
A good case in point is file processing. I've got a class that
encapsulates a directory: instantiate it and it reads the directory
into an internal list. Then if you invoke the .visit(instance)) method,
it calls either the 'file' or the 'directory' method in that instance
for each of the names in the directory. If I need to go down a
directory chain, I simply invoke it recursively.

Recursively? I thought the whole point of using such a class was to
disconnect, as you say, the sequencing logic from the processing logic.
If the user of the class must explicitly invoke the recursion the
sequencing logic becomes hard-wired into the processing logic. With a
generator you could pass an argument to the sequence logic that instructs
it to do, for example, a breadth-first or depth-first traversal without
affecting the processing logic.
If I arranged it so I called the visitor instance one last time
(possibly using a 'lastTime' method) I could completely

Like this?

for object in generator(...):
processing logic
last time


I think it's great that Python has functions and bound methods as
first-class objects and that they can be passed around as values. I just
don't think they should be used when there are far simpler ways to
achieve the same result.

Oren
 
S

Sean Ross

John Roth said:
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.

Hi.
Every time I see that feature in Ruby I find it appealing - and then I don't
(which is kind of how I feel about the language as a whole). I find it
appealing because, well, like you've said, the operation doesn't require
parameters, so why clutter up the code with unnecessary parenthesis? And if
I only ever read my own code, and I was sure I would always know what I had
been doing in older code, I might be okay using that feature. But that's not
the case. I do have to read other people's code, which means (in this case)
I have to decipher, on each occurrence of

a

whether that is a variable or an implicit operation call (if I care about
that sort of thing, which I might). In Python, it's a binding (unless it's a
property "obj.a" in which case it's still a binding to a descriptor but that
gets invoked during look-up, so ... have I lost my leg to stand on there?).

I suppose I just prefer to know, from reading that line of code, without
tracking back into other parts of the implementation, or running it to find
out, whether a is a variable or an operation. But, then, properties can
obscure the issue in Python just as well, so I don't think this argument has
much steam (unless I advocate losing properties - which I really don't).

So, I'll address a slightly different but wholly related issue. In Python,
when I want to pass a function, method, or object as an argument, I do so by
name:

callable(function, method, obj)

The names in the argument list are bindings to the object - in this case to
a function, a method and some other type of object. Using the name of a
function or method does not invoke it, so I can pass these operations by
name without resorting to disambiguatory syntax introduction. Not so in
Ruby: because, there, the names function/method would be found (during
lookup) to refer to callables that take no parameters, so Ruby would invoke
them - which is not what we want. To get around this, Ruby introduces
:function, :method - which is not so terrible, I suppose. It's a trade-off
imposed, in part, by the desire of the language designer to allow for a
cleaner parameter-less method invocation. So, they've cleaned up one thing,
only to dirty up another. And Python has done the same thing, only they've
cleaned up name referencing rather than parameter-less callable invocations.

Which is better? Having to say a() explicitly when you wish to invoke a
callable, or having to say :a when you wish only to refer to the object and
not invoke it? Well, If we just go by syntax, :a uses one less character
than a(), so that could be a plus. And :a is very explicit (once you know
what it means) - you know you're using a name reference (correct term?).
But, when a and a() can both mean the same thing, or different things,
depending on the context ...

a = "variable"

def a
"method"
end

puts a
puts a()

# output
variable
method


... well, for me, that's not such a great thing.

Part of language design appears to be about trade-off. And part of language
preference appears to be about choosing the language that handles most of
those tradeoffs as you would prefer (which can save you from having to write
your own). I think I prefer that callable invocation be done explicitly, so
that I may recognize it as such in my, and other people's, code. And I think
I prefer not having to disambiguate name referencing via arbitrary syntax. I
think that's what I prefer - and yet I see the allure of the "Ruby Way".

Why use parenthesis for an empty parameter-list, when you don't have to? To
be explicit. Why is that preferable? Because it's explicit? Um. Try again.
Because explicit is better than implicit? Begs the question. Because
ambiguous code requires you to expend more time reading to understand than
does less ambiguous code? Hm. I don't find the code ambiguous, but even so
the ambiguous code might take less time to write, so the overall time may
balance out. People read code more often than they write it, so the balance
would tip towards those who must read the code. Do they? Prove it. I site
such and such a study. Well, I write more code than I read. Then you musn't
be a very good programmer... and how could you write more code than you
read? Do you not read your own code? You know what I meant, and who're you
calling a bad programmer? ...

And so on ... ad nauseum ... much like this post ... heh

Sean
 
V

Ville Vainio

John Roth said:
Notice that there is only one polarity here: Perl vs Python. Ruby goes
meta on the discussion in that it looks at what the customer (the developer)
*wants*, rather than what the language designer thinks they should have.

Customer is often less informed than the language designer. I think
someone mentioned somewhere that Perl is a "popularity whore", I guess
the same applies to Ruby. I can rest assured that Python won't start
decaying because the language designers wanted to please the whims of
some members of the audience.
Most businesses would look at a competitor who is stealing customers
as an opportunity to figure out what those customers want that they
aren't getting.

Fair enough. Someone might want to compile a list where the issue
could be dissected once and for all. A lot of the issues rubyists have
tend to be along the lines of "well, Python has this feature *now*,
but it wasn't in version blah blah when I tried it. We had it since
the beginning, so it is not an add-on but a real feature!". IOW, they
fall apart w/ even a minor analysis.
and in the case of list comprehensions, pretty darned useful although
I think that it's a rather baroque addition to an otherwise very clear
and comprehensible language.

List comprehensions are, for me, one of the killer features in Python
that raise Python above all other languages (Haskell has them, but
it's.. umm.. Haskell and one would be laughed out of the office if he
suggested Haskell for implementing anything).
There is no replacement for lambda in sight, even though lambda is
arguably the ***largest single*** one of the functional constructs
that needs work, and has obviously needed work for a long time.

Party line is that ppl should just define a function with a name. It
might not be the most comfortable option at the time of writing the
code, but it will make the program more readable. It is definitely not
a big enough of a problem to switch the language.

Hmm, I wonder if it is the time to start crossposting this to c.l.ruby
and let the flamewar start. It's been a while already ;-).
 
D

David M. Wilson

John Roth said:
What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.

The point he was making (in a rather convoluted way) is that optional
parens is against the Python philosophy. "Explicit rather than
implicit" being line 2. I would rather be forced to use empty parens
after a function call - it shows you/others exactly what you are
trying to do.

On the other hand, I would detest Python if by simply referring to an
object with a __call__ method caused it to be executed. I'd say that's
closer to braindead.

a = sys.exit
a

Unless you design some silly rules to determine when empty parenthesis
should be allowed - did a get assigned the return value of sys.exit()?
(yes I know it doesn't have one), or did some silly unclear
(implicit) rules stop that from happening. Did sys.exit() run on the
second line?

I think if you can't understand why this option isn't provided for
you, then you misunderstand some of the most fundamental Python
concepts. import this.


David.
 
V

Ville Vainio

John Roth said:
That may not be one of your common coding mistakes.

It was when I started. Not after a while.
My mind doesn't quite get the point of inserting an
otherwise useless pair of parenthesis, and consequently
it's fairly high on the list of common coding errors I make
that causes run time errors. Of course, rigidly applying

Don't something like pychecker detect these things?
TDD will bring those errors up rapidly so they don't
lurk to cause problems later, but not having them in the
first place would be even better.

Not if they go against the fundamental ideas of how the language
works.

is looking at what it's doing right and asking if some of those
things might not improve Python.

Hasn't Alex Martelli done something like this recently? Alex?
As I said, my intent is not to inspire anyone to switch. My intent
is to ask whether there is anything they're doing that would be
(in concept if not in implementation) an improvement to Python.

Sounds like a morally correct motive :).
 
J

John Roth

David M. Wilson said:
John Roth said:
What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.

The point he was making (in a rather convoluted way) is that optional
parens is against the Python philosophy. "Explicit rather than
implicit" being line 2. I would rather be forced to use empty parens
after a function call - it shows you/others exactly what you are
trying to do.

On the other hand, I would detest Python if by simply referring to an
object with a __call__ method caused it to be executed. I'd say that's
closer to braindead.

a = sys.exit
a

Unless you design some silly rules to determine when empty parenthesis
should be allowed - did a get assigned the return value of sys.exit()?
(yes I know it doesn't have one), or did some silly unclear
(implicit) rules stop that from happening. Did sys.exit() run on the
second line?

I think if you can't understand why this option isn't provided for
you, then you misunderstand some of the most fundamental Python
concepts. import this.

I don't think I misunderstand it. As I've said several times in this
thread, I am not seriously advocating it for a number of reasons.

However, yours is not one of them. It's easy enough to distinguish
between a function and some other kind of object that simply has
a __call__ method. Functions provide the number of parameters
they are expecting, other callables don't, so it would indeed be
brain dead to expect an absent call parameter to call something
other than a function. Also, to make it crystal clear, to call anything
other than a function that is expecting no parameters.

Please think before making a critique.

John Roth
 
J

John Roth

Ville Vainio said:
It was when I started. Not after a while.


Don't something like pychecker detect these things?

Since I normally use TDD, using Pychecker would slow
the flow down substantially. See the next paragraph.
Not if they go against the fundamental ideas of how the language
works.

If a language makes opportunities for errors, then there is
something wrong with the language that needs to be corrected.
I'm not a fan of carrying a reasonable idea past the point where
it starts showing its flaws. I'm also not a fan of the idea that
there are any ideas that are flawless if carried to extreme.
Hasn't Alex Martelli done something like this recently? Alex?

There was a mini-project to identify "warts" a year or two ago.
Is this what you mean?
Sounds like a morally correct motive :).

John Roth
 
P

Paul Moore

Oren Tirosh said:
I've always considered the visitor pattern as a rather poor substitute
for generators, not as a something worth having for its own sake. Using
generators instead of visitors+anonymous functions obviously reduces the
need for anonymous functions (not that it's any excuse for not having
something better than Python's lambdas!).

This is a bit out of context, as I've not read the full thread here,
but while I can see that the visitor pattern doesn't offer anything
much over generators for a *single* visitor function, I'm not sure how
that generalises to visitors with multiple "visit" methods.

Consider a file-tree walker, which takes a visitor. On each directory
seen, the visit_directory() method is called, on each file seen, the
visit_file() method is called, and on each symlink seen, the
visit_symlink() method is called.

Replacing that with generators seems like it may be clumsy. Or have I
missed a simple transformation?

Paul.
 
D

David M. Wilson

Ville Vainio said:
I don't know if you have seen this before, but here goes:

http://text.userlinux.com/white_paper.html

There is a jab at Python, though, mentioning that Ruby is more
"refined".


I read a lot of that last night, and I find it intriguing. It strikes
me as being misdirected on a number of fronts, but that's Linux talk
so I'll skip it here.

I find his rationale for using Python to be poor. It is lumped between
two bullets for 'Mail Transfer Agent' and 'Java-like environment'. His
reasoning for using Python is terse - essentially because he couldn't
use Ruby.

Maybe he was typing this up in a rush, but regardless. The reasons he
has given for making Python the primary 'interpretive'(wtf?) language
are unclear. I could think of a hundred reasons for it, but that's not
my job, it's his.

I wouldn't call what he said a jibe, given that he shows no
understanding of what Python is about. If he isn't or hasn't been an
enlightened one, then how can he insult us? :)


David.
 
J

John Roth

Skip Montanaro said:
Python's design doesn't admit the option of calling functions without the
parens. Perl's and Ruby's do. On the other hand, functions are first-class
objects in Python. I don't know about Ruby, but in Perl, whether or not a
function is called or treated as a piece of data is very context-dependent,
to the point of near madness for people like myself who don't use it day in
and day out.

That's one of the reasons it was a rather bad choice of example.
As far as I can tell, it would be quite hard to do in any comprehensible
fashion, and not backward compatible.
John> The jihad against the "functional" builtins is a good case in
John> point. The replacements for apply, map and filter seem to be
John> adequate, and in the case of list comprehensions, pretty darned
John> useful although I think that it's a rather baroque addition to an
John> otherwise very clear and comprehensible language.

Why do you call it a "jihad"? Guido has stated on multiple occasions that
he regretted adding functional constructs to the language. I still can't
get to the Python website (have to wait another two hours for my ISP to
reload its tables), but here's a Google pointer to an HTML-ized version of
his OSCON 2002 Powerpoint slides:
http://216.239.41.104/search?q=cach...ets.ppt+OSCON+"python+regrets"&hl=en&ie=UTF-8

I've read it before. I'm in complete agreement that the replacement
for apply makes the lanugage cleaner, and I've no particular objection
to list comprehensions replacing map and filter.
John> There is no replacement for lambda in sight, even though lambda is
John> arguably the ***largest single*** one of the functional constructs
John> that needs work, and has obviously needed work for a long time.

Once again, you desire Python to be something it is not. If you want a
strong functional language, program in Lisp or Haskell.

John> The obvious replacement for lambda, which is some form of inline
John> block, has not been seriously discussed, with proposed syntax and
John> examples, anywhere I've seen it. Clearly, I'm not ominiscient, so
John> that doesn't mean it hasn't, though.

Anonymous blocks are not a replacement for lambdas, named functions are.
How do you pass parameters to an anonymous block?

By putting them in the first line. Again, I'm not a language purist, and
if the term 'block' means something to someone that causes confusion,
then I regret it.

Frankly, I don't think that anyone is going to come up with the ideal
syntax for anonymous functions. The thing that becomes more and
more apparent every time I think of it is that one of Python's real
strengths,
it's automatic indentation, also makes it very hard to incorporate statement
syntax within expressions.
You seem to have a burr under your saddle about this stuff. I'm not sure
why. Maybe it's time to get out the curry comb.

The world changes, and ideas that seemed to be perfectly appropriate
five or ten years ago may no longer be such. Small languages with a limited
audience have a perfect right to be as quirky or as "pure" as their authors
want. Once they get beyond that point, there's a bit of social
responsibility
involved in addressing common problems.

John Roth
 
J

John Roth

Oren Tirosh said:
You mean like this?

def generator(...):
sequencing logic, yield stuff

for object in generator(...):
processing logic

Good point. That's upside down from the way I usually
think of it.
Can you give any specific reasons why you believe this to be the
case?

Yes. You now have two sequencing constructs: the for loop
and the loop inside the generator. The visitor pattern has only
one: the for loop inside the .visit() method.

John Roth
 
J

Jarek Zgoda

David M. Wilson said:
Unless you design some silly rules to determine when empty parenthesis
should be allowed - did a get assigned the return value of sys.exit()?
(yes I know it doesn't have one)

It has. The returned value is None.
 
D

Dennis Lee Bieber

John Roth fed this fish to the penguins on Saturday 20 December 2003
04:19 am:

John Osterhout (TCL). I want a language I can embed in tools as a
common scripting language.
Given that last entry, I'll speak blasphemy since I feel there is a
fifth candidate. REXX, especially as implemented on the Amiga, /was/
such a common scripting language without needing to be "embedded"
within the application/tool (it actually was done in a way that
permitted one script to glue multiple "tools" together).


--
 
J

John Roth

Dennis Lee Bieber said:
John Roth fed this fish to the penguins on Saturday 20 December 2003
04:19 am:


Given that last entry, I'll speak blasphemy since I feel there is a
fifth candidate. REXX, especially as implemented on the Amiga, /was/
such a common scripting language without needing to be "embedded"
within the application/tool (it actually was done in a way that
permitted one script to glue multiple "tools" together).

Oh, there were a lot of those languages, but that was what
Osterhout wanted for TCL - something that could be embedded
in various tools. He had a problem, and it was lots of tools, each
of which used its own special purpose, completely incompatible
and usually poorly implemented language.

REXX was very much a niche specific language, mostly on
IBM systems (because IBM also wanted to consolidate
languages.) It grew beyond there, but not by all that much.
Part of it's quirky charm is the way that it's i/o system faithfully
mirrored the old VM/CMS system.

John Roth



============================================= <
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,277
Latest member
VytoKetoReview

Latest Threads

Top