Reverse comma operator?

P

Paul N

I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

but without needing the temporary value.

Is this a remotely sensible idea? Are there any cunning tricks (other
than RAII in C++) why it might not be necessary?
 
A

Alf P. Steinbach

* Paul N:
I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

but without needing the temporary value.

Put your setupstuff in a constructor.

Put your resetsetuff in a destructor.


Cheers & hth.,

- Alf
 
L

Lew Pitcher

* Paul N:

Put your setupstuff in a constructor.

Put your resetsetuff in a destructor.

While that solution might apply to C++, it certainly doesn't apply to C; C
has no "constructor" or "destructor" thingies.

The OP proposed a new operator for two languages: C and C++

For C, the OP should repost his proposal to comp.std.c, along with more
details. He should be prepared to defend his proposal, and expand on it as
necessary.

For C++, the OP should repost his proposal to the moderated comp.std.c++
group, again with more details.

HTH
--
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
 
J

Juha Nieminen

Paul said:
I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

but without needing the temporary value.

IMO such operator would only promote obfuscation. What's wrong with a
temporary value (which will usually be optimized away by the compiler
anyways)?
 
D

Daniel Pitts

Juha said:
IMO such operator would only promote obfuscation. What's wrong with a
temporary value (which will usually be optimized away by the compiler
anyways)?
or be generated by necessity even if it isn't named explicitly.
 
V

Victor Bazarov

Paul said:
I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. [..]

What problem would it solve that can't already be solved by means that
already exist in the language?

V
 
H

hstagni

What problem would it solve that can't already be solved by means that
already exist in the language?

So, you are saying, for instance, that 'for' and 'while' constructions
should not be in the language, since you can use 'if' and 'goto'
statements to do their jobs? [] operator should not be in the the
language, since you can use pointer arithmetic? Good programming
languages usually have many ways to do the exactly same thing, and
there is nothing wrong with that.
 
M

Michael Doubez

So, you are saying, for instance, that 'for' and 'while' constructions
should not be in the language, since you can use 'if' and 'goto'
statements to do their jobs?

for, while, do/while and foreach are loops and although the same can
be achieved with goto, it is not understood at that level by the
compiler (it cannot identify the structure). They require support from
the compiler.
[] operator should not be in the the
language, since you can use pointer arithmetic?

For that one, it is true the definition are the same but it is because
arrays are inherited from C and are not first class object.
Good programming
languages usually have many ways to do the exactly same thing, and
there is nothing wrong with that.

There is more than one way to kill a cat but, contrary to the
citation, IMHO not every single one of them is right: using a while
loop where you should use a for loop doesn't express the same thing.
 
V

Victor Bazarov

hstagni said:
What problem would it solve that can't already be solved by means that
already exist in the language?

So, you are saying, for instance, that 'for' and 'while' constructions
should not be in the language, since you can use 'if' and 'goto'
statements to do their jobs? [] operator should not be in the the
language, since you can use pointer arithmetic? Good programming
languages usually have many ways to do the exactly same thing, and
there is nothing wrong with that.

No, I am not saying that at all. But where was the OP when the
languages were being worked on and standardized? I am saying there has
to be the limited amount of syntactic sugar - after all all languages
are just spruced up representations of the machine code. I am saying
that at this point in language development the introduction of a new
operator has to be justified. And I am asking about that justification.
"Wouldn't it be cool?" is simply not enough.

V
 
T

Tom St Denis

I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

but without needing the temporary value.

Is this a remotely sensible idea? Are there any cunning tricks (other
than RAII in C++) why it might not be necessary?

couldn't you just write a wrapper that does calculatevalue and
resetstuff in one call? Heck roll the setup into it too.

Tom
 
R

Rui Maciel

Paul said:
I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

but without needing the temporary value.

Is this a remotely sensible idea? Are there any cunning tricks (other
than RAII in C++) why it might not be necessary?

Why do you feel you need to implement a new operator in two different programming languages to perform a task
that is already trivial to accomplish with the features already available?


