Gmail
Calendar
Documents
Photos
Reader
Web
more
Mr G
« Groups Home
comp.lang.apl
Discussions
+ new post
About this group
Edit my subscription
This is a Usenet group - learn more View this group in the new Google Groups
Modern APL practices
Options
Messages 1 - 25 of 30 - Collapse all - Report discussion as spam Newer >
Aaron W. Hsu View profile
More options Feb 13, 7:47 pm
I am quite new to APL, but I am fascinated by the readings I have found so
far. Particularly, the programming methodology of avoiding klunky control
structures and the like. On the other hand, when I read about the versions
of APL out there, it seems like so many of the new advances are in adding
more traditional control structures and things like OOP, which is kind of
disappointing to my image of APL as a different way of thinking about
problems.
Can anyone share their thoughts on the frequency of using these control
structures and whether they are used as often as traditional control
patterns in APL? Being more than a newbie, I am quite curious about
whether modern APL still is written in the same style as time past, or
whether OOP and If-then-else forms have become the standard practice
instead?
Aaron W. Hsu
--
Programming is just another word for the lost art of thinking.
Reply Reply to author Forward Report spam Rate this post:
Phil Last View profile
More options Feb 14, 3:55 am
On Feb 14, 2:47 am, "Aaron W. Hsu"
- Show quoted text -
This is a purely personal statement and I should say I'm probably in a
minority of one.
I use almost exclusively the more-or-less functional subset of
DyalogAPL called DFNS (direct functions). I only don't write a DFN
when I can't do what I want to do by writing one. The things you'd be
ashamed to admit to having to write anyway. They don't allow
"traditional" control structures and I've never found a need for them
as user defined syntax operators could already do all the things they
do, more concisely and more elegantly, a good five years before
control structures were introduced.
There seems to be a feeling among the vendors that the more similar
APL is to all other run-of-the-mill computer languages the more users
and purse-string-holders are going to flock to it.
As to examples of use of control structures I once removed a six
line :FOR loop by substituting a single inner product but my change
was reversed after peer review because it would have upset the natives.
Reply Reply to author Forward Report spam Rate this post:
Your post was successful
Stephen Taylor
More options Feb 14, 10:40 am
On Feb 14, 10:55 am, Phil Last
- Show quoted text -
Phil illustrates a condition that applies to writing of all kinds:
write for your readers.
Who are your readers? One of the most important is yourself in the
future. Careful writing in the present preserves your insights and
thinking and reduces the cost of maintenance. As a general rule I
prefer to write at the highest level of abstraction I can handle. As
Arthur Whitney said, “It’s a lot easier to find the errors in 4 lines
[of K] than 400 lines [of C].” This also matches my philosophy
professor’s advice on style: “Write so you see your mistakes before
your colleagues do.”
If I have other readers, I must write for them too. Some of them might
not be programmers! I commonly collaborate with ‘domain experts’ who
are grappling with the logic of a problem as we work. I write for them
by – as far as I can – naming only quantities they refer to, and using
their names for those quantities. The value of this is very high, and
virtually unknown outside APL circles. In APL circles, it is sometimes
known as ‘semantic density’, the proportion of the defined names that
are drawn from the user’s vocabulary. (Functional style in general and
Dyalog’s anonymous D-fns in particular are brilliant for this.) In
some agile development circles, this is known as the ‘ubiquitous
common language’. It is valued there as a vocabulary in which to
discuss what the code does. In a very few languages, notably the APLs,
you can achieve a semantic density high enough that you can share the
code with a non-programmer.
This buys something very valuable. Your domain expert can follow the
_flow_ of a calculation and see how one quantity is derived from
others. Just this morning I had a non-programming expert review code I
had written and propose a change, because it was clear to her that a
quantity we should have been using was not incorporated. In terms of
devt time, this is gold.
We must also write for our colleagues. This is a grief to writers like
Phil Last, for most of us struggle to achieve his facility with
abstraction. It is right for us to try, and for Phil to encourage us,
because we improve. This is what education looks like – learning to
reason at higher levels of abstraction. But unless you have a client
who is happy for you to be the sole author – probably you are your
only such client – you will need to write for your colleagues. (And in
response to Phil, I can only quote an unknown Australian: “I’m no
native, I was bloody born here!”)
Lastly we write for our unknown successors, whom we hope will be
smarter and more compassionate than we, and will find and correct our
errors without making too much fuss about them. These are the hardest
readers to write for, because we can only guess their skills.
APL’s reputation has suffered here. Its expressive powers mean that
careless writing can be spectacularly hard to read. (“When she was
good, she was very, very good/But when she was bad, she was horrid.”)
Esoteric technology attracts intolerant mavericks. Whether your
successor is an argumentative eccentric, or a scalar programmer who
would rather be working at lower levels of abstraction, it will be all
too easy for him to persuade management his predecessor was an oaf, or
that APL, with its funky character set, is inherently a write-only
language.
Your job as an author is to write for your readers. Morten Kromberg is
justly proud of his ability to code in anyone else’s style, merging
his changes in seamlessly. He is often called in as a troubleshooter,
so this is a great and generous skill. In contrast, I fantasise that I
can write with such clarity that others will prefer and mimic my
expressions – such is the vanity of poets. I am currently finishing a
rewrite of a core part of an application system. The earlier version
involved scores of similarly-named vectors and literally hundreds of
repetitive lines of code. The new version avoids the verbose and error-
prone replication. Each logical move is made once. But the ‘moves’ are
now defined on arrays of ranks 6 to 8. Before embarking on this higher
degree of abstraction, I had to negotiate the – cautious – agreement
of my colleagues.
Back to our question, and control structures. I avoid their verbosity
where the test is simple. APL provides many ways of doing this. Where
a test is not simple, it is usually better separated from its
consequences. Most non-programmers have difficulty reading non-trivial
boolean expressions. Particularly where a sequence of tests is tried,
control structures can make the logic very much clearer. I recommend
relying on – and sharpening – your aesthetic sense.
You ask also about OOP. While old timers such as I will insist in our
cups that one could get _anything_ done in quite early implementations
of APL, it was always wrong to see APL as the last programming
language. OOP is a good and widely-understood way to present a complex
interface, not a falling back from some purer and truer approach. (If
APL enabled a better description of GUIs than OOP, for example, you’d
think we should have found it by now.) A similar point could be made
about – oh, regular expressions. Be wary of your inner hunger for A
Perfect Language.
In my world your question is very important and practical. I spend
roughly half my devt time getting logic correct, the rest seeking more
clarity. The goal – often approached, occasionally reached – is code
that runs right first time, is well understood, and that welcomes a
return visit.
HTH
Stephen Taylor
Reply Reply to author Forward Report spam Rate this post:
Aaron W. Hsu View profile
More options Feb 14, 2:53 pm
Stephen:
Thank you for your detailed thoughts. Regarding your comments below, it
might help if I give my background. I am a long time Scheme programmer, so
my normal mode of operation is to break a problem down into layers of
abstractions, considering data, procedural, and syntactic layers that
might be of use to me. Occasionally, this leads me towards an OOP
solution, though usually in a different syntactic form than, say, Java,
but normally the solution is a combination of simple data abstraction,
careful functional arrangement and the right touch of syntax to bring it
all to center.
Scheme's ability to implement any programming paradigm as a native element
of the language, and the support of Unicode in program source has led me
to consider creating a library to embed the language of APL into Scheme.
This leads me to the question of control flow in APL programs. I want to
know what is worth having and what is not. For example, should I keep the
→ (branch) functionality, and if so, what is the best way to situate it
within the context of Scheme? Many things such as the :If style control
structures seem redundant when APL is considered as a sub-language of
Scheme, and if everyone just uses those, then maybe it is not worth
implementing other control structures. On the other hand, if the other
structures lend something useful to the language, then I do wish to add
them.
Aaron W. Hsu
On Mon, 14 Feb 2011 12:40:00 -0500, Stephen Taylor
- Show quoted text -
--
Programming is just another word for the lost art of thinking.
Reply Reply to author Forward Report spam Rate this post:
Aaron W. Hsu View profile
More options Feb 14, 2:54 pm
On Mon, 14 Feb 2011 05:55:40 -0500, Phil Last
wrote:
> There seems to be a feeling among the vendors that the more similar
> APL is to all other run-of-the-mill computer languages the more users
> and purse-string-holders are going to flock to it.
:-) As a Scheme programmer, doing that sort of thing is definitely not the
way to get me to flock to it.
> As to examples of use of control structures I once removed a six
> line :FOR loop by substituting a single inner product but my change
> was reversed after peer review because it would have upset the natives.
That surprises me. I happen to really like the inner product.
Aaron W. Hsu
--
Programming is just another word for the lost art of thinking.
Reply Reply to author Forward Report spam Rate this post:
Stephen Taylor
More options Feb 15, 11:58 am
On Feb 14, 9:53 pm, "Aaron W. Hsu"
- Show quoted text -
Specifically on branch arrows: I have never used one since control
structures became available.
Like Phil, I find Dyalog's d-fns (especially the 'anonymous lambdas')
most convenient for control of flow.
SJT
Reply Reply to author Forward Report spam Rate this post:
Paul Mansour View profile
More options Feb 15, 8:12 pm
On Feb 13, 9:47 pm, "Aaron W. Hsu"
- Show quoted text -
I view control structures and OO extentsions in very different lights
with respect to APL.
Nintey nine percent of the time, control structures are unneccessary,
and contrary to popular belief, do not add clarity. I let my functions
do the controlling, with the only structure being the guard, to exit a
function with a given result, which is often the result of another
function. (I never use traditional branches or labels) I sometimes
find control structures useful when I am working out a problem, but
they don't remain for long. They are a sign of unfinished code, or
code that is not "clean" (see Robert C. Martin's "Clean Code"), and
generally indicate that the problem was not fully and deeply
understood and refactored properly. (Of course, one use of control
structures is a quick fix to an existing function that you have
neither the time nor inclination to refactor properly - but that
really is not a good thing in the long run). I view them as very un-
APL. I'm afraid that Phil and I may be a group of two in this regard.
OO on the other hand, meshes perfectly with a traditional APL style.
In one respect, OO is just another way to let your functions do the
controlling (what is polymorphism but a case statement?) Arrays and
objects work together quite well - you can have arrays of objects,
giving the full power of APL to operatate on objects, and objects
encapulating arrays. There is nothing inheritantly un-APL like about
OO. That being said, the apparatus in some APL implementations needed
to generate class definitions can look quite un-APL like, and that is
a bit annoying, and I would have preferred some different approaches.
The results however, of using objects, is pure APL as far as I am
concerned. For example consider the expression:
m.f v
Where m is an array of objects (perhaps of different types), f is a
method supported by all the types in m, and v is an array with the
same shape as m. This is powerful stuff, and very much APL.
Reply Reply to author Forward Report spam Rate this post:
Paul Mansour View profile
More options Feb 15, 8:25 pm
On Feb 14, 12:40 pm, "Stephen Taylor
- Show quoted text -
Stephen, I have to take issue with your contrast of APL and OOP. OOP
is not a programming language, but a way to organize code. I think it
is completely orthogonal to APL. And it is a testament to the power
and simplicity of APL that objects integrate so seamlessly. What is
more natural in APL than a array of objects, be they customers, bank
accounts, or buttons on a form?
Reply Reply to author Forward Report spam Rate this post:
Paul Mansour View profile
More options Feb 16, 9:52 am
On Feb 15, 10:25 pm, Paul Mansour
> Stephen, I have to take issue with your contrast of APL and OOP. OOP
> is not a programming language, but a way to organize code. I think it
> is completely orthogonal to APL. And it is a testament to the power
> and simplicity of APL that objects integrate so seamlessly. What is
> more natural in APL than a array of objects, be they customers, bank
> accounts, or buttons on a form?- Hide quoted text -
> - Show quoted text -
Stephen, I should have noted that this is a minor quibble with your
excellent essay in response to Aaron's question. It's always a
pleasure to read your always insightfull and well written thoughts on
programming.
Reply Reply to author Forward Report spam Rate this post:
Phil Last View profile
More options Feb 16, 3:30 pm
On Feb 16, 4:52 pm, Paul Mansour
- Show quoted text -
Right on. As it were.
Reply Reply to author Forward Report spam Rate this post:
kai View profile
More options Feb 17, 1:44 am
Regarding control structures: it all depends.
Since I started to work in a team with Paul Mansour and Phil Last my
style has changed a lot: I write dfns rather than tfns except when I
have a very good reason not to, and that is the case in 10-20% of my
functions.
However, for maintenance control structures are often preferable.
Constructs like:
dfns6 dfns5 dfns4 dfns3 dfns2 dfns1¨ array
for example might be considered elegant and nice but are in fact
inappropriate: When there is a problem in dfns6, tracing into it can
be a pain.
Also:
key≡0 1:dfns1 array1
key≡0 13:dfns1 array1
key≡2 112:dfns1 array1
....
are no match to
:Select key
Case: 0 1
dfns1 array1
Case: 0 2
dfns1 array2
Case: 0 3
dfns1 array3
:else
. ⍝ MUST NOT happen!
:EndSelect
This is not a matter of readability, it's a matter of maintainability:
the second one is MUCH easier to trace through.
In short: Compared with other languages I use control structures not
often but I am happy that they do exist, and I use them when they make
my live easier, and the often do.
Reply Reply to author Forward Report spam Rate this post:
Stephen Taylor
More options Feb 17, 4:28 am
Paul, you are right to take me to task – for leaving that impression.
I loved the object paradigm since I read the first article about
Smalltalk, in BYTE Magazine, Aug 1981. It has influenced my thinking
about a range of subjects, including, most lately, political
philosophy:
http://www.opendemocracy.net/ourkingdom/michael-birnhack/we-need-stro...
Despite that, for a long time I wondered if there might not be a
‘functional’ way to write GUI. Nah. Now if someone devised one I doubt
I would want to use it.
We agree, I think, on avoiding branch arrows, for the same reasons
Djikstra marshalled against GOTOs. We both prefer, I think, using
constructions such as X←↑test⌽Y Z to if/then/else. We both admire and
prefer the minimalist control structures afforded by D-fns.
We both work in somewhat mathematical application domains. I have the
impression that my application domain – valuing British pension
liabilities – is messier than yours, the math muddied with the
accumulated silt of decades of legislation. I can believe that in the
purer air you breathe, control structures can always be refactored
into something mathematical. But I doubt strongly that the claim can
be generalised.
But even if it could, it falls under my prescriptions about writing
for your readers. You collaborate with Phil Last and Kai Jaeger, lucky
you. My readers include people for whom, in some contexts,
:If X0
:AndIf …
is the best 'tool for thinking' I have been able to provide.
On Feb 16, 3:25 am, Paul Mansour
- Show quoted text -
Reply Reply to author Forward Report spam Rate this post:
Bjorn View profile
More options Feb 17, 4:34 am
On 14 Feb, 02:47, "Aaron W. Hsu"
- Show quoted text -
The introduction of OOP techniques in APL solves a problem that
existed before that time.
It has not much to do with APL as such but rather the fact that when
systems written in APL had to deal with a lot of names together at the
same time in the WS.
For small systems with few functions this does not matter.
Once you begin to make a system bigger and add more functionality the
solution was to divide the system into many Ws:es and use prefixes and
suffixes and there were endless rules created to use within the
system.
With the advent of OOP and the option to control a system from a
central space and divide the different parts into various namespaces
is a major advantage and makes life a lot easier.
If/when you add a lot of people into a project you may need to get
people with a background from other languages and people used to
control structures it is good to have the option withing APL to assist
those people to work in APL as well.
So having new techniques available to make life easier for people of
different backgrounds as well as extending the range of tools
available to people working in/with APL has made APL even more useful
user friendly and giving APL programmers the option of making bigger
and better systems with more ease.
Reply Reply to author Forward Report spam Rate this post:
Randy MacDonald View profile
More options Feb 17, 7:06 am
Paul Mansour
news:bc743060-fe6d-45b6-8e68-115d6c644d5f@s18g2000vbe.googlegroups.com:
...
> For example consider the expression:
> m.f v
> Where m is an array of objects (perhaps of different types), f is a
> method supported by all the types in m, and v is an array with the
> same shape as m. This is powerful stuff, and very much APL.
Also, it can be written:
v 'f' to m -- 'to' created in 1992, btw...
without waiting for the dot to move from function to syntax.
Reply Reply to author Forward Report spam Rate this post:
Aaron W. Hsu View profile
More options Feb 17, 3:52 pm
On Thu, 17 Feb 2011 03:44:49 -0500, kai
wrote:
> In short: Compared with other languages I use control structures not
> often but I am happy that they do exist, and I use them when they make
> my live easier, and the often do.
Thanks to everyone for their comments. These comments continue to be very
educational and interesting.
Aaron W. Hsu
--
Programming is just another word for the lost art of thinking.
Reply Reply to author Forward Report spam Rate this post:
phil chastney View profile
More options Feb 18, 9:37 am
On 2011/Feb/14 10:55, Phil Last wrote:
> As to examples of use of control structures I once removed a six
> line :FOR loop by substituting a single inner product but my change
> was reversed after peer review because it would have upset the natives.
just as a marra interest, where you allowed
to retain such esoterica as × and ÷
/phil
Reply Reply to author Forward Report spam Rate this post:
phil chastney View profile
More options Feb 18, 9:45 am
On 2011/Feb/14 21:53, Aaron W. Hsu wrote:
>
> example, should I keep the → (branch) functionality, and if so, what is
> the best way to situate it within the context of Scheme?
before deciding whether to dump the branch arrow, you might like to
remember that, when structured programming was the height of fashion,
Knuth produced a very simple problem whose solution using a branch arrow
was simpler than a solution using structured programming
I believe the paper was called "Structured Programming Considered
Harmful" -- damned if I can remember why
/phil
Reply Reply to author Forward Report spam Rate this post:
Aaron W. Hsu View profile
More options Feb 18, 10:48 pm
On Fri, 18 Feb 2011 11:45:55 -0500, phil chastney
> I believe the paper was called "Structured Programming Considered
> Harmful" -- damned if I can remember why
Yes, that is a very interesting paper with which I am familiar. I use
continuations in Scheme, which are basically GOTOs, so, I am not a staunch
detractor of its virtues.
Aaron W. Hsu
--
Programming is just another word for the lost art of thinking.
Reply Reply to author Forward Report spam Rate this post:
Paul Mansour View profile
More options Feb 19, 6:10 am
On Feb 17, 6:28 am, "Stephen Taylor
- Show quoted text -
Stephen,
A couple of thoughts:
It's definitely true that when you have a "clean" problem - far
removed from business particulars, that it is easier to write without
control structures. I would question whether the folks you are writing
for or with who need structures like:
:If X0
:AndIf …
should be considered APL programmers or "business scripters" using a
domain specific language.
And I would include myself in those who need these structures when
faced with the minutia and arbitrary stuff of pensions and what not. I
agree its the best way to layout the problem for clarity and
maintenance.
In fact, in my app, we provide scripting, which does indeed included
all the control structures, and allows the end users to script using
objects we provide them, many of which are thin covers for APL things.
This just provides a clear separation between pure, functional (ok,
well, mostly!) system code and messy, loopy, if-then-elsy user code.
Paul
Reply Reply to author Forward Report spam Rate this post:
Bakul Shah View profile
More options Feb 19, 1:40 pm
On 2/14/11 9:40 AM, Stephen Taylor
- Show quoted text -
This is a very nice article on what every programmer should keep in mind!
> Back to our question, and control structures. I avoid their verbosity
> where the test is simple. APL provides many ways of doing this. Where
> a test is not simple, it is usually better separated from its
> consequences. Most non-programmers have difficulty reading non-trivial
> boolean expressions. Particularly where a sequence of tests is tried,
> control structures can make the logic very much clearer. I recommend
> relying on – and sharpening – your aesthetic sense.
Also note that often more control structures are required when one is
programming in smaller chunks (item at a time instead of whole structure).
This is often easier to grasp but can be more error prone. Stringing
together higher order functions (or operators) can also make it harder
to grasp what is going on.
> You ask also about OOP. While old timers such as I will insist in our
> cups that one could get _anything_ done in quite early implementations
> of APL, it was always wrong to see APL as the last programming
> language. OOP is a good and widely-understood way to present a complex
> interface, not a falling back from some purer and truer approach. (If
> APL enabled a better description of GUIs than OOP, for example, you’d
> think we should have found it by now.) A similar point could be made
> about – oh, regular expressions. Be wary of your inner hunger for A
> Perfect Language.
I got off the OOP bandwagon ever since I started using C++! I think
given arrays, functions, associative arrays ("dictionaries"), tables
and streams one can do anything! The rest is mere syntactic sugar and
too much of that has made modern OOPLs' middles very fat:-)
> In my world your question is very important and practical. I spend
> roughly half my devt time getting logic correct, the rest seeking more
> clarity. The goal – often approached, occasionally reached – is code
> that runs right first time, is well understood, and that welcomes a
> return visit.
I too find that a few iterations to improve API clarity and code
clarity pays off handsomely. At least for me this process is never
finished; I stop working on some piece of code once some goal or,
more often, some constraint is reached. Just like a painting is
never finished!
Reply Reply to author Forward Report spam Rate this post:
Roberto Waltman View profile
More options Feb 20, 9:03 am
phil chastney wrote:
>...
>Knuth produced a very simple problem whose solution using a branch arrow
>was simpler than a solution using structured programming
>I believe the paper was called "Structured Programming Considered
>Harmful" -- damned if I can remember why
(Off topic) You are justified to block these memories.
The paper was by Slater & Modell, here:
http://www.modell.com/Magery/SPharmful.html
Introducing the COMEFROM statement, DON'T WHILE block, etc.
--
Roberto Waltman
[ Please reply to the group,
return address is invalid ]
Reply Reply to author Forward Report spam Rate this post:
James J. Weinkam View profile
More options Feb 20, 9:46 pm
Roberto Waltman wrote:
> phil chastney wrote:
>> ...
>> Knuth produced a very simple problem whose solution using a branch arrow
>> was simpler than a solution using structured programming
>> I believe the paper was called "Structured Programming Considered
>> Harmful" -- damned if I can remember why
The Knuth paper Phil is thinking of is "Structured Programming with GOTO Statements." It appeared in
Computing Surveys in 1974.
> (Off topic) You are justified to block these memories.
> The paper was by Slater& Modell, here:
> http://www.modell.com/Magery/SPharmful.html
> Introducing the COMEFROM statement, DON'T WHILE block, etc.
> --
This paper was a send up of the flood of "... considered harmful" articles published in the years
following Djikstra's "GOTO Statement Considered Harmful." That was actually a letter to the editor
in CACM and the title was supplied by the editor, not Djikstra.
Reply Reply to author Forward Report spam Rate this post:
phil chastney View profile
More options Feb 21, 2:53 am
On 2011/Feb/21 04:46, James J. Weinkam wrote:
- Show quoted text -
thank you, James
I knew it wasn't CACM and it wasn't JACM -- all I could dredge up was
the smaller page size of Computing Surveys, and (possibly) a green cover
/phil
Reply Reply to author Forward Report spam Rate this post:
Peter Keller View profile
More options Feb 28, 10:21 am
Aaron W. Hsu
> On Fri, 18 Feb 2011 11:45:55 -0500, phil chastney
>
>> I believe the paper was called "Structured Programming Considered
>> Harmful" -- damned if I can remember why
> Yes, that is a very interesting paper with which I am familiar. I use
> continuations in Scheme, which are basically GOTOs, so, I am not a staunch
> detractor of its virtues.
Continuations are not basically like GOTOs. :)
Calling a continuation not only changes the control flow to where
the continuation was taken (and becoming the result with which you
invoked the continuation) BUT ALSO changes ALL in scope bindings at
the outer stack frames to the values they had when the continuation
was taken. This is _very different_ behavior than simply a goto.
Most languages use a stack based discipline. Restricted continuations,
those which cannot be invoked outside of their extent, force the stack
discipline into a tree discipline. Indefinite extent continuations,
those of Scheme's, can cause the stack discipline to be a graph
discipline instead.
Continuations are not only more powerful than gotos, but you can
actually implement ALL forms of control manipulation with them. From
the lowly goto to exception handling, to loops, to threads, to anywhere
in between or beyond.
-pete
Reply Reply to author Forward Report spam Rate this post:
phil chastney View profile
More options Feb 28, 11:17 am
On 2011/Feb/28 17:21, Peter Keller wrote:
- Show quoted text -
I first came across the term "continuations" in Dana Scott's writings,
where they were introduced as a means of formalising a "mathematical"
description of the simple GOTO
("mathematical" in the sense that it could be derived from Set Theory)
the equivalence of the Lambda Calculus and Recursive Function Theory, I
believe, only requires the ability to take the current continuation, and
then call it within the same frame of reference
since then the concept has been generalised and, as you so rightly point
out, it can now be used to implement all forms of control
that being so, if Aaron's msg had read "continuations ... are basically
a generalisation of GOTOs", then surely that would have been acceptable?
/phil
Reply Reply to author Forward Report spam Rate this post:
Messages 1 - 25 of 30 Newer >
« Back to Discussions « Newer topic Older topic »
Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2011 Google
No comments:
Post a Comment