Tuesday, November 10, 2015

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

"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 10 05:07AM +0100

On 11/9/2015 3:57 PM, Alf P. Steinbach wrote:
 
> auto hopefully( bool const condition )
> -> bool
> { return condition; }
 
This and other functions should be `inline`. I just noticed. This
resulted from writing the code in an implementation file first, and
moving it wholesale to a header when I decided to do more variations of
the problem.
 
Cheers,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Nov 09 11:30PM -0800

On Tuesday, 10 November 2015 06:07:31 UTC+2, Alf P. Steinbach wrote:
> resulted from writing the code in an implementation file first, and
> moving it wholesale to a header when I decided to do more variations of
> the problem.
 
It can be that you have already elaborated purpose of that 'hopefully'
and 'fail' in text that I haven't read. If so then please post a
link.
 
Otherwise ... my impression is that these are made for indicating error
handling syntax. That syntax:
 
if ( !condition )
throw runtime_error( "condition not met" );
 
Replaced with that syntax:
 
hopefully( condition )
|| fail( "condition not met" );
 
I can't see a benefit. Typical project-specific generic error handling
doesn't use neither syntax. Most often I have seen something like
'R_VERIFY(condition,text);' where 'R_VERIFY' is some project-specific
macro name.
Juha Nieminen <nospam@thanks.invalid>: Nov 10 09:38AM

> using std::wcin;
> using std::wistream;
> using std::wstring;
 
Are you serious?
 
Just use those prefixes. It's not that bad. On the contrary, they will make
your code more readable (for a very similar reason as why code coloring
does.)
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 10 12:39PM +0100

On 11/10/2015 8:30 AM, Öö Tiib wrote:
 
> hopefully( condition )
> || fail( "condition not met" );
 
> I can't see a benefit.
 
I like it. :)
 
Well, first, when the function call whose result should be tested,
produces a convertible-to-boolean value, one avoids using an
if-condition with side effects or introducing a logically redundant
variable to hold the function result.
 
bool const success = foo();
if( not success )
{
throw runtime_error( "foo: failed" );
}
 
or
 
if( not foo() )
{
throw runtime_error( "foo: failed" );
}
 
versus just
 
foo()
|| fail( "foo: failed" );
 
Second, it makes failure generation stand out visually. Even more so
when one adopts a convention of using "and", "or" and "not" for ordinary
boolean expressions that produce not ignored values.
 
Third, with just a little more machinery it makes it easy to pick up the
function result value and apply any condition to it, or embed in the
failure message, whatever.
 
So, the "hopefully" function is simply in support of "fail", to make it
possible and practical to use "fail" also where the function is not
producing a convertible-to-boolean, and more in general, to use "fail"
in all kinds of situations without introducing more advanced machinery.
 
I.e. a single convention (I like single conventions).
 
 
> doesn't use neither syntax. Most often I have seen something like
> 'R_VERIFY(condition,text);' where 'R_VERIFY' is some project-specific
> macro name.
 
Uhm, proliferation of macros = evil, IMHO :)
 
But I think a /single macro/ to pick up filename, function name and line
number can be a good idea.
 
Such a macro can be used with any scheme, given proper support, and then
few if any will wonder exactly what it does, for it will be known and
familiar to all programmers on the project. I believe. Uh, hope! :)
 
 
Cheers,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 10 12:58PM +0100

On 11/10/2015 11:56 AM, Stefan Ram wrote:
 
> ftp.cs.stanford.edu/tex/tex/tex.web
 
> (via HTTP) and then search for
 
> Breaking paragraphs into lines
 
Thanks for the link. ITYM "via FTP", but anyway. Is this part of Knuth's
self-documented code initiative?
 
It's doesn't look very clear to me, but then, TeX never did look clear
to me! :)
 