Rui Maciel
 
B

bartc

Paul N said:
I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

but without needing the temporary value.

Is this a remotely sensible idea?

Normally I like novel new bits of syntax, but it's difficult to get excited
about this one:

A $ B

executes A, then B, and returns A? It seems that if A is complex enough to
need setup and reset code, then that code deserves to be written properly,
not all squeezed into the same expression.
Are there any cunning tricks (other
than RAII in C++) why it might not be necessary?

Such as A+B, when B is set to return 0, and A is known to execute first?
Even if there was, it's hardly going to make for clear code. Why not just a
function:

T getvalue(void) {T temp; setupstuff(); T=calculatevalue(); resetstuff();
return temp;}
....
return getvalue():

Then the setup/reset code needn't be repeated. Perhaps an actual example
would be helpful.
 
V

Victor Bazarov

Tom said:
couldn't you just write a wrapper that does calculatevalue and
resetstuff in one call? Heck roll the setup into it too.

Problem is often in the necessity to use several local variables.
Imagine that the 'setup' uses 'a', 'b', and 'c', the 'calculate' uses
'a', 'c', and 'e', and 'reset' uses 'd', 'e', and 'f' (I am exaggerating
of course). It quickly becomes rather difficult to follow. What could be

return setup(a,b,c), calculate(a,c,e) $ reset(d,e,f);

becomes

return setup_calculate_reset(a,b,c,d,e,f);

It's not so difficult to mix them up (especially if they aren't named so
conveniently in alphabetical order), not to mention that it's now more
difficult to comprehend which variable is used for what. If 'setup' is
not rolled into it, the expression is a bit simpler, of course:

return setup(a,b,c), calculate_reset(a,c,d,e,f);

but not much :-(

The original set of statements can all be written in one expression, of
course, provided that 'res' is declared earlier:

return setup(a,b,c), res = calculate(a,c,e), reset(d,e,f), res;

As for C++ and its RAII, perhaps it's good enough a reason to switch...
Or not... <shrug>

V
 
T

Tom St Denis

Problem is often in the necessity to use several local variables.
Imagine that the 'setup' uses 'a', 'b', and 'c', the 'calculate' uses
'a', 'c', and 'e', and 'reset' uses 'd', 'e', and 'f' (I am exaggerating
of course).  It quickly becomes rather difficult to follow.  What could be

     return setup(a,b,c), calculate(a,c,e) $ reset(d,e,f);

becomes

     return setup_calculate_reset(a,b,c,d,e,f);

It's not so difficult to mix them up (especially if they aren't named so
conveniently in alphabetical order), not to mention that it's now more
difficult to comprehend which variable is used for what.  If 'setup' is
not rolled into it, the expression is a bit simpler, of course:

    return setup(a,b,c), calculate_reset(a,c,d,e,f);

but not much :-(

The original set of statements can all be written in one expression, of
course, provided that 'res' is declared earlier:

    return setup(a,b,c), res = calculate(a,c,e), reset(d,e,f), res;

As for C++ and its RAII, perhaps it's good enough a reason to switch...
  Or not... <shrug>

The "time" you save by not typing a few characters you lose in having
to maintain/debug/review/document. It's better to write it properly
the first time then have to revisit it.

And I don't mean specifically in this case, but in general.
Developers should plan to invest time upfront as opposed to trying to
cut corners then revisit things when it goes wrong.

I'm in the process of adding PKCS #8 support to a crypto library [for
example] and the "encrypt private key" function which I wrote from
scratch is ~400 lines of code, has to manipulate ciphers, hashes, ASN.
1 structures, etc. Aside from a couple typos that prevented
compilation it worked on the first try.

Oh yeah, it took me a day and a half to write the 400 lines. Plus all
the time I spent thinking about the design of the function (did I
mention the function takes ~12 parameters?). I could have "hacked"
out something like it in a couple of hours, then circled around and
around and around as I fixed one bug after another. But that's a heck
of a lot more dangerous. So while the code I wrote is still not fully
verified, it stands a better chance of being correct because I spent
the time up front doing the design work and proper coding techniques.

