Tuesday, June 19, 2018

Digest for comp.lang.c++@googlegroups.com - 25 updates in 3 topics

Christian Gollwitzer <auriocus@gmx.de>: Jun 19 06:41AM +0200

Am 18.06.18 um 22:19 schrieb Bart:
 
>> Why wouldn't those character combinations work?
 
> Because \ is usually involved with line continuation. There would be
> ambiguities.
 
I don't see that. Even now, the \ character does lie continuation only
if it is immediately foloowed by a newline character. In case somebody
necessarily wants to break the expresssion over multiple lines, a space
can be inserted:
 
a /\<newline> -> line continuation
 
a /\<space><newline> -> /\ operator followed by newline
 
At least the pure \ character works flawlessly in other languages like
Matlab as an operator, it means "matrix left divide". I've done a
similar language, here is the PEG grammar:
 
https://github.com/auriocus/VecTcl/blob/master/generic/vexpr.peg#L66
 
As you can see in line 66, \ followed by newline is parsed as
"whitespace". Line 58 defines the backslash as a multiplicative operator.
 
Christian
David Brown <david.brown@hesbynett.no>: Jun 19 07:27AM +0200

On 18/06/18 22:19, Bart wrote:
 
>> Why wouldn't those character combinations work?
 
> Because \ is usually involved with line continuation. There would be
> ambiguities.
 
It is usually as an escape character, for writing characters like \n or
\t - I'd say line continuation was a good deal less common. But in
either case you'd risk ambiguities or complications. Using \ as part of
an operator would mean changing details of the C parsing. I'd expect it
to be doable, however.
David Brown <david.brown@hesbynett.no>: Jun 19 07:40AM +0200

On 18/06/18 22:12, Scott Lurndal wrote:
 
>> In C++, you'd be better with a template. That would let you avoid the
>> "min(a++, b++)" problem.
 
> like std::min and std::max?
 
Yes, just like that :-)
Juha Nieminen <nospam@thanks.invalid>: Jun 19 07:15AM

> Not to mention that the "correct" way to do the "traditional" way is
> #define min(a,b) (((a) <= (b)) ? (a) : (b))
> #define max(a,b) (((a) >= (b)) ? (a) : (b))
 
Which is very bad because a or b will be evaluated twice, which can be
bad for many reasons. For starters, if they are very heavy to evaluate
(eg. they are function calls that perform some heavy calculations),
it will take twice as long as necessary. More damningly, if either a
or b have any side-effects, those side-effects will be applied twice,
which may break things. (Side effects don't always necessarily
affect the variable itself, like in min(a++, b++), but can affect
other things somewhere else.)
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Jun 19 02:01AM -0600

On Tue, 19 Jun 2018 07:27:35 +0200, David Brown
>either case you'd risk ambiguities or complications. Using \ as part of
>an operator would mean changing details of the C parsing. I'd expect it
>to be doable, however.
 
In my experience, the backslash has *always* been an escape
character, and I would expect using it for anything else to be a
well-intentioned but unpopular and ultimately disastrous effort.
 
Off the top of my head -- and based on absolutely no relevant
experience -- I would expect the addition of a new digraph or trigraph
to be almost as unpopular but with a better chance at success.
 
Louis
David Brown <david.brown@hesbynett.no>: Jun 19 10:39AM +0200

On 19/06/18 09:15, Juha Nieminen wrote:
> which may break things. (Side effects don't always necessarily
> affect the variable itself, like in min(a++, b++), but can affect
> other things somewhere else.)
 
Of course. That is why the traditional way is to call these MIN and
MAX, not min and max, as a warning to users that they are macros and you
should not "call" them with arguments with side-effects.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 19 11:28AM +0100

On Tue, 19 Jun 2018 10:39:44 +0200
 
> Of course. That is why the traditional way is to call these MIN and
> MAX, not min and max, as a warning to users that they are macros and you
> should not "call" them with arguments with side-effects.
 
All macro systems for languages with side effects and eager evaluation
run into the problem of side-effectful arguments, and the normal way
around that when writing a macro for such languages is to assign the
value of each argument to a local variable at the beginning of the macro
definition. The problem with that in the case of C and C++ is that
pre-processor macros are unhygienic and inject local variable names
into the call site[1].
 
The way around that in C and C++ is to put every macro definition with
local variables within its own statement block. But then you have the
problem that in C++ statement blocks are not expressions (they cannot
return values). So you end up having to pass in an additional argument
as an out parameter.
 
So you could have something like this as a mostly hygienic version of
MAX:
 
#define MAX(a, b, res) {auto aa = a; auto bb = b; res = (((aa) >= (bb)) ? (aa) : (bb));}
 