Anyway I don't share the lecturer's opinion about the difficulty of the
problem (by modern standards it's pretty basic); I just quoted it.
 
* * *
 
I think the task is interesting for a very different reason, namely that
there are at least 3 very different approaches to it, corresponding to
what one thinks is the natural top level goal:
 
* process a bunch of input lines, or
* generate a bunch of output lines, or
* looking at it as a data flow problem.
 
The latter can be expressed with OO techniques but is more naturally
expressed as parallel processing, either with threads or with
coroutines. I chose threads since the C++ standard library, very
unfortunately, doesn't support coroutines. I believe a coroutine
solution would be much simpler since one avoids the synchronization.
 
Cheers,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Nov 10 09:20AM -0800

On Tuesday, 10 November 2015 13:40:10 UTC+2, Alf P. Steinbach wrote:
> > || fail( "condition not met" );
 
> > I can't see a benefit.
 
> I like it. :)
 
That I ... already assumed. :)
 
 
> versus just
 
> foo()
> || fail( "foo: failed" );
 
IOW, it can be used as more terse compared to explicit 'throw'. That is
always good reason.
 
 
> Second, it makes failure generation stand out visually. Even more so
> when one adopts a convention of using "and", "or" and "not" for ordinary
> boolean expressions that produce not ignored values.
 
Yes, it stands out from 'if'-s.
 
 
> Third, with just a little more machinery it makes it easy to pick up the
> function result value and apply any condition to it, or embed in the
> failure message, whatever.
 
Doesn't such a machinery result with loss of terseness?
 
> producing a convertible-to-boolean, and more in general, to use "fail"
> in all kinds of situations without introducing more advanced machinery.
 
> I.e. a single convention (I like single conventions).
 
That again is good reason.
 
 
> Uhm, proliferation of macros = evil, IMHO :)
 
> But I think a /single macro/ to pick up filename, function name and line
> number can be a good idea.
 
Yes, such meta-information is often desired in failures and diagnostic traces
and it isn't available to functions. Some of meta-information can be added
by replacing 'fail( text )' with 'FAIL( text )' that gathers it.
 
Macro with two parameters covers also all your reasons. Macro can be single
convention. It is relatively terse. It is idiomatically capitalized so it also stands
out in C++ where we generally avoid macros. Benefit of macro is that some
projects may want also that 'condition' stringized. I'm unsure about various
sorts of other "machinery" (fit well into macro).
 
 
> Such a macro can be used with any scheme, given proper support, and then
> few if any will wonder exactly what it does, for it will be known and
> familiar to all programmers on the project. I believe. Uh, hope! :)
 
What failure generation does may change during project or depend on target
platform or build reason (unit test/debug/release). I need to dig around in
codebases and think about it a bit but I hope that I see your point now, thank
you.
Christian Gollwitzer <auriocus@gmx.de>: Nov 10 07:09PM +0100

Am 09.11.15 um 15:57 schrieb Alf P. Steinbach:
> 3 This is essentially word-wrapping within a paragraph of a text
> editor. "As such, it is a classic ObjectOriented problem, used as an
> example in the Design Patterns Book."
 
Design Patterns? WTF?
 
 
> 4 It is surprisingly difficult to specify correctly, and to design a
> correct program in Java or C++.
 
???
 
 
> So ;-)
 
> <file "cppx.hpp">
> [...]
 
What an utter complicated mess. Even if C++ is not as good at string
processing as, say, awk, perl or Tcl, I cannot believe that you need
coroutines or threads (WTF? Mutexes???) for such a simple problem. What
is wrong with the following solution, implemented as a Unix filter:
 
Apfelkiste:Tests chris$ cat wordwrap.cpp
#include <iostream>
#include <string>
 
int main() {
const int wraplength=80;
 
std::string outputline;
while (true) {
std::string word;
std::cin >> word;

if (!std::cin) { break; }
 
if (outputline.length()+1+word.length() > wraplength) {
std::cout<<outputline<<std::endl;
outputline="";
}
 
if (outputline == "") {
outputline = word;
} else {
outputline = outputline + " " + word;
}
}
 
std::cout<<outputline<<std::endl;

return 0;
}
 