/anecdote.

So cute little tricks like this seem to be time savers, but in reality
they're just more expensive in the end.

Tom
 
V

Victor Bazarov

Tom said:
[..]
The "time" you save by not typing a few characters you lose in having
to maintain/debug/review/document. It's better to write it properly
the first time then have to revisit it.
[..]

Isn't this a contradiction? If you write it properly the first time (so
there is no need "to revisit it"), would you actually not *really* be
concerned with maintenance? I mean, revisiting *is* maintenance.

I am picking this as an example of the difficult decisions software
engineers and programmers face almost every day. Do you write a perfect
function that needs no improvement whatsoever (and then it doesn't
really need any code comments, sensible variable naming, etc.), or do
you write the function in such a way that anybody who comes in will
understand what it does and how and why, even though nobody is supposed
to (since it works)?

There is no need to make your activities about extreme, but there are
methods to help even yourself while you're writing your program.
Twelve arguments in your function? That's, like, seven or nine too
many. Perhaps some of them need to be wrapped in their own types...

We've digressed, though.

V
 
L

Lew Pitcher

Tom said:
[..]
The "time" you save by not typing a few characters you lose in having
to maintain/debug/review/document. It's better to write it properly
the first time then have to revisit it.
[..]

Isn't this a contradiction? If you write it properly the first time (so
there is no need "to revisit it"), would you actually not *really* be
concerned with maintenance? I mean, revisiting *is* maintenance.

I am picking this as an example of the difficult decisions software
engineers and programmers face almost every day. Do you write a perfect
function that needs no improvement whatsoever (and then it doesn't
really need any code comments, sensible variable naming, etc.), or do
you write the function in such a way that anybody who comes in will
understand what it does and how and why, even though nobody is supposed
to (since it works)?

You write the function so that anyone who reads the code will understand the
function's purpose, operation, and limits.

In my experience, no source code remains static. New or changed requirements
(even when they don't explicitly affect the code in question) will often
have an impact on how code is (re)written. The "perfect function" (now) may
need alteration in order to fit the requirements of the revised
application.

And then, there's debugging. /I/ prefer readable code, where the author has
taken the time to document his (or her) logic. This way, I can follow the
code as I debug. And, it makes logic errors that much easier to spot.

[snip]
We've digressed, though.

Yes, we have :)

--
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
 
V

Vladimir Jovic

Lew said:
Tom said:
[..]
The "time" you save by not typing a few characters you lose in having
to maintain/debug/review/document. It's better to write it properly
the first time then have to revisit it.
[..]
Isn't this a contradiction? If you write it properly the first time (so
there is no need "to revisit it"), would you actually not *really* be
concerned with maintenance? I mean, revisiting *is* maintenance.

I am picking this as an example of the difficult decisions software
engineers and programmers face almost every day. Do you write a perfect
function that needs no improvement whatsoever (and then it doesn't
really need any code comments, sensible variable naming, etc.), or do
you write the function in such a way that anybody who comes in will
understand what it does and how and why, even though nobody is supposed
to (since it works)?

You write the function so that anyone who reads the code will understand the
function's purpose, operation, and limits.

In my experience, no source code remains static. New or changed requirements
(even when they don't explicitly affect the code in question) will often
have an impact on how code is (re)written. The "perfect function" (now) may
need alteration in order to fit the requirements of the revised
application.

And then, there's debugging. /I/ prefer readable code, where the author has
taken the time to document his (or her) logic. This way, I can follow the
code as I debug. And, it makes logic errors that much easier to spot.

Few smart things from the internet :

1) Programs must be written for people to read, and only incidentally
for machines to execute.

2) Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by
definition, not smart enough to debug it.

What OP suggested is simple obfuscation
 
V

Victor Bazarov