Yuck. As you have said, for something simple like 'max' and 'min',
template functions are much to be preferred in C++. They also have the
advantage that they can be made variadic.
 
Chris
 
[1] Less problematically, pre-processor macros also resolve external
identifier names used in the macro (in particular, function and operator
names) from the macro's call site and not from its definition site.
Hygienic macro systems do not do this.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 19 08:31AM -0400

On 6/19/2018 8:21 AM, Stefan Ram wrote:
> their usage in lattice theory.
 
> 2 ⊥ 8 == 2
> 2 ⊤ 8 == 8
 
 
That's not a standard character. How would you propose it be input
into the text editor by people seeking to use it?
 
--
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Jun 19 02:43PM +0200

On 19/06/18 12:28, Chris Vine wrote:
> problem that in C++ statement blocks are not expressions (they cannot
> return values). So you end up having to pass in an additional argument
> as an out parameter.
 
The way around this, whenever possible, is to use inline functions
rather than function-like macros. In C++, templates let you generalise
such functions - in C, C11 generics give you a more limited and
cumbersome solution, but enough to write safe min or max macros.
 
And some compilers (gcc and clang, maybe others) recognised this
limitation long ago and introduced an extension to give you statement
blocks with expression values. Whether or not you want to use such
extensions, is another matter.
 
 
> Yuck. As you have said, for something simple like 'max' and 'min',
> template functions are much to be preferred in C++. They also have the
> advantage that they can be made variadic.
 
With enough effort, you can get a variadic hygienic polymorphic min and
max macro in C11. But it is not nearly as neat as with C++ templates,
or, even better, C++ concepts:
 
auto max(auto a, auto b) {
return (a >= b) ? a : b;
}
 
It's hard to get neater than that!
 
(With concepts, you could add addition constraints that would improve
compile-time errors.)
 
David Brown <david.brown@hesbynett.no>: Jun 19 03:14PM +0200

On 19/06/18 14:31, Rick C. Hodgin wrote:
>> 2 ⊤ 8 == 8
 
> That's not a standard character. How would you propose it be input
> into the text editor by people seeking to use it?
 
They are standard unicode characters, but I don't think they are
standard for maximum or minimum. In lattice theory, they are symbols
for "top" and "bottom" - the maximum of all elements, and the minimum of
all elements. You would normally use ∨ or ∧ for maximum and minimum -
or \/ and /\, or v and ^, if you are restricted to ASCII. Another
alternative would be ⊔ and ⊓.
 
That reminds me - in maths, "a ∨ b" is the /maximum/ and "a ∧ b" is the
minimum, while you wanted to use the opposite symbols. I believe you
are familiar with boolean logic - "a ∨ b" is a way to write "a inclusive
or b", which is the maximum of two boolean values. If you like
axiomatic set theory and the Peano integers, then "maximum" is the same
as set union ∪, and "minimum" is set intersection ∩.
 
All these symbols have the disadvantage that they are difficult to type
with normal keyboard layouts - you need a character map applet, ugly
unicode-by-number input, or you would have to tweak your keyboard layout
files or compose key files (easy enough on *nix if you know what you are
doing, a good deal more difficult on Windows AFAIK). On my keyboard, I
can easily type ↓ and ↑, which would be an option - but that will not
apply to everyone.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 19 09:15AM -0400

On 6/18/2018 4:19 PM, Bart wrote:
 
>> Why wouldn't those character combinations work?
 
> Because \ is usually involved with line continuation. There would be
> ambiguities.
 
I don't think so. While it's theoretically possible to break existing
code, it would have to be a very specific form, and it would be easy
to generate a diagnostic on /\ when it's declared as the last thing on
a line, that there may be ambiguity.
 
I look at additions like this to the language as a new thing, such that
it would introduce new processing logic to the compiler, and therefore
comments like "...won't work for obvious reasons" are rendered of none
effect (due to the enhancements to the compiler's parsing engineb).
 
--
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 19 09:27AM -0400

On 6/19/2018 9:14 AM, David Brown wrote:
> or b", which is the maximum of two boolean values. If you like
> axiomatic set theory and the Peano integers, then "maximum" is the same
> as set union ∪, and "minimum" is set intersection ∩.
 
Never heard of it. I think "a ∨ b" is confusing as a maximum, and
likewise "a ∧ b" is confusing as a minimum. I like the idea of the
arrow pointing up or down for max or min.
 
> doing, a good deal more difficult on Windows AFAIK). On my keyboard, I
> can easily type ↓ and ↑, which would be an option - but that will not
> apply to everyone.
 