Apfelkiste:Tests chris$ g++ wordwrap.cpp
Apfelkiste:Tests chris$ ./a.out < wordwrap.cpp
#include <iostream> #include <string> int main() { const int wraplength=80;
std::string outputline; while (true) { std::string word; std::cin >>
word; if
(!std::cin) { break; } if (outputline.length()+1+word.length() >
wraplength) {
std::cout<<outputline<<std::endl; outputline=""; } if (outputline == "") {
outputline = word; } else { outputline = outputline + " " + word; } }
std::cout<<outputline<<std::endl; return 0; }
Apfelkiste:Tests chris$
 
 
Christian
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 10 10:59PM +0100

On 11/10/2015 7:09 PM, Christian Gollwitzer wrote:
 
>> <file "cppx.hpp">
>> [...]
 
> What an utter complicated mess.
 
It would be nice if you could supply some of your reasons for landing on
this conclusion.
 
Most of that header is very simple stuff as I see it.
 
The "Pipe" class is possibly more complicated than strictly necessary.
 
 
> Even if C++ is not as good at string
> processing as, say, awk, perl or Tcl, I cannot believe that you need
> coroutines or threads (WTF? Mutexes???) for such a simple problem.
 
You are correct sir. Two of the three posted solutions did not use that.
 
 
> What is wrong with the following solution, implemented as a Unix filter:
 
Not so much if it only targets Unix-land, with an assumption of ASCII
encoding.
 
For Windows you'd better use wide strings and wide streams. This has to
do with recognition of whitespace as such. Unicode has some 25
characters designated as whitespace. I don't know how well the standard
library supports that, but it can't support it with SBCS encoding.
 
Or, one may simply roll that problem up in one's definition of "word". ;-)
 
For an empty input this code outputs a blank line, but also that's
ultimately a matter of specification.
 
Also it has a hardcoded max line length instead of the problem
statement's "takes a number w", which is not a matter of specification,
but is trivial to fix.
 
 
> outputline = word; } else { outputline = outputline + " " + word; } }
> std::cout<<outputline<<std::endl; return 0; }
> Apfelkiste:Tests chris$
 
Apparently the above code strives for shortness, leveraging the
word-splitting ability of the input stream, and in general the C++
standard library.
 
I didn't cover that angle because it was not so interesting for what I
was investigating.
 
But I think the following is shorter, while clear, don't you agree?
 
#include <iostream>
#include <string>
using namespace std;
 
auto main( int, char** args ) -> int
{
int const max = stoi( args[1] );
wstring word, separator, line;
while( wcin >> word ) {
if( int(line.length() + 1 + word.length()) > max ) {
wcout << line << endl;
line.clear();
}
line += (line.length()? L" " : L"") + word;
}
wcout << line << endl;
}
 
In case you'd think there a missing "return": nope.
 
Cheers & hth.,
 
- Alf (dang, should really have posted short code also, thanks!)
Juha Nieminen <nospam@thanks.invalid>: Nov 10 09:33AM


> the_loop_variable
 
> instead of
 
> i
 
Of course the opposite of needless brevity in variable names is not to
make the variable names long but meaningless. They should be descriptive.
 
Compare:
 
for(int i = 0; i < amount; ++i)
 
for(int the_loop_variable = 0; the_loop_variable < amount; ++the_loop_variable)
 
for(int playerIndex = 0; playerIndex < amount; ++playerIndex)
 
Which one of those is most descriptive, even without seeing the context?
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 10 03:27PM

On Tue, 2015-11-10, Juha Nieminen wrote:
 
> for(int the_loop_variable = 0; the_loop_variable < amount; ++the_loop_variable)
 
> for(int playerIndex = 0; playerIndex < amount; ++playerIndex)
 
> Which one of those is most descriptive, even without seeing the context?
 
