Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 13, 2002 infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
My thinking: Why does operator overloading exist? I think the primary reason is to allow an infix notation for user-defined functions. Common compiler construction technology (YACC, PCCTS) requires the syntax be fixed; the set of infix tokens is fixed, their precedence is fixed, their associativity is fixed. But maybe we've progressed beyond that. What if it were possible for the user to simply declare a function as "infix?" infix int plus(int a, int b) { return a + b; } Now you can code: int x, y, z; z = x plus y; Pretty readable. Clearly "plus" is a user- (or library-) defined operation, and I *like* making that clear to the reader. That leaves precedence and associativity. Right now I'd guess that it would be okay if all infix operators would have lower precedence than all built-in operators. We can also simplify by giving all infix functions equal precedence, and make the user group them as needed by parentheses, but it might be nice to be able to specify their associativity (does "a plus b plus c" do "b plus c" first, or "a plus b" first?). Now, ISTR that the current alpha D compiler is a hand-coded recursive-descent parser, and I'm pretty sure that a smart man like Walter could in fact code up syntactic analyser that is tolerant of additions to the infix operator table (eh, Walter?). But it means you can't build D compilers with YACC (um, maybe; if you leave out user control of precedence and associativity, I think it could still be done). Oh, and it means feeding back info from semantic analysis into syntax, and I recall reading that Walter has decided this is bad (the reasoning for his syntactic changes to type-casting operations). Well, it was a thought. -- Richard Krehbiel, Arlington, VA, USA rich@kastle.com (work) or krehbiel3@home.com (personal) |
February 13, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Richard Krehbiel | Richard Krehbiel wrote: > But it means you can't build D > compilers with YACC (um, maybe; if you leave out user control of precedence > and associativity, I think it could still be done). Oh, and it means > feeding back info from semantic analysis into syntax, and I recall reading > that Walter has decided this is bad (the reasoning for his syntactic changes > to type-casting operations). Can you describe why this is impossible with YACC? As I understand it, what YACC really sees is <token> = <token> <token> <token> ; Which it would parse into blocks something like blockA: x plus y blockB: z = <blockA> blockC: <blockB> ; It's the responsibility of the compiler code supplied with the blockA rule to determine what those 3 alphanumeric tokens mean. It's not particularly different from foo bar; which the compiler must deduce (from semantics) is a variable declaration. Maybe I'm missing something again... -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ] |
February 13, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Richard Krehbiel | "Richard Krehbiel" <rich@kastle.com> wrote in message news:a4dqip$28i7$1@digitaldaemon.com... > int x, y, z; > z = x plus y; > > Pretty readable. Clearly "plus" is a user- (or library-) defined operation, > and I *like* making that clear to the reader. Hey, I still want to be able to overload + as is! =) |
February 13, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C6A7779.27137005@deming-os.org... > Richard Krehbiel wrote: > > > But it means you can't build D > > compilers with YACC (um, maybe; if you leave out user control of precedence > > and associativity, I think it could still be done). Oh, and it means feeding back info from semantic analysis into syntax, and I recall reading > > that Walter has decided this is bad (the reasoning for his syntactic changes > > to type-casting operations). > > Can you describe why this is impossible with YACC? As I understand it, what > YACC really sees is > <token> = <token> <token> <token> ; > > Which it would parse into blocks something like > blockA: x plus y > blockB: z = <blockA> > blockC: <blockB> ; > It's the responsibility of the compiler code supplied with the blockA rule to > determine what those 3 alphanumeric tokens mean. It's not particularly > different from > foo bar; > which the compiler must deduce (from semantics) is a variable declaration. > > Maybe I'm missing something again... Here's a YACC (like) expression of some of the C grammar, taken from the back of K&R's "The C Programming Language:" shift_expr: add_expr | shift_expr '<<' add_expr | shift_expr '>>' add_expr; add_expr: mul_expr | add_expr '+' mul_expr | add_expr '-' mul_expr; mul_expr: cast_expr | mul_expr '*' cast_expr | mul_expr '/' cast_expr | mul_expr '%' cast_expr; Precedence is defined in the grammar, that is, the grammar (which can't be changed at run time) defines that a mul_expr has higher precedence than add_expr and shift_expr (so "a + b * c" evaluates as "a + (b * c)"). Associativity is also defined in the grammar. Associativity says that if you have "a + b - c" it's evaluated as "(a + b) - c" (um, probably; C can reorder these, and you can tell by side-effects, if it can prove that otherwise the result is indistinguishable - and if overflow is possible, then it can be). Associativity matters a great deal if the side effects matter, like with the C++ "<<" iostream operator. When you code 'cout << "result is " << i << endl;', the output must go left-to-right. What I was saying is, if we rule that user-defined infix operators always and forever have a particular precedence and associativity, then we *can* build such a compiler with YACC. Assuming that the above was the top of the "expression" definition (it's not), we'd add: user_infix_expr: shift_expr | user_infix_expr INFIX_TOKEN shift_expr; And then, we'd tell the lexer that user-defined infix function names be returned as INFIX_TOKEN rather than as IDENTIFIER_TOKEN. Now, with a recursive-descent parser written in plain C, precedence and associativity rules could also be changed at run time. But you still need to know it's an "infix operator", not an "identiier", which means feedback. (...and I'm sure that *real* compiler designers will correct any of this that's wrong...) -- Richard Krehbiel, Arlington, VA, USA rich@kastle.com (work) or krehbiel3@home.com (personal) |
February 13, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Richard Krehbiel | Richard Krehbiel wrote: > What I was saying is, if we rule that user-defined infix operators always and forever have a particular precedence and associativity, then we *can* build such a compiler with YACC. Gotcha! Now I understand. Frankly, it seems like left-to-right precedence/associativity makes sense for the majority of applications. Anybody got (good) counterexamples? -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ] |
February 13, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Richard Krehbiel | Richard Krehbiel a écrit :
> My thinking: Why does operator overloading exist?
>
> I think the primary reason is to allow an infix notation for user-defined functions.
>
> Common compiler construction technology (YACC, PCCTS) requires the syntax be fixed; the set of infix tokens is fixed, their precedence is fixed, their associativity is fixed.
>
> But maybe we've progressed beyond that. What if it were possible for the user to simply declare a function as "infix?"
>
> infix int plus(int a, int b) { return a + b; }
>
> Now you can code:
>
> int x, y, z;
> z = x plus y;
>
> Pretty readable. Clearly "plus" is a user- (or library-) defined operation, and I *like* making that clear to the reader.
>
I already suggested something like this (see "Operator overloading, ann other
idea").
I was not convinced by counter arguments.
So i still support infix notation
Roland
|
February 13, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | Pavel Minayev wrote:
> "Richard Krehbiel" <rich@kastle.com> wrote in message
> news:a4dqip$28i7$1@digitaldaemon.com...
>
>
>> int x, y, z;
>> z = x plus y;
>>
>>Pretty readable. Clearly "plus" is a user- (or library-) defined
>>
> operation,
>
>>and I *like* making that clear to the reader.
>>
>
> Hey, I still want to be able to overload + as is! =)
For a second, I thought Richard's suggestion was a valuable
compromise.
But when you think about it, it just _looks_ like... I
don't know. Baby talk. Training wheels. Writing with crayon.
(No offense intended.)
Once you start trying to write a big hairy expression
with "plus", you're going to want to rename it "pl" then
"p" (or "add", then "a") to save space on the line. At
that point you've hurt readability more than if you had
overloaded the plus sign. Likewise, you still can't
reasonably enforce against writing a "plus" function that,
say, appends to a file on the disk. So who are we kidding?
Unless you're going to vastly alter the way D is specified
now, Walter, there are going to be a million ways to write
misleading and crappy code. Giving us overloaded operators
in the style of C++[1], or not, isn't materially going to
change that. Many people want the overloaded operators. I
don't know what other arguments I can make.
Okay, okay, here's one more.
Bignums. If I want to create a class that manages arbitrary-
precision, arbitrary-magnitude numbers, I want to manipulate
them using the conventional mathematical operators. :+: and
other weirdness isn't going to help readability.
-Russell B
[1] And by that I mean without substantially restricting the
operator list from C++ -- sure, get rid of . and -> and , but
leave the bitwise, logical, and comparison operators in.
|
February 17, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C6A891A.A5881559@deming-os.org... > Richard Krehbiel wrote: > > > What I was saying is, if we rule that user-defined infix operators always > > and forever have a particular precedence and associativity, then we *can* > > build such a compiler with YACC. > > Gotcha! Now I understand. > > Frankly, it seems like left-to-right precedence/associativity makes sense for > the majority of applications. Anybody got (good) counterexamples? > CInt256 a = 1, b = 2, c = 5; a = a + b * c; // Should yield 11, not 15.... -- Stijn OddesE_XYZ@hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail |
February 17, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | "Pavel Minayev" <evilone@omen.ru> wrote in message news:a4duo0$2ao6$1@digitaldaemon.com... > "Richard Krehbiel" <rich@kastle.com> wrote in message news:a4dqip$28i7$1@digitaldaemon.com... > > > int x, y, z; > > z = x plus y; > > > > Pretty readable. Clearly "plus" is a user- (or library-) defined > operation, > > and I *like* making that clear to the reader. > > Hey, I still want to be able to overload + as is! =) > > Me too! -- Stijn OddesE_XYZ@hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail |
February 17, 2002 Re: infix functions as a substitute for operator overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to OddesE | "OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:a4o5g5$rgm$1@digitaldaemon.com... > CInt256 a = 1, b = 2, c = 5; > > a = a + b * c; > > // Should yield 11, not 15.... He said "user-defined", not "built-in". For user-defined, I guess we can live with fixed precedence, using braces where necessary... |
Copyright © 1999-2021 by the D Language Foundation