CAlive will use /\ for max, and \/ for min, and /\= for max assignment,
and \/= for min assignment. Other languages are free to use whatever
other syntaxes they choose.
 
You can always add this to CAlive to make it work otherwise:
 
#define ∨ /\
#define ∧ \/
 
Or:
 
#define ↑ /\
#define ↓ \/
 
And then you're good to go.
 
--
Rick C. Hodgin
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jun 19 02:32PM +0100

Wildly off-topic now...
 
David Brown <david.brown@hesbynett.no> writes:
<snip>
> or b", which is the maximum of two boolean values. If you like
> axiomatic set theory and the Peano integers, then "maximum" is the same
> as set union ∪, and "minimum" is set intersection ∩.
 
Peano's axioms don't define numbers as sets. You are thinking of von
Neumann's construction of the naturals as sets. They can be used to
build a model of Peano arithmetic that has the property you state. But
other constructions are possible (such a Zermelo's or Frege's) which
give rise to models that don't have that property.
 
<snip>
--
Ben.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 19 03:52PM +0100

On Tue, 19 Jun 2018 14:43:22 +0200
David Brown <david.brown@hesbynett.no> wrote:
[snip]
> With enough effort, you can get a variadic hygienic polymorphic min and
> max macro in C11.
 
Do you know enough about C11 macros to show how that is done? (I would
be interested for that matter in how you get a non-variadic hygienic
macro in C, if that is by using a different technique from the one I
mentioned. I am still stuck on C89/90 as far as C pre-processors are
concerned.)
David Brown <david.brown@hesbynett.no>: Jun 19 05:00PM +0200

On 19/06/18 15:32, Ben Bacarisse wrote:
> build a model of Peano arithmetic that has the property you state. But
> other constructions are possible (such a Zermelo's or Frege's) which
> give rise to models that don't have that property.
 
Yes, it was the von Neumann construction I was thinking of. It's quite
a number of years since I studied this stuff!
David Brown <david.brown@hesbynett.no>: Jun 19 05:08PM +0200

On 19/06/18 15:27, Rick C. Hodgin wrote:
 
> Never heard of it. I think "a ∨ b" is confusing as a maximum, and
> likewise "a ∧ b" is confusing as a minimum. I like the idea of the
> arrow pointing up or down for max or min.
 
Whether or not /you/ find it confusing, this is how it is used in
mathematics. You can decide that your language will never be of
interest to mathematicians or people who know about boolean logic, and
pick symbols that are the direct opposite of the standard. In the same
way, you can decide that your booleans will use "oui" for false and
"non" for true on the basis that you don't know French and don't care
about confusing Frenchmen.
 
Maximum and minimum are not so common operations that they need an
operator. Few programming languages have them as operators - many have
them as built-in functions named "max" and "min". That would seem to me
to be the best approach, avoiding confusing anyone.
 
It's your language. Listen to the advice you are given, or make the
decisions on your own - it's up to you. But remember that every step
you take that is against the flow limits the likelihood of anyone other
than you ever using the language.
 
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 19 11:32AM -0400

On 6/19/2018 11:08 AM, David Brown wrote:
> mathematics. You can decide that your language will never be of
> interest to mathematicians or people who know about boolean logic, and
> pick symbols that are the direct opposite of the standard.
 
I think very few people will use CAlive, David. I think those who do
will be of a particular mindset and it will work for them. It's been
demonstrated below how to fix it up for those who have need.
 
 
>> #define ↑ /\
>> #define ↓ \/
 
>> And then you're good to go.
 
I would like to see these operators and operator assignments added to
the C programming language, as well as C++. If they choose to use the
opposite direction then CAlive will support it.
 
--
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 19 11:47AM -0400

On 6/19/2018 11:08 AM, David Brown wrote:
> ...remember that every step
> you take that is against the flow limits the likelihood of anyone other
> than you ever using the language.
 
These are new features, David. They don't have to be used.
 
-----
I wouldn't waste my time worrying about anything related to me or CAlive.
The language and my offering of its abilities will be given to people.
It will either be received or not, but my effort is in the giving, not in
its success. I seek to give people the best tool with the most features
available, and I am going the extra mile to make it be compatible with C,
and some of C++. This is my offering to the Lord first, and people second.
 
If I get it completed before leave this world, it will be given to people
for free, unencumbered, source code and all, in a variant of the public
domain license (where each person who receives it is asked to use it in a
proper manner, giving their changes and enhancements to people as they also
received it, but I don't force it by man's legal authority, but only leave
it between them and God to voluntarily follow that guidance).
 
But regardless, each person can choose what to do with these skills the
Lord first gave me that I have, in return, given back to Him first, and
to each of you second.
 