Lew said:
[..]
In my experience, no source code remains static. New or changed requirements
(even when they don't explicitly affect the code in question) will often
have an impact on how code is (re)written. The "perfect function" (now) may
need alteration in order to fit the requirements of the revised
application.

See how many possibilities to not change it you left in? "Will often
have an impact", "may need alteration"... By definition, a working
function does *not* need alteration. If your requirements changed, you
will most likely write a new function. "No source code remains static"?
At the macro level, yes. But quite a few low level functions will
never have to be rewritten. How many times did you write a new 'sort'
or 'stricmp'? Or 'norm'?

Even if you consider such drastic change as moving from 'char' to
'wchar_t', all functions that you have working for 'char' just need to
get their 'wchar_t' counterparts, and then template wrappers to direct
the code to either of those two variations. (I am not sure how you'd do
it in C, but there is probably a way, like naming those functions
differently). The point is that you don't throw away the functions that
are already perfect. That's the definition of "perfect".
And then, there's debugging. /I/ prefer readable code, where the author has
taken the time to document his (or her) logic. This way, I can follow the
code as I debug. And, it makes logic errors that much easier to spot.

A perfectly working function doesn't *need* debugging. If you know what
the function does (from the documentation, its name, or by divining it),
you don't need to "follow the code". You step over it, get the results,
and move onto the code that does need debugging.

So, "no source code remains static" most likely just means there are no
"perfect functions". Even the one doing what it's supposed to do now
can never be perfect simply because the world is changing around it.
So, my exaggeration about "perfection == written properly" doesn't apply
here, right? I was mostly picking at Tom St Denis' flawed (IMHO)
statement that "It's better to write it properly the first time then
have to revisit it." We seem to agree that those are not exclusive.

V
 
K

Kaz Kylheku

I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second.

You mean like PROG1 in Common Lisp? Quite useful indeed.

In C we have kind of a special case of this, namely post-increment. I.e.

y = x++;

is similar to a use of your $ operator:

y = x $ x++;

Implicit to a saved copy of some prior value of a computation is sometimes a
handy way to express yourself.
For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

Lisp:

(progn (set-up-stuff)
(prog1 (calculate-value)
(reset-stuff)))

There is prog2 also, (but no prog3, just 1, 2 and n).

I'm pretty sure you can't emulate this operator in any way in portable C.

In the GNU C dialect, we can use the ``typeof'' operator to figure out the
return type of the expression, so that we can define a temporary variable
of a compatible type. And GNU C has block statements which return a value
(the value of the last statement in the block), similar to Lisp's PROG.
(GNU C was originally written by Lisp hackers). So in GNU C, we can easily make:

#define PROG1(A, B) ...

which evaluates A, then B, with a sequence point, and yields the value of A.

I can't think of a way to do this in ISO C. Even if we accept this ugly
interface:

#define PROG1(TYPEOF_A, A, B)

the problem is we need a block in order to be able to define the temporary
variable, which conflicts with the requirement to expand into a value-yielding
expression.
would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

But you can do it like this:

(setupfstuff(), res = calculatevalue(), resetstuff(), res)

which isn't /that/ bad.
but without needing the temporary value.

I.e. the temporary variable is the /only/ inconvienience. The other aspects
of the above example are strawmen.
 
F

Frank

I had an idea the other day for a new operator for C and C++, which
acts like the comma operator but which returns the first value instead
of the second. For example, and using $ for my operator as it doesn't
seem to be already used,

return setupstuff() , calculatevalue() $ resetstuff();

would do the same as

setupstuff();
res = calculatevalue();
resetstuff();
return res;

but without needing the temporary value.

Is this a remotely sensible idea? Are there any cunning tricks (other
than RAII in C++) why it might not be necessary?

I'd rather see these languages deprecate or shed the comma operator as
its use is highly idiomatic. In Perl, it blended in seamlessly with
list form, which made it a perfect pain in the ass. Fortran doesn't
have the darn thing and is better off for it.
 

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
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top