merits of Lisp vs Python

P

Paul Rubin

Jon Harrop said:
It is not "just like in Scheme" if you don't have anonymous functions in
Python.

Python has anonymous functions (what they can do is somewhat limited
by syntax) but the similarity mentioned with Scheme was about the data
objects. Anyway you don't need to pollute the namespace with lots of
(i.e. more than one) different temporary function name even if you use
non-anonymous functions.
 
P

Paul Rubin

Kay Schluehr said:
Could you explain in which way Python lacks lexical scoping?

Python has lexical scope but you can't update lexical variables from
scopes other than the innermost or outermost (global) scope. I.e:

def counter():
x = 0
def g():
x += 1
return x
return g

c = counter()
print c()

doesn't do what you'd hope. Yes there are workarounds but they're not
all that satisfactory.
 
P

Paul Rubin

Wolfram Fenske said:
Yes, I wrote about it in another post. It was introduced in Python
2.5. And if it hadn't been I'd still have to write code like this.

You could do something with decorators that's not too bad. You'd end
up writing:

@withConnection
def some_func():
do_whatever_stuff ()
 
P

Paul Rubin

Jon Harrop said:
I discovered this recently with F#. Although F# (as a dialect of OCaml) is
impure like Lisp, it does make purely functional programming easy and
provides many purely functional data structures. I translated 15kLOC of
mostly-functional OCaml code into F# and only had to add four locks to make
the whole library concurrent.

The idea of the composable-STM stuff is to not add locks at all, just
mark sections as atomic and the right stuff happens automagically
(i.e. you never have to worry about deadlock), including when you nest
such sections. Its performance also exceeds traditional locking. But
it relies on Haskell's purity.
 
J

Jon Harrop

Paul said:
Jon Harrop said:
# cond 2
[( = ) 1, "one";
( = ) 2, "two";
( = ) 3, "three"]
"neither one, two nor three";;
- : string = "two"

I'm missing something. Doesn't Ocaml have strict evaluation?
Yes.

That means if you use function calls instead of string constants in those
values, they all get called.
True.

You haven't really done what cond does.

Good point. How about this:

# let rec cond x rules default = match rules with
| [] -> default
| f :: t -> match f x with
| Some e -> e
| None -> cond x t default;;
val cond : 'a -> ('a -> 'b option) list -> 'b -> 'b = <fun>

# cond 2
[(fun n -> if n=1 then Some "one" else None);
(fun n -> if n=2 then Some "two" else None);
(fun n -> if n=3 then Some "three" else None)]
"neither one, two nor three";;
- : string = "two"

The 'Some "one"' is only called if its predicate matched. Anyway, you don't
need macros to write COND and you don't need COND if you have pattern
matching.
 
J

Jon Harrop

Paul said:
The idea of the composable-STM stuff is to not add locks at all, just
mark sections as atomic and the right stuff happens automagically
(i.e. you never have to worry about deadlock), including when you nest
such sections. Its performance also exceeds traditional locking. But
it relies on Haskell's purity.

Yes. My point is that I only had to add four locks in 15kLOC of F# code
because my code was almost entirely pure. So F# is a long way towards that
Haskell ideal whilst having many other advantages over Haskell, like
predictable memory usage.
 
A

Alex Mizrahi

(message (Hello 'Paul)
(you :wrote :eek:n '(10 Dec 2006 00:01:34 -0800))
(

PR> I'm not persuaded, I haven't examined his example carefully yet but it
PR> looks like basically a reader hack. Lexical scope in Lisp means among
PR> other things lexical closures and (maybe I'm mistaken) it seemed to me
PR> Alex's example didn't supply that.

lexical scope is pretty low-level concept that affects lot of stuff, so it
requires lot of changes -- we are not extending a language, but build a new
one actually.
we'll have to create object 'lexical environment' and to query it for
variable values instead of just using variable values: var -> (query env
'var).
then, we'll need to make closures -- that is a pair of environment and code
itself.
so, it's very close to writting new interpreter -- but it's order of
magnitude easier to write this interpreter via macros than from scratch,
most other language constructs can be reused.
that's the point -- macros allow to implement a language with aprox. same
syntax but different semantics relatively easily.

PR> I'm also unconvinced (so far) of his description of call/cc as a Lisp
PR> macro but that's going to take me some head scratching.

there is a chapter about continuations in Paul Graham's "On Lisp".

"Common Lisp doesn't provide call/cc, but with a little extra effort we can
do the same things as we can in Scheme. This section shows how to use macros
to build continuations in Common Lisp programs."

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity")
 
P

Paul Rubin

Jon Harrop said:
Yes. My point is that I only had to add four locks in 15kLOC of F# code
because my code was almost entirely pure.

But that's like saying you only had to call malloc in 4 different
places, which means dealing with freeing, buffer overruns, etc. As
soon as you use any locks at all, you're susceptable to all the
headaches of dealing with locks. Anyway this is turning into
ML vs. Haskell, maybe an improvement on Lisp vs. Python but still OT.
So F# is a long way towards that Haskell ideal whilst having many
other advantages over Haskell, like predictable memory usage.

F# is pretty similar to ML, right? Hmm. Haskell's memory usage
issues stem more from laziness than purity. One could imagine a
strict Haskell dialect that was still pure (I think ML is heading
in that direction) but that would throw out a lot of Haskell coolness.

Does OCaml support parallel threads at all? I mean using multiple
cpu's simultaneously. I thought it didn't and this was one of the
factors that got me to make the leap into Haskell.
 
P

Paul Rubin

Alex Mizrahi said:
so, it's very close to writting new interpreter -- but it's order of
magnitude easier to write this interpreter via macros than from scratch,
most other language constructs can be reused.

But now you've got an interpreter and you no longer have that Lisp
compiler.
there is a chapter about continuations in Paul Graham's "On Lisp".

"Common Lisp doesn't provide call/cc, but with a little extra effort we can
do the same things as we can in Scheme. This section shows how to use macros
to build continuations in Common Lisp programs."

I think he's mistaken about being able to implement call/cc in full
generality with CL macros in any reasonable way. But it might be
possible to implement enough to do something like Python generators
using lexical closures that one re-enters through some kind of cond
statement selecting the yield point to be continued from.
 
R

Ramon Diaz-Uriarte

If someone handed you a calculus book written in Latin, you'd probably
find it undesirably old-fashioned too.

I think the "reasoning by analogy" is clearly showing its weakness
here (truth is, it was me who used the analogy to begin with). However
since (and this is no cynicism) I do really respect and find thought
provoking most of what you write,

how is Lisp similar to a calculus book written in Latin (or to the
Latin in the calculus book, or whatever)? What exactly is
"old-fashioned" supposed to mean here, and how does it carry a truly
negative connotation?

R.

P.D. I am only now starting with Lisp, after having written a lot of
Python for the last two years.
--
Ramon Diaz-Uriarte
Statistical Computing Team
Structural Biology and Biocomputing Programme
Spanish National Cancer Centre (CNIO)
http://ligarto.org/rdiaz
 
S

Steven D'Aprano

Of course I didn't say that: What I said was, "To start with,
English does not restrict the expressiveness and
power of the syntax and grammar. People who use the English language
in specific communities and in specific forms of discourse do.

Hang on... are you saying that *people* create languages?

*slaps head*

And here I was thinking that languages fell from the sky like donuts!
Gosh, thank you for explaining that too me. What a fool I must seem!

By the way, that was sarcasm. Of course the English language doesn't exist
in a vacuum. Of course people -- not rocks, not trees, not the Greek
Furies, and especially not the Academie Francaise -- create languages.
And, as an Australian in a world dominated by Americans, I know damn well
that different communities of English speakers use different rules.

*Slightly* different rules. That's why Standard American English and
British English are both English, not different languages like Italian and
German or Korean and Russian.

[snip]
As an example of the context-specific nature of pragmatics at work,
if I was your reviewer or editor, I'd reject this manuscript.

Perhaps you should find out what "manuscript" means before talking about
rejecting one, because what I wrote was most certainly not a manuscript in
any English language I'm aware of.
As a
participant on usenet, I'll just point out that you selectively
quoted the antithesis, and deleted my thesis to argue a straw-man.

Look, I was arguing a really simple point: for communication to occur
between two individuals, both people must agree on a set of rules for the
language that they use to communicate. If they don't have a common
language with agreed upon rules, communication will be feeble and weak, if
not non-existent, or there will be misunderstandings and errors.

Is that so hard to grasp? If you ask for "fire water", by which you
mean whiskey, but I understand to be petrol (gasoline), you're going
to be a very sick person indeed if you drink what I give you.

Of course there are restrictions, *enforced by users of language in
specific communities.* But the English language is quite malleable,
and includes not only the discourse we are currently engaged in, but
the clipped jargon of internet chat and amateur radio, the
chronically passive discourse of academia, the passionate chants of
protesters, and a wide variety of poetic expression.

Did I say it wasn't malleable? You are attacking me for things I never
said.

This is where wannabe critics of "English grammar" fail to
understand the language they claim to defend, much to the amusement
of those of us who actually do study language as it is, rather than
the mythical eternal logos we want it to be.

Ho ho ho, have you ever jumped to a foolish conclusion. You think I'm one
of those tiresome bores who think that just because the ancient Romans
couldn't end a sentence with a preposition, English shouldn't either?
Puh-lease!

Languages are (with some trivial exceptions) human creations. The
laws, rules and restrictions of languages are dynamic and dependent
on community, mode, medium and context. Of course, wannabe
grammarians frequently rise up at this point and say that if such is
the case, then there is nothing to prevent <language of choice> from
devolving into a babble of incomprehensible dialects. To which the
easy response is that the benefits of conformity to linguistic
communities almost always outweigh the costs of nonconformist
expression.

Yes yes, you're really passionate about language, you have little respect
for grammarians, blah blah blah. None of that has the slightest relevance
to what I was talking about. I'm not denying that languages evolve and
mutate. I'm talking about the simple fact -- and it is a fact -- that two
people must share at least some common linguistic concepts in order
to communicate, and the fewer common constructs they share, the worse
the communication. Languages accomplish that through rules. Yes, the
rules are mere conventions, and can change. They're still rules.

Some languages have very strict rules, some have very flexible rules, but
they all have rules and they all restrict how you use the language.
English has a rule that you turn "programmer" into a plural by adding
"s" to the end. If you decide to drop the -er and add -ing instead, as in
"I hired a team of six programming this week", at best people will do a
double-take and be forced to work out what you mean from context. If you
decide to make the plural of programmer by deleting the first and last
three characters, nobody will have any idea what drugs you are smoking.


[snip]
What is "legal" in English depends on the communities in which you
are currently participating. Likely there is some community in which
such clipped discourse is understood and therefore legal.

Oh yes, the mythical "some community". Nope, sorry, I don't buy it. That's
not legal in any English dialect I've come across, and I've dealt with --
and still do -- English speakers from all over the world. No English
language or dialect typically puts the verb in front of both the object
and subject for present tense expressions. It isn't just *clipped*, the
word order is completely different from English. Didn't you notice that?

But in fact even if there is some obscure dialect of English that would
allow that, that doesn't change my point that there are some constructs
which aren't legal in English (as it exists today). If not "sit cat rat",
something else.

No doubt you can come up with some particular idiomatic phrase in English
that puts the verb first, or a different grammatical construct like the
imperative tense, e.g. "Sit on the rat, cat!". Poetry, in particular,
sometimes uses the verb-subject-object order. But these exceptions merely
emphasis that English, unlike Gaelic, doesn't normally write
verb-subject-object.

A language that was so radically different from all the other English
dialects as to allow "sits cat rat" as a typical construct wouldn't be
English. It might be a pidgin or a creole language. But it won't be
English, not now. In the indefinite future, who knows? I'm not saying that
languages are carved in stone, never to change -- that would be stupid.
But at any one time, languages have rules, even if those rules change over
time, and if two people disagree on those rules, communication is hurt, up
to the point of stopping communication completely.

If you are
talking to me, I'd express my lack of comprehension by saying
"Pardon?" and ask you to rephrase.

And how unfortunate for you that in my local community, "pardon" is the
worst insult imaginable and I punch you in the face.

(See, you aren't the only one that can just invent local communities
with implausible variations of English.)

When you make an "illegal" statement in English, exactly who or what
corrects you?

Is it Zeus, the divine Logos, the flying spaghetti monster, some
platonic ideal?

No. Your peers or your parents or your editor or your teachers correct
you. Or you get a reputation for being "stupid" and people start treating
you as if you were stupid -- maybe they start talk-ing ver-y slow-ly at
you, using baby words. Or people just find it difficult to communicate
with you, or misunderstand what you are trying to say.

There is no law of physics that says that people can't say "Head on my hat
I put". But English speakers just don't do it, and when somebody does,
they are treated as if they aren't speaking English.

But notice that semantics is important -- if I were to say "Head on my
pillow I lay", chances are good that I'd be treated as speaking
poetically, rather than as a non-English speaker. We commonly lay our head
on our pillow, but put our hat on our head.
As you can probably tell, this kind of silliness is a bit of a sore
spot for me. So please by all means, do some basic reading of
linguistics before you continue to engage in such silliness. Or at
least learn to properly quote an argument.

Before patronizing me, do make the effort to understand what I am saying.
Just because you've got valid concerns about ignorant grammarians doesn't
excuse your carelessness. Instead of reading what I actually wrote, you
read into it what you wanted to see: another stupid wanna-be grammarian
who thinks that languages are frozen, static, dead things. You couldn't be
more wrong, and your repeated assumption -- and that's all it was, just an
assumption -- that I know nothing about linguistics is shameful.

Are you man enough to acknowledge your error, or are you going to continue
this ridiculous charade of attacking me for holding views I don't have?
 
S

Stefan Nobis

Steven D'Aprano said:
Is that an argument against factory functions? Damn straight it is:
they are a powerful tool, and in the hands of morons, they can be
dangerous. Does that mean that languages shouldn't permit
higher-order functions? Not necessarily: all programming tools can
be misused, but some can be misused more easily than others. Power
and risk is often a trade-off, and language designers can't
eliminate all risk of stupid behaviour, but they can design the
language to allow whatever level of risk they believe is
acceptable. (E.g. there is no doubt that C's raw pointers are
powerful, but many languages deliberately don't use them.)

I understand your point, I understand the Java folks. But I think this
point of view is really wrong. The right solution would be to better
train people, to give more good examples or even to not employ those,
who don't grasp it.

You point of view is that of (big) companies: Every developer should
be equal, exchangable. I'm very sure this is only an illusion. And I
think this point of view leads to many failures of (big)
projects. Each project has it's working horse(s) and these are quite
more equal than the others. :)

To deny the good developers, the working horses the power they need
isn't a good idea. Give them all the tools they need and let others
learn from them -- so (nearly) everybody becomes a good to great
developer.

Am I naive? Maybe...
The risk of stupid factory functions is small compared to the
benefit, but maybe there is some domain somewhere where the ideal
solution is a language that DOESN'T treat functions as first class
objects, deliberately weakening the language so that a particular
class of errors (or stupid behaviour) just cannot happen.

And with Lisp macros the good developers may easily create these DSLs
to be used by the not so good developers. :)
That's the perspective of many people, and maybe it is wrong. Maybe
you really need to be immersed in Lisp for a while to see the
advantages of macros.

Yes, I think this perspective is wrong. Some time ago I wondered about
the hype of LinQ -- with Lisp macros it's already there. These things,
embedded languages (like embedded SQL, embedded Prolog, ...) are
really great. I also hate the amount of boilerplate code nesseccary in
Java -- yes, in Python it's muss less, but in Lisp it really vanished.

If you use a really good designed language which don't assume every
programmer to be dumb and equal, yes, maybe macros would be not that
big a bonus. But hey, they are not worse than operator overloading and
the like, so why not include them? (Answer: In most cases it's hard to
add macros because of non-homogenous syntax.) :)
 
S

Steven D'Aprano

Hunh? I have tons of them. Of coure at your level of discourse you will
want to know if those are metric tons or...

Stop playing games Ken. You said they were rare. Not me. You. The fact
that you personally make lots of use of the more radical macros doesn't
come into it. As you said, the norm across the wider Lisp community is the
less radical macro, the ones that are basically just functions.

That's what you said -- or are you changing your mind?
 
H

hg

Bill said:
Of course, but you have to realize that Turing-completeness is a
useless concept when comparing languages. C and Python are both
Turing-complete. So: write me some code in each that reads in a line
of text, splits it on spaces and stores the result in an array. Which
would you rather write? Which will be shorter and more easily changed
and straightforwardly grasped in the future?

QED. Turing-completeness is irrelevant when comparing languages.
Take it as a given.

Lisp ? ;-)
 
S

Stefan Nobis

Steven D'Aprano said:
Look at us: we're all communicating in a common language, English,
and we all agree on syntax and grammar. Now, I could be a lot more
expressive, and language could be a lot more powerful, if I could
define my own language where "You are a poopy-head" was in fact a
detailed and devastatingly accurate and complete explanation for why
Python was a better language than Lisp.
So it is good that English restricts the expressiveness and power of
the syntax and grammar. While we're talking English, we can both
understand each other, and in fact people who redefine words and
ignore the common meaning of them are often covering weaknesses in
their arguments.

Uh, you don't talk often to non-programmers, do you? Talk a bit to
non-programmers about your programming habits, why you prefer which
programming language and so on. Everything in english. How much do
they understand?

Ever talked to skateboarders? Other people of different scenes? They
are creating new, specialized languages every day. Here in Germany a
study was published a little time ago, how few people understand
commercials and their slogans.

Do you know how many jokes work? Yes, by misunderstandings. Why is
this? Because (natural) languages have macros, operator overloading
and all this fuss.

I'm no expert, I not really studied linguistics, but I would say, you
are completley wrong.
 
K

Ken Tilton

Steven said:
Stop playing games Ken. You said they were rare. Not me. You. The fact
that you personally make lots of use of the more radical macros doesn't
come into it. As you said, the norm across the wider Lisp community is the
less radical macro, the ones that are basically just functions.

That's what you said -- or are you changing your mind?

No, I simply misapprehended what you wrote, though it was perfectly
clear. You said:
If macros' advanced usage is rare, and most usage of macros could be done
by functions, then maybe that explains why so many coders don't miss them.

Maybe my brain misfired because there is so much wrong with that. The
meta-wrong is that clearly you do not understand macros or how they play
out in real applications, but you have climbed up on this soapbox as if
you were an expert on both issues. Like your interview, you are
speculating without basis on what might happen. You do have a good
excuse since GvR does the same.

Here you have a chance to talk with people who program with macros day
in and day out and learn about them, instead you are trying to tell us
how they are used. Does that make a lot of sense? Or do you think we are
lying? :)

Language-transforming macros such as defclass/defmethod (the heart of
CLOS) and my defmodel come along rarely. This does not mean my
applications do not /use/ CLOS extensively. They do. It means I do not
have ten such different language extensions. I have three: defclass,
defmodel, and LOOP. Can you understand that difference? "Used everywhere
because they are so cool" and "just a few such cool tools exist" are not
contradictory.

Does rare mean "who needs it"? Nice try, but obviously not. Well, maybe
not obviously, because not everyone likes OO, but I would not want to
program without defclass or defmodel or even LOOP. The latter is such a
powerful iteration tool it justifies learning the new syntax, which is
also not a problem because I use it all day making it is easy to
remember. (Aside: I /did/ resist learning it for years because of the
different syntax--my loss.)

Recall that this subwar started over someone saying Lisp was able to
"grow" CLOS without changing and have it look like part of the language,
which led you and others to echo GvR and pronounce macros to be
obfuscatory (?). Sorry, no, not in fact. Only in your nightmares.

As for simple macros not being necessary, what they do is clean up the
code, letting the beef stand out more. Obviously people with that
interest do not turn around and create obfuscated code, no matter how
many times you want to FUD that (which seems to be quite a lot <g>).

ken

--
Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

"Well, I've wrestled with reality for thirty-five
years, Doctor, and I'm happy to state I finally
won out over it." -- Elwood P. Dowd

"I'll say I'm losing my grip, and it feels terrific."
-- Smiling husband to scowling wife, New Yorker cartoon
 
K

Kirk Sluder

Steven D'Aprano said:
Yes. But you can't redefine 1+2 in Python, at least not without hacking
the interpreter. Can you redefine (+ 1 2) in Lisp?

Not without barreling through error messages about name conflicts.
 
S

Steven D'Aprano


That's your opinion, and as an experienced Lisp coder, it is an opinion
worth treating seriously. Nevertheless, a mere denial doesn't constitute
evidence, let alone proof.
And do they? To paraphrase Brian Griffin: "Are you sure it
was people? Are you sure it wasn't...nothing?"

You know, I'm really starting to think that you Lispers -- and I hate to
generalise, but in this case I feel I'm forced to -- have a real problem
here. On the one hand, I keep reading how unfair it is that the rest of
the programming world won't give Lisp a fair go, that all these other
programmers are spreading FUD over Lisp, especially over the macros and
parentheses. And then you come along and imply that nobody is concerned
about Lisp macros.

So which is it? If Lisp is so self-evidently better than every other
language, and if nobody has any fears or concerns with Lisp, why is Lisp a
fringe language? Not as fringe as it was ten years ago, and maybe growing
in popularity, and it is beyond all doubt that Lisp has a lot of influence
amongst language designers, but outside of a few niche areas, its still a
fringe language.


Jesus H Christ. Didn't you just get through talking about how easily
someone can redefine built-ins in Python?

Yes. But you can't redefine 1+2 in Python, at least not without hacking
the interpreter. Can you redefine (+ 1 2) in Lisp?

Agreed. This is why I've always argued that I/O should never have
been included in programming languages. Too dangerous. And, let's
face it, pretty old-fashioned these days.

Ha ha, I love good sarcasm!

Unfortunately, that isn't good sarcasm.

No, it treats code as text. See the difference?

Text is data.

What is the point of your comment? You don't have to argue about every
thing I say, even the ones we agree on. Look again at what I wrote. Is
there anything that gave you the impression that I think that having the
ability to write text to a file and import it is better than actually
supporting functional programming directly?

[snip]
Could you please calm down?

Huh?
Could you calm down?

Okay, once was funny. Twice is worrying. What exactly is giving you the
idea I need to calm down? Was it the use of reasoning and logic?
Perhaps it was the attempt to be reasonable and moderate and find some
middle ground that we could agree on, or if not agree, at least say "Well,
I disagree with you, but at least I understand where you are coming from"?
 
K

Kirk Sluder

Steven D'Aprano said:
And here I was thinking that languages fell from the sky like donuts!
Gosh, thank you for explaining that too me. What a fool I must seem!

Certainly that is what you wrote. If you had not meant that English
enforces restrictions on expressiveness, perhaps you should not have
written it.
Look, I was arguing a really simple point: for communication to occur
between two individuals, both people must agree on a set of rules for the
language that they use to communicate. If they don't have a common
language with agreed upon rules, communication will be feeble and weak, if
not non-existent, or there will be misunderstandings and errors.

No, in that post you are arguing a straw man. In this post you seem
to be agreeing with me while acting like you disagree.

If we both agree that the rules of languages are social, then we
should both agree that in the case of programming language,
communities of language users help to constrain how the language is
used by rejecting extensions that are not lispy/pythonic, and
accepting extensions that converge with accepted style.
No. Your peers or your parents or your editor or your teachers correct
you. Or you get a reputation for being "stupid" and people start treating
you as if you were stupid -- maybe they start talk-ing ver-y slow-ly at
you, using baby words. Or people just find it difficult to communicate
with you, or misunderstand what you are trying to say.

And likewise, if you propose a construct that is unlispy/unpythonic,
that construct is not likely to be adopted by the community of
computer language users.

Since you are apparently in complete agreement with the post you
dishonestly quoted out of context, I don't see where we have an
argument.
Before patronizing me, do make the effort to understand what I am saying.

I understand what you wrote. Perhaps your problem is that in your
rhetoric zest you chose to dishonestly attack a strawman, and chose
to defend a position you now claim not to hold.
Are you man enough to acknowledge your error, or are you going to continue
this ridiculous charade of attacking me for holding views I don't have?

I have no way of knowing the views that you have, only the views
that you write. And if you don't write what you mean, I have no way
of understanding that you are really in agreement with me, when you
attack something I did not say.
 
F

Frank Buss

Steven said:
Yes. But you can't redefine 1+2 in Python, at least not without hacking
the interpreter. Can you redefine (+ 1 2) in Lisp?

Yes, that's no problem and works without warnings and in every Common Lisp
implementation:

CL-USER > (shadow '+)
T

CL-USER > (defun + (&rest rest) (apply #'- rest))
+

CL-USER > (+ 3 1)
2
 

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

No members online now.

Forum statistics

Threads
474,434
Messages
2,571,690
Members
48,796
Latest member
Greg L.

Latest Threads

Top