-----
When it's released, use it, don't use it. It won't bother me. I am
doing the best I can for my Lord. I am not receiving help in the form
of productive work on the project. Nobody's written a line of source
code on it. The entire creation is my authoring, my doing. And I am
proceeding despite receiving only constant criticism on the choices I
make.
 
At some point you'll have to realize I'm not doing this for you, David,
or anyone else who is critical of my work. I'm doing it for the Lord,
and for those who will receive it.
 
It is the same thing Jesus offers people with salvation. He will not
save those who reject Him, but for all who come to Him, He gives them
forgiveness and eternal life.
 
CAlive is my best offering along those lines. I give it freely to
people, and they will choose to receive it or reject it, but my offer-
ing will tie back explicitly to my giving the Lord the best of what He
first gave me.
 
As I say, I wouldn't waste my time worrying about anything related to me
or CAlive, David. Life's too short. Let it go.
 
--
Rick C. Hodgin
Keith Thompson <kst-u@mib.org>: Jun 19 09:00AM -0700

David Brown <david.brown@hesbynett.no> writes:
[...]
> either case you'd risk ambiguities or complications. Using \ as part of
> an operator would mean changing details of the C parsing. I'd expect it
> to be doable, however.
 
It would require changing translation phase 2, which is where line
splicing occurs.
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Keith Thompson <kst-u@mib.org>: Jun 19 09:01AM -0700

> which may break things. (Side effects don't always necessarily
> affect the variable itself, like in min(a++, b++), but can affect
> other things somewhere else.)
 
Which is why it's traditional to write macro names in all-caps (MIN()
and MAX()) so the reader is reminded that they're macros and can have
odd interactions with side effects.
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 19 08:53AM -0400

I had occasion today to write some code along these lines:
 
for (int pass = 1; pass <= 3; ++pass)
{
switch (pass)
{
case 1:
// Some code unique to pass-1 goes here
break;
 
case 2:
// Some code unique to pass-2 goes here
break;
 
case 3:
// Some code unique to pass-3 goes here
break;
 
default:
// ?? Something invalid
goto finished;
}
 
// Code common to all passes goes here
}
finished:
 
While lnPass should only ever be valid, what do you think about
a need to test the unexpected condition with the "default:" ?
 
--
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 19 09:04AM -0400

Let me try this again:
 
I had occasion today to write some code along these lines:
 
for (int pass = 1; pass <= 3; ++pass)
{
switch (pass)
{
case 1:
// Some code unique to pass-1 goes here
break;
 
case 2:
// Some code unique to pass-2 goes here
break;
 
case 3:
// Some code unique to pass-3 goes here
break;
 
default:
// ?? Something invalid
goto finished;
}
 
// Code common to all passes goes here
}
finished:
 
While "pass" should only ever be valid, what do you think about
a need to test the unexpected condition with the "default:" ?
 
--
Rick C. Hodgin
"Öö Tiib" <ootiib@hot.ee>: Jun 19 08:51AM -0700

On Tuesday, 19 June 2018 16:04:47 UTC+3, Rick C. Hodgin wrote:
> finished:
 
> While "pass" should only ever be valid, what do you think about
> a need to test the unexpected condition with the "default:" ?
 
Given example contains strange design error that I have seen several
times in practice. To explain the design error I just rewrite the
code to equal one:
 
int pass = 1;
// Some code unique to pass-1 goes here
pass = 2;
// Some code unique to pass-2 goes here
pass = 3;
// Some code unique to pass-3 goes here
finished:
 
That is clearly superior way to write same thing as it is more
straight and robust?

If to imagine that the values of "pass" come from somewhere else
but from linear loop, then everything depends on contract with that
source. If it is contract violation (IOW programming or maintenance
error) then I abort the program. If it is required that I ignore
other values then I ignore those. If it is required that I throw 42
on other values then I throw 42. Simple?
woodbrian77@gmail.com: Jun 19 08:19AM -0700

> http://slashslash.info/2018/02/a-foolish-consistency/
 
> https://www.reddit.com/r/cpp/comments/80k8hc/a_blog_rant_on_east_const/
 
> I'm glad Jon is speaking up about this.
 
Here's a script to help people switch to east const:
 
https://www.reddit.com/r/cpp/comments/8ryuee/in_case_you_want_to_migrate_from_constwest_to/
scott@slp53.sl.home (Scott Lurndal): Jun 19 03:29PM


>> https://www.reddit.com/r/cpp/comments/80k8hc/a_blog_rant_on_east_const/
 
>> I'm glad Jon is speaking up about this.
 
>Here's a script to help people switch to east const:
 
Why on earth would someone want to do something so silly? Talk
about churn for the sake of churn.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: