Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reverse comma operator?

18 views
Skip to first unread message

Paul N

unread,
Aug 10, 2009, 3:43:51 PM8/10/09
to
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?

Alf P. Steinbach

unread,
Aug 10, 2009, 4:07:49 PM8/10/09
to
* 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

Lew Pitcher

unread,
Aug 10, 2009, 4:13:18 PM8/10/09
to
On August 10, 2009 16:07, in comp.lang.c, Alf P. Steinbach (al...@start.no)
wrote:

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. ------


Juha Nieminen

unread,
Aug 10, 2009, 5:47:12 PM8/10/09
to
Paul N wrote:
> 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)?

Daniel Pitts

unread,
Aug 10, 2009, 5:58:13 PM8/10/09
to
or be generated by necessity even if it isn't named explicitly.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Victor Bazarov

unread,
Aug 10, 2009, 6:00:02 PM8/10/09
to
Paul N wrote:
> 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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

hstagni

unread,
Aug 11, 2009, 8:06:43 AM8/11/09
to

>
> 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.

Michael Doubez

unread,
Aug 11, 2009, 8:28:34 AM8/11/09
to
On 11 août, 14:06, hstagni <sta...@gmail.com> wrote:
> > 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?

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.

--
Michael

Victor Bazarov

unread,
Aug 11, 2009, 8:45:45 AM8/11/09
to

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.

Tom St Denis

unread,
Aug 11, 2009, 9:19:08 AM8/11/09
to

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

Tom

Victor Bazarov

unread,
Aug 11, 2009, 9:43:35 AM8/11/09
to

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>

Tom St Denis

unread,
Aug 11, 2009, 9:55:34 AM8/11/09
to

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

Victor Bazarov

unread,
Aug 11, 2009, 10:16:36 AM8/11/09
to
Tom St Denis wrote:
> [..]

> 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[s].
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.

Rui Maciel

unread,
Aug 11, 2009, 9:22:16 AM8/11/09
to
Paul N wrote:

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

Lew Pitcher

unread,
Aug 11, 2009, 10:55:17 AM8/11/09
to
On August 11, 2009 10:16, in comp.lang.c, Victor Bazarov
(v.Aba...@comAcast.net) wrote:

> Tom St Denis wrote:
>> [..]
>> 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 :-)

Kaz Kylheku

unread,
Aug 11, 2009, 12:22:55 PM8/11/09
to
On 2009-08-10, Paul N <gw7...@aol.com> wrote:
> 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.

Alan Woodland

unread,
Aug 11, 2009, 3:17:35 PM8/11/09
to

You inspired me to have a go (and I've not really succeeded 100%) at
doing this using variadic templates (a learning exercise for me if
nothing else!)

#include <iostream>

// Based on simple_tuple from http://www.devx.com/cplus/Article/41533/1954
template <typename ... Types>
class ParamSet;

template <>
class ParamSet<> {};

template <typename First, typename ... Rest>
class ParamSet<First,Rest...> : private ParamSet<Rest...>
{
First member;
public:
ParamSet(First const& f, Rest const& ... rest):
ParamSet<Rest...>(rest...), member(f) { }

operator First() const { return member; }
};

template <typename Ret, typename... Args>
Ret dispatch(Ret (*f)(Args...), const ParamSet<Args...>& args) {
return f(args);
}

template <typename Ret>
Ret dispatch(Ret (*f)(), const ParamSet<>&) {
return f();
}

template <typename Ret, typename... Args1, typename... Args2>
Ret first(Ret (*f1)(Args1...), Ret (*f2)(Args2...), const
ParamSet<Args1...>& args1, const ParamSet<Args2...>& args2) {
const Ret& val = dispatch(f1,args1);
dispatch(f2,args2);
return val;
}

template <typename ... Types>
class ParamSet<Types...> make_param(const Types&... types) { return
ParamSet<Types...>(types...); }

// no parenthesis on a1, a2 is important to avoid operator comma with
// multiple parameters here.
#define prog1(f1,f2,a1,a2) first(f1,f2,make_param a1,make_param a2)

bool test1(void*) {
std::cout << "in test1()" << std::endl;
return true;
}

bool test2() {
std::cout << "in test2()" << std::endl;
return false;
}

int main() {
std::cout << prog1(test1, test2, ((void*)NULL),()) << std::endl;
return 0;
}


Can anyone improve it? The problem I have is dispatching with more than
1 argument. I also can't quite think of a tidy way to 'steal' the
arguments in a macro and make the macro just take two parameters instead
of 4.

Alan

Frank

unread,
Aug 11, 2009, 6:51:48 PM8/11/09
to

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.

0 new messages