I'm going to be obnoxious by pointing out that you cannot disregard
context. Short names, if they are any good, rely completely on
being obvious /in context/.
 
(I'm a bit worried by "amount", by the way. Doesn't seem to mix that
well with a loop index.)
 
(Meta: I know this subject has been beaten to death many times before.
But I still find it interesting, mostly because talking about it gives
insight into how other programmers think.)
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
"Öö Tiib" <ootiib@hot.ee>: Nov 10 09:45AM -0800

On Tuesday, 10 November 2015 17:28:12 UTC+2, Jorgen Grahn wrote:
> On Tue, 2015-11-10, Juha Nieminen wrote:
 
...
 
 
> > for(int i = 0; i < amount; ++i)
 
> > for(int the_loop_variable = 0; the_loop_variable < amount; ++the_loop_variable)
 
> > for(int playerIndex = 0; playerIndex < amount; ++playerIndex)
 
...

> (I'm a bit worried by "amount", by the way. Doesn't seem to mix that
> well with a loop index.)
 
"amount" is perhaps result of Juha fixing magic number error '10' automatically
without much thinking from Richard's example:
 
for (int the_loop_variable = 0; the_loop_variable < 10; ++the_loop_variable)
{
cout << the_loop_variable << '\n';
}
 
That '10' does pass no reviews especially when author is using names like
'the_loop_variable'. Reviews of such code will be from unfriendly to extreme anal.
I have seen even coding standard extended to suggest against using various
ballast words (like "data", "item", "value", "the", "buffer", "variable", "list", "info")
in names thanks to such guys.
Gareth Owen <gwowen@gmail.com>: Nov 10 06:32PM

> underscores to separate words and ease readability is almost sadistic.
 
> But I suspect it made perfect sense to him, and was written in good
> faith.
 
Oh, I'm sure it was ... that doesn't make me feel any better tho.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 10 07:09PM

On Tue, 2015-11-10, 嘱 Tiib wrote:
> On Tuesday, 10 November 2015 17:28:12 UTC+2, Jorgen Grahn wrote:
>> On Tue, 2015-11-10, Juha Nieminen wrote:
...
>> well with a loop index.)
 
> "amount" is perhaps result of Juha fixing magic number error '10'
> automatically without much thinking from Richard's example:
 
Yes, I'm pretty sure it was something like that.
I guess that makes "amount" a good name -- because it made
me suspicious.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
ram@zedat.fu-berlin.de (Stefan Ram): Nov 10 10:56AM

>4 It is surprisingly difficult to specify correctly, and to design a
>correct program in Java or C++.
 
For an algorithm by Knuth load
 
ftp.cs.stanford.edu/tex/tex/tex.web
 
(via HTTP) and then search for
 
Breaking paragraphs into lines
 
.
ram@zedat.fu-berlin.de (Stefan Ram): Nov 10 12:17PM

> * process a bunch of input lines, or
> * generate a bunch of output lines, or
> * looking at it as a data flow problem.
 
To me it is a problem of global optimization.
 
I first read the paragraph into a buffer.
 
Then, I conceptually assign a quality to every possible way
to break the paragraph into lines. For example
 
alpha beta gamma
delta epsilon zeta eta theta
iota kappa lambda.
 
has a lower quality than
 
alphe beta gamma delta
epsilon zeta eta theta
iota kappa lambda.
 
because the standard deviation of the lenghts of the lines
is smaller in the second case. (But this standard deviation
is only /one/ component of the overall quality assessment.)
 
In the end, the program then will have found the best way.
 
That is, a break choice in the first output line might yield
a poor quality in lines 7-9, thus, /global/ optimization,
and therefore might have to be revised. So, the quality of
break choice for later lines (lines 7-9) might influence the
choice for earlier lines (e.g., line 1).
 
When I prepare a post for the Usenet, I often try to do this
manually.
 
The challenge is to reasonably prune the search tree so as
not to exceed the resources when a paragraph is long.
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: