(From vm-dev list)
> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. Hi Eliot. May I ask why you prefer the former over the latter? I'm interested because I'm working on an application where the folks involved prefer something similar, to where they write (expr) not ifTrue: [ ] rather than (expr) ifFalse: [ ]. I know you wouldn't do that but your statement definitely piqued my surprise and curiosity. |
Ah, now I just saw the ~= discussion, sorry..
On Mon, Oct 17, 2011 at 10:11 PM, Chris Muller <[hidden email]> wrote: > (From vm-dev list) >> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. > > Hi Eliot. May I ask why you prefer the former over the latter? > > I'm interested because I'm working on an application where the folks > involved prefer something similar, to where they write (expr) not > ifTrue: [ ] rather than (expr) ifFalse: [ ]. > > I know you wouldn't do that but your statement definitely piqued my > surprise and curiosity. > |
In reply to this post by Chris Muller-3
On 18.10.2011, at 05:11, Chris Muller wrote:
> (From vm-dev list) >> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. > > Hi Eliot. May I ask why you prefer the former over the latter? > > I'm interested because I'm working on an application where the folks > involved prefer something similar, to where they write (expr) not > ifTrue: [ ] rather than (expr) ifFalse: [ ]. > > I know you wouldn't do that but your statement definitely piqued my > surprise and curiosity. Maybe this is a clue: very few other programming languages have an "else"-case without a preceding "if true". So maybe for people versed in multiple languages the ifFalse: feels wrong? I personally like "expr ifFalse:" better than "expr not ifTrue:". And I read "~~" as "not identical" which also has a mental "not" in it, so I prefer "== ifFalse" :) - Bert - |
On 18 October 2011 09:58, Bert Freudenberg <[hidden email]> wrote:
> On 18.10.2011, at 05:11, Chris Muller wrote: > >> (From vm-dev list) >>> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. >> >> Hi Eliot. May I ask why you prefer the former over the latter? >> >> I'm interested because I'm working on an application where the folks >> involved prefer something similar, to where they write (expr) not >> ifTrue: [ ] rather than (expr) ifFalse: [ ]. >> >> I know you wouldn't do that but your statement definitely piqued my >> surprise and curiosity. > > Maybe this is a clue: very few other programming languages have an "else"-case without a preceding "if true". So maybe for people versed in multiple languages the ifFalse: feels wrong? > > I personally like "expr ifFalse:" better than "expr not ifTrue:". And I read "~~" as "not identical" which also has a mental "not" in it, so I prefer "== ifFalse" :) Ruby and Common Lisp have "unless"... and I find I almost never use them. frank |
In reply to this post by Bert Freudenberg
Hi Guys,
>On 18.10.2011, at 05:11, Chris Muller wrote: > >> (From vm-dev list) >>> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. >> >> Hi Eliot. May I ask why you prefer the former over the latter? >> >> I'm interested because I'm working on an application where the folks >> involved prefer something similar, to where they write (expr) not >> ifTrue: [ ] rather than (expr) ifFalse: [ ]. >> >> I know you wouldn't do that but your statement definitely piqued my >> surprise and curiosity. > >Maybe this is a clue: very few other programming languages have an "else"-case without a preceding "if true". So maybe for people versed in multiple languages the ifFalse: feels wrong? > >I personally like "expr ifFalse:" better than "expr not ifTrue:". And I read "~~" as "not identical" which also has a mental "not" in it, so I prefer "== ifFalse" :) >- Bert - Allow me to throw out an outside the box (programming box) thought. If one is able to mentally read "x ~= y ifTrue:..." or "x == y ifFalse:..." all in one look, I don't think it matters much as they know what the sentence says instantly. It then becomes a matter of what they are use to. For those of us who read those sentences in two parts: "x ~= y" and "ifTrue:...", the "not" being included in the comparison is preferred as it tells us up front what the comparison is about. Then the second part tells us what is being done about it. I hope helps and makes some sense. Lou ----------------------------------------------------------- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon mailto:[hidden email] http://www.Keystone-Software.com |
Hi,
In general negation can be confusing, but negations are not only syntactically. You can find negation in the semantic also, e.g.: variable names. You can find yourself with a variable name which express a negation, e.g.: abandoned (I must admit this is not the majority of the cases) In such situations, it's really convenient to have different combinations that allow you to write the code that reads better. Which read better between these? abandoned not ifTrue: [] abandoned ifFalse: [] Maybe what you will discover is that most of the time you use ifTrue... maybe you negate the variable or not... I think is not what you like the most, but what you write most of the time that tent to be readable. Regards, Erlis On Tue, Oct 18, 2011 at 9:20 AM, Louis LaBrunda <[hidden email]> wrote: Hi Guys, |
In reply to this post by Bert Freudenberg
On Tue, Oct 18, 2011 at 1:58 AM, Bert Freudenberg <[hidden email]> wrote:
For me, it's not about feeling right or wrong, it's about directly expressing intent. For example, in some loop where a predicate is being used to select or reject elements I would write "obj predicate ifTrue:" if I were looking for the element based on predicate and "obj predicate ifFalse:" if I were trying to filter-out elements based on predicate, just as I'd write collection select: [:e| e predicate] to select items based on predicate and collection reject: [:e| e predicate] to filter them out, and I would /not/ write collection select: [:e| e predicate not] to filter them out unless performance was really really important (since reject: adds another block activation for each element). I'm trying to communicate whether I'm selecting or rejecting based on predicate, and not wanting the reader to go through mental hoops by internally collapsing predicate not ifFalse: to predicate ifTrue: and vice verse.
Agreed. expr not ifTrue: & expr not ifFalse are perverse. And I read "~~" as "not identical" which also has a mental "not" in it, so I prefer "== ifFalse" :) Ah, there we differ. I view == and ~~ as complementary predicates. If I'm writing foo == bar ifTrue: I'm clearly selecting, and foo ~~ bar ifTrue: I'm clearly rejecting, but foo == bar ifFalse: is IMO worse (more cognitively demanding) than foo ~~ bar ifTrue:.
best, Eliot |
2011/10/18 Eliot Miranda <[hidden email]>:
> > > On Tue, Oct 18, 2011 at 1:58 AM, Bert Freudenberg <[hidden email]> > wrote: >> >> On 18.10.2011, at 05:11, Chris Muller wrote: >> >> > (From vm-dev list) >> >> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. >> > >> > Hi Eliot. May I ask why you prefer the former over the latter? >> > >> > I'm interested because I'm working on an application where the folks >> > involved prefer something similar, to where they write (expr) not >> > ifTrue: [ ] rather than (expr) ifFalse: [ ]. >> > >> > I know you wouldn't do that but your statement definitely piqued my >> > surprise and curiosity. >> >> Maybe this is a clue: very few other programming languages have an >> "else"-case without a preceding "if true". So maybe for people versed in >> multiple languages the ifFalse: feels wrong? > > For me, it's not about feeling right or wrong, it's about directly > expressing intent. For example, in some loop where a predicate is being used > to select or reject elements I would write "obj predicate ifTrue:" if I were > looking for the element based on predicate and "obj predicate ifFalse:" if I > were trying to filter-out elements based on predicate, just as I'd write > collection select: [:e| e predicate] to select items based on predicate > and collection reject: [:e| e predicate] to filter them out, and I would > /not/ write collection select: [:e| e predicate not] to filter them out > unless performance was really really important (since reject: adds another > block activation for each element). I'm trying to communicate whether I'm > selecting or rejecting based on predicate, and not wanting the reader to go > through mental hoops by internally collapsing predicate not ifFalse: to > predicate ifTrue: and vice verse. >> >> I personally like "expr ifFalse:" better than "expr not ifTrue:". > > Agreed. expr not ifTrue: & expr not ifFalse are perverse. > Well guys, while I agree, I just browsed senders of not and that's 1175 senders to refactor :) Well, maybe NOT all the senders (hey how you translate this, (senders allSatisfy: [:e | e shouldBeRefactored]) not or: [(senders anySatisfy: [:e | e shouldBeRefactored not]) or: [(senders noneSatisfy: [:e | e shouldBeRefactored not ]) not]] I tend to slightly dislike the last triple negation ;) Among the senders some answer true to your filter predicate, like select: predicate not / anyStatisfy: predicate not / but others are composed logic... Some like checkName: aFileName fixErrors: fixing ...snip... hasBadChars := fName ~= correctedName. (hasBadChars and:[fixing not]) ifTrue:[^self error:'Invalid file name']. hasBadChars ifFalse:[^ fName]. ^ correctedName shall easily become fname = correctedName ifTrue: [^fname]. fixing ifTrue: [^correctedName]. ^self error: 'Invalid file name' Some are tougher and would probably deserve a new selector like (self isPointers or: [ self isWords not ]) ifTrue: [ ^self ]. See https://code.google.com/p/pharo/issues/detail?id=2230 to just measure how badly we tend to misunderstand negation and what mistakes we make (same as subtraction is lot harder to learn than addition) Nicolas >> >> And I read "~~" as "not identical" which also has a mental "not" in it, so >> I prefer "== ifFalse" :) > > Ah, there we differ. I view == and ~~ as complementary predicates. If I'm > writing foo == bar ifTrue: I'm clearly selecting, and foo ~~ bar ifTrue: I'm > clearly rejecting, but foo == bar ifFalse: is IMO worse (more cognitively > demanding) than foo ~~ bar ifTrue:. > > same for noneSatisfy: , notNil etc... >> >> - Bert - >> >> >> > > > > -- > best, > Eliot > > > > |
In reply to this post by Eliot Miranda-2
2011/10/18 Eliot Miranda <[hidden email]>:
> > > On Tue, Oct 18, 2011 at 1:58 AM, Bert Freudenberg <[hidden email]> > wrote: >> >> On 18.10.2011, at 05:11, Chris Muller wrote: >> >> > (From vm-dev list) >> >> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. >> > >> > Hi Eliot. May I ask why you prefer the former over the latter? >> > >> > I'm interested because I'm working on an application where the folks >> > involved prefer something similar, to where they write (expr) not >> > ifTrue: [ ] rather than (expr) ifFalse: [ ]. >> > >> > I know you wouldn't do that but your statement definitely piqued my >> > surprise and curiosity. >> >> Maybe this is a clue: very few other programming languages have an >> "else"-case without a preceding "if true". So maybe for people versed in >> multiple languages the ifFalse: feels wrong? > > For me, it's not about feeling right or wrong, it's about directly > expressing intent. For example, in some loop where a predicate is being used > to select or reject elements I would write "obj predicate ifTrue:" if I were > looking for the element based on predicate and "obj predicate ifFalse:" if I > were trying to filter-out elements based on predicate, just as I'd write > collection select: [:e| e predicate] to select items based on predicate > and collection reject: [:e| e predicate] to filter them out, and I would > /not/ write collection select: [:e| e predicate not] to filter them out > unless performance was really really important (since reject: adds another > block activation for each element). I'm trying to communicate whether I'm > selecting or rejecting based on predicate, and not wanting the reader to go > through mental hoops by internally collapsing predicate not ifFalse: to > predicate ifTrue: and vice verse. >> >> I personally like "expr ifFalse:" better than "expr not ifTrue:". > > Agreed. expr not ifTrue: & expr not ifFalse are perverse. > He He, Eliot, I saw your initials stamped on this quite defensive code: (self selectedClass notNil and: [multiWindowState notNil "Can only support multi-window if original window has all the right panes." and: [multiWindowState prototype isHierarchy not]]) ifTrue: Probably a negative day ;) (no offense, I'd like to hide all my own production away) However, I'm not sure whether (or not) the negated form makes the intention clearer... (self selectedClass isNil or: [multiWindowState isNil "Can only support multi-window if original window has all the right panes." or: [multiWindowState prototype isHierarchy]]) ifFalse: Nicolas >> >> And I read "~~" as "not identical" which also has a mental "not" in it, so >> I prefer "== ifFalse" :) > > Ah, there we differ. I view == and ~~ as complementary predicates. If I'm > writing foo == bar ifTrue: I'm clearly selecting, and foo ~~ bar ifTrue: I'm > clearly rejecting, but foo == bar ifFalse: is IMO worse (more cognitively > demanding) than foo ~~ bar ifTrue:. > > >> >> - Bert - >> >> >> > > > > -- > best, > Eliot > > > > |
On Tue, Oct 18, 2011 at 2:01 PM, Nicolas Cellier <[hidden email]> wrote: 2011/10/18 Eliot Miranda <[hidden email]>: This is a great example. At least for me the first form is much clearer, expressing my intent to find a window that is selected and not a hierarchy window. The problem in teh former is that there is no inverse of isHierarchy. isNotHierarchy is overkill (but not I think isNotEmpty, as there are far more use-cases). Calling the inverse something like "isNormal" is just not descriptive enough. So in this case I had to use isHierarchy not to compose the predicate I wanted.
best, Eliot |
In reply to this post by Nicolas Cellier
On Tue, Oct 18, 2011 at 11:01:41PM +0200, Nicolas Cellier wrote:
> 2011/10/18 Eliot Miranda <[hidden email]>: > > > > > > On Tue, Oct 18, 2011 at 1:58 AM, Bert Freudenberg <[hidden email]> > > wrote: > >> > >> On 18.10.2011, at 05:11, Chris Muller wrote: > >> > >> > (From vm-dev list) > >> >> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. > >> > > >> > Hi Eliot. ?May I ask why you prefer the former over the latter? > >> > > >> > I'm interested because I'm working on an application where the folks > >> > involved prefer something similar, to where they write (expr) not > >> > ifTrue: [ ] rather than (expr) ifFalse: [ ]. > >> > > >> > I know you wouldn't do that but your statement definitely piqued my > >> > surprise and curiosity. > >> > >> Maybe this is a clue: very few other programming languages have an > >> "else"-case without a preceding "if true". So maybe for people versed in > >> multiple languages the ifFalse: feels wrong? > > > > For me, it's not about feeling right or wrong, it's about directly > > expressing intent. For example, in some loop where a predicate is being used > > to select or reject elements I would write "obj predicate ifTrue:" if I were > > looking for the element based on predicate and "obj predicate ifFalse:" if I > > were trying to filter-out elements based on predicate, just as I'd write > > collection select: [:e| e predicate] to select items based on predicate > > and?collection reject: [:e| e predicate] to filter them out, and I would > > /not/ write?collection select: [:e| e predicate not] to filter them out > > unless performance was really really important (since reject: adds another > > block activation for each element). ?I'm trying to communicate whether I'm > > selecting or rejecting based on predicate, and not wanting the reader to go > > through mental hoops by internally collapsing predicate not ifFalse: to > > predicate ifTrue: and vice verse. > >> > >> I personally like "expr ifFalse:" better than "expr not ifTrue:". > > > > Agreed. ?expr not ifTrue: & expr not ifFalse are perverse. > > > > He He, Eliot, I saw your initials stamped on this quite defensive code: > > (self selectedClass notNil > and: [multiWindowState notNil > "Can only support multi-window if original window has all the right panes." > and: [multiWindowState prototype isHierarchy not]]) ifTrue: > > Probably a negative day ;) (no offense, I'd like to hide all my own > production away) > However, I'm not sure whether (or not) the negated form makes the > intention clearer... > > (self selectedClass isNil > or: [multiWindowState isNil > "Can only support multi-window if original window has all the right panes." > or: [multiWindowState prototype isHierarchy]]) ifFalse: And in the category of "no good deed goes unpunished" the nominees are: Eliot Miranda, for attempting to propose a tiny performance enhancement primitive, for which we reward him with a full blown language war, destined to be enthusiastically reargued on an annual basis for many years to come... ;-) Dave |
In reply to this post by Louis LaBrunda
> For those of us who read those sentences in two parts: "x ~= y" and
> "ifTrue:...", the "not" being included in the comparison is preferred as it > tells us up front what the comparison is about. Then the second part tells > us what is being done about it. I hope helps and makes some sense. That's a great thought, thanks. It made me remember, a couple of times (cough), I have focused too quickly on the first-part (the condition) and then the second part (the what-to-do) so quickly that missed the middle part (the "ifFalse:") and made me mis-interpret the code momentarily because I assumed it was the true case.. |
In reply to this post by Eliot Miranda-2
2011/10/19 Eliot Miranda <[hidden email]>:
> > > On Tue, Oct 18, 2011 at 2:01 PM, Nicolas Cellier > <[hidden email]> wrote: >> >> 2011/10/18 Eliot Miranda <[hidden email]>: >> > >> > >> > On Tue, Oct 18, 2011 at 1:58 AM, Bert Freudenberg <[hidden email]> >> > wrote: >> >> >> >> On 18.10.2011, at 05:11, Chris Muller wrote: >> >> >> >> > (From vm-dev list) >> >> >> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. >> >> > >> >> > Hi Eliot. May I ask why you prefer the former over the latter? >> >> > >> >> > I'm interested because I'm working on an application where the folks >> >> > involved prefer something similar, to where they write (expr) not >> >> > ifTrue: [ ] rather than (expr) ifFalse: [ ]. >> >> > >> >> > I know you wouldn't do that but your statement definitely piqued my >> >> > surprise and curiosity. >> >> >> >> Maybe this is a clue: very few other programming languages have an >> >> "else"-case without a preceding "if true". So maybe for people versed >> >> in >> >> multiple languages the ifFalse: feels wrong? >> > >> > For me, it's not about feeling right or wrong, it's about directly >> > expressing intent. For example, in some loop where a predicate is being >> > used >> > to select or reject elements I would write "obj predicate ifTrue:" if I >> > were >> > looking for the element based on predicate and "obj predicate ifFalse:" >> > if I >> > were trying to filter-out elements based on predicate, just as I'd write >> > collection select: [:e| e predicate] to select items based on predicate >> > and collection reject: [:e| e predicate] to filter them out, and I would >> > /not/ write collection select: [:e| e predicate not] to filter them out >> > unless performance was really really important (since reject: adds >> > another >> > block activation for each element). I'm trying to communicate whether >> > I'm >> > selecting or rejecting based on predicate, and not wanting the reader to >> > go >> > through mental hoops by internally collapsing predicate not ifFalse: to >> > predicate ifTrue: and vice verse. >> >> >> >> I personally like "expr ifFalse:" better than "expr not ifTrue:". >> > >> > Agreed. expr not ifTrue: & expr not ifFalse are perverse. >> > >> >> He He, Eliot, I saw your initials stamped on this quite defensive code: >> >> (self selectedClass notNil >> and: [multiWindowState notNil >> "Can only support multi-window if original window has all the >> right panes." >> and: [multiWindowState prototype isHierarchy not]]) ifTrue: >> >> Probably a negative day ;) (no offense, I'd like to hide all my own >> production away) >> However, I'm not sure whether (or not) the negated form makes the >> intention clearer... >> >> (self selectedClass isNil >> or: [multiWindowState isNil >> "Can only support multi-window if original window has all the >> right panes." >> or: [multiWindowState prototype isHierarchy]]) ifFalse: > > This is a great example. At least for me the first form is much clearer, > expressing my intent to find a window that is selected and not a hierarchy > window. The problem in teh former is that there is no inverse of > isHierarchy. isNotHierarchy is overkill (but not I think isNotEmpty, as > there are far more use-cases). Calling the inverse something like > "isNormal" is just not descriptive enough. So in this case I had to use > isHierarchy not to compose the predicate I wanted. > That's what I thought. I started refactoring just to push these absolutist ideas to the limits of absurdity. But your example soon was disturbing. I agree to not refactor it. We can say that using negation MAY be intention obscuring and is thus questionnable, but it would be a great mistake to generalize and answer prematurely to this legitimate question with a single pre-established answer. We shall not carve such ban in stone. That's funny, because I got exactly this discussion yesterday with colleagues which had prepared stone tablets and chisel. An excuse : they program in C and ! is effectively really intention obscuring (hardly readable to my brain & eyes). Nicolas >> >> Nicolas >> >> >> >> >> And I read "~~" as "not identical" which also has a mental "not" in it, >> >> so >> >> I prefer "== ifFalse" :) >> > >> > Ah, there we differ. I view == and ~~ as complementary predicates. If >> > I'm >> > writing foo == bar ifTrue: I'm clearly selecting, and foo ~~ bar ifTrue: >> > I'm >> > clearly rejecting, but foo == bar ifFalse: is IMO worse (more >> > cognitively >> > demanding) than foo ~~ bar ifTrue:. >> > >> > >> >> >> >> - Bert - >> >> >> >> >> >> >> > >> > >> > >> > -- >> > best, >> > Eliot >> > >> > >> > >> > >> > > > > -- > best, > Eliot > > > > |
In reply to this post by David T. Lewis
2011/10/19 David T. Lewis <[hidden email]>:
> On Tue, Oct 18, 2011 at 11:01:41PM +0200, Nicolas Cellier wrote: >> 2011/10/18 Eliot Miranda <[hidden email]>: >> > >> > >> > On Tue, Oct 18, 2011 at 1:58 AM, Bert Freudenberg <[hidden email]> >> > wrote: >> >> >> >> On 18.10.2011, at 05:11, Chris Muller wrote: >> >> >> >> > (From vm-dev list) >> >> >> But I much prefer foo ~~ bar ifTrue: than foo == bar ifFalse:. >> >> > >> >> > Hi Eliot. ?May I ask why you prefer the former over the latter? >> >> > >> >> > I'm interested because I'm working on an application where the folks >> >> > involved prefer something similar, to where they write (expr) not >> >> > ifTrue: [ ] rather than (expr) ifFalse: [ ]. >> >> > >> >> > I know you wouldn't do that but your statement definitely piqued my >> >> > surprise and curiosity. >> >> >> >> Maybe this is a clue: very few other programming languages have an >> >> "else"-case without a preceding "if true". So maybe for people versed in >> >> multiple languages the ifFalse: feels wrong? >> > >> > For me, it's not about feeling right or wrong, it's about directly >> > expressing intent. For example, in some loop where a predicate is being used >> > to select or reject elements I would write "obj predicate ifTrue:" if I were >> > looking for the element based on predicate and "obj predicate ifFalse:" if I >> > were trying to filter-out elements based on predicate, just as I'd write >> > collection select: [:e| e predicate] to select items based on predicate >> > and?collection reject: [:e| e predicate] to filter them out, and I would >> > /not/ write?collection select: [:e| e predicate not] to filter them out >> > unless performance was really really important (since reject: adds another >> > block activation for each element). ?I'm trying to communicate whether I'm >> > selecting or rejecting based on predicate, and not wanting the reader to go >> > through mental hoops by internally collapsing predicate not ifFalse: to >> > predicate ifTrue: and vice verse. >> >> >> >> I personally like "expr ifFalse:" better than "expr not ifTrue:". >> > >> > Agreed. ?expr not ifTrue: & expr not ifFalse are perverse. >> > >> >> He He, Eliot, I saw your initials stamped on this quite defensive code: >> >> (self selectedClass notNil >> and: [multiWindowState notNil >> "Can only support multi-window if original window has all the right panes." >> and: [multiWindowState prototype isHierarchy not]]) ifTrue: >> >> Probably a negative day ;) (no offense, I'd like to hide all my own >> production away) >> However, I'm not sure whether (or not) the negated form makes the >> intention clearer... >> >> (self selectedClass isNil >> or: [multiWindowState isNil >> "Can only support multi-window if original window has all the right panes." >> or: [multiWindowState prototype isHierarchy]]) ifFalse: > > > And in the category of "no good deed goes unpunished" the nominees are: > > Eliot Miranda, for attempting to propose a tiny performance enhancement > primitive, for which we reward him with a full blown language war, > destined to be enthusiastically reargued on an annual basis for many > years to come... > > ;-) > > Dave > :) :) it would be great to plan a calendar of recurrent subjects > > |
On 19.10.2011, at 07:20, Nicolas Cellier wrote:
> 2011/10/19 David T. Lewis <[hidden email]>: >> >> And in the category of "no good deed goes unpunished" the nominees are: >> >> Eliot Miranda, for attempting to propose a tiny performance enhancement >> primitive, for which we reward him with a full blown language war, >> destined to be enthusiastically reargued on an annual basis for many >> years to come... >> >> ;-) >> >> Dave >> > > :) :) it would be great to plan a calendar of recurrent subjects Namespace discussions aren't due until Spring time. Followed by method chaining, and then arrow-assignments. - Bert - |
Free forum by Nabble | Edit this page |