Friday, March 2, 2018

Digest for comp.lang.c++@googlegroups.com - 18 updates in 4 topics

"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Mar 02 02:31PM -0800

On 3/1/2018 4:07 AM, Rick C. Hodgin wrote:
 
> Begin with this question: "Have I ever sinned?"
 
> When you realize the answer is "yes," then you must go and see
> about the rest.
 
Why must we always realize the answer is "yes"? Is it because if we
choose another answer, then we get threatened? Interesting.
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Mar 02 02:34PM -0800

On 2/28/2018 3:32 PM, Öö Tiib wrote:
 
>> If we ever meet, please do not try to grab me.
 
>> [...]
 
> Please, it is not nice to tease kooky people.
 
Yes. It is also dangerous. You might get them thinking about beating you
up into some sort of pulp.
 
 
JiiPee <no@notvalid.com>: Mar 02 03:54AM

> // loop perpetually, doing nothing useful
> }
> }
 
Are you talking about the syntactical errors: +i => ++i? yes was mean to
be ++i
JiiPee <no@notvalid.com>: Mar 02 04:03AM

On 01/03/2018 20:20, Öö Tiib wrote:
 
>> so here is no variables and one simple function call. So how would you
>> end that otherwise than using a goto?
> There is nothing wrong with goto there. It has been already replied
 
Yes just wanted to hear experienced peoples opinions. First time I am
also using it. I just used it in my code and checking hoe it goes.
 
I only use goto if I dont have anything better at that moment. Like a
long function and for some reason (no time, lazyness or just liking that
long function! etc) and need to do a long jump there. I couple of times
used it and felt actually fine with it there.
 
Some programmers say they want long functions (C programmers mostly) in
order to see clearly what is happening. Others use only small functions
for everything. I kinda go in the middle: sometimes long functions but
mostly short ones. Sometimes I feel that in a long function I can see
all clearly and if am sure that code does not need to be changed then I
felt like making it long.
 
> that it can be replaced with making the loop separate function
> and using return instead of goto in it.
 
I kinda feel like I want to see that for loop "in place" (especially if
its short) so I dont need to scroll to see it. But maybe a matter of
getting used to doing different things. thats why I like lambdas: can
see in-place what is happening.
 
Ian Collins <ian-news@hotmail.com>: Mar 02 05:19PM +1300

On 03/02/2018 05:03 PM, JiiPee wrote:
> long function and for some reason (no time, lazyness or just liking that
> long function! etc) and need to do a long jump there. I couple of times
> used it and felt actually fine with it there.
 
Short functions are easier to read, easier to test and easier to avoid
the delusion that you need a goto...
 
> mostly short ones. Sometimes I feel that in a long function I can see
> all clearly and if am sure that code does not need to be changed then I
> felt like making it long.
 
You end up loosing the wood for the trees. It's much clearer for most
readers to see the logic of a function if the (to them) irrelevant
detail is elsewhere. If they want to see the details, they can find it,
if they don't it isn't in their face. They have a choice!
 
> its short) so I dont need to scroll to see it. But maybe a matter of
> getting used to doing different things. thats why I like lambdas: can
> see in-place what is happening.
 
As I sad before, give the function with the details a meaningful name
and this won't be a problem.
 
If you used a goto in my team, you would probably end up wearing a road
code on your head for the week!
 
--
Ian.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 01 02:55PM +0100

On 01.03.2018 01:57, JiiPee wrote:
> afterLoop:
 
> I googled and this seems to be manys preferably way. I have this often.
> How would you break nested loops? Somebody said Substroup said this is ok.
 
I forgot to mention, you can also use a single 2D index and ordinary
`break` from the then single `for` loop, like this:
 
#include <iostream>
#include <iomanip>
using namespace std;
 
auto main()
-> int
{
const int w = 5;
const int h = 7;
for( my::Indices indexing{{ w, h }}; not indexing.at_end();
++indexing )
{
if( inner( indexing ) == 3 and outer( indexing ) == 5 )
{
break;
}
 
const bool first_item = (inner( indexing ) == 0);
const bool new_row = (first_item and outer( indexing )
> 0);
 
cout << (new_row? "\n" : first_item? "" : ", ");
cout << setw( 2 ) << inner( indexing ) + 5*outer( indexing );
}
cout << endl;
}
 
Support machinery that can easily be made reusable (amortized O(1)
programmer's time):
 
#include <array>
 
namespace my{
using std::array;
 
struct Indices
{
static constexpr int n = 2;
 
array<int, n> const limits;
array<int, n> values;
 
void operator++()
{
for( int i = 0; i < n; ++i )
{
int& index = values[i];
++index;
if( index != limits[i] )
{
break;
}
index = 0;
}
}
 
auto at_end() const
-> bool
{
for( int i = 0; i < n - 1; ++i )
{
if( values[i] != 0 )
{
return false;
}
}
return values.back() == limits.back();
}
};
 
inline auto inner( Indices& indexing )
-> int&
{ return indexing.values[0]; }
 
inline auto outer( Indices& indexing )
-> int&
{ return indexing.values[1]; }
 
} // namespace my
 
Cheers & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 01 02:58PM +0100

On 01.03.2018 14:55, Alf P. Steinbach wrote:
 
>     }  // namespace my
 
> Cheers & hth.,
 
> - Alf
 
Oh so nice there's a bug -- to find. :-)
 
Cheers!
 
- Alf
Ralf Goertz <me@myprovider.invalid>: Mar 02 10:58AM +0100

Am Thu, 1 Mar 2018 17:58:37 +0000
> endloop:
 
> so here is no variables and one simple function call. So how would
> you end that otherwise than using a goto?

I sometimes have a somewhat different problem whose solution might be
applicable here as well. Suppose you don't know in advance how many
nested loops there will be and their ranges aren't necessarly the same
like they are in your example. Then you can still use just one loop and
therefore just one break:
 
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
 
using namespace std;
 
typedef vector<unsigned long> vec_type;
 
int main(int argc, char *argv[]) {
if (argc==1) {
cerr<<"usage "<<argv[0]<<" n_1 n_2 … n_n\n\nwhere [0…n_i) is the range of the i'th loop\n";
return -1;
}
vec_type n(argc-1),m(n);
for (int i=1;i<argc;++i) {
m[i-1]=stoul(argv[i]);
}
if (m==n) return 0; //nothing to do
bool stop;
do {
//do something
copy(n.begin(),n.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//do I need to break?
if (count_if(n.begin(),n.end(),[](vec_type::value_type i) {return i==1;})==2)
break;
//next
stop=true;
for (int i=0;i<n.size();++i) {
if (++n[i]>=m[i]) {
n[i]=0;
} else {
stop=false;
break;
}
}
} while (!stop);
}
JiiPee <no@notvalid.com>: Mar 01 05:45PM

On 01/03/2018 02:21, Christiano wrote:
> And the solution with goto seems very simple.
 
 
Just first time testing goto in my code to see how it works.
 
But sure sometimes the solution is to make better code structure.. but
its a handy solution for quick fix if perfect code not needed.
JiiPee <no@notvalid.com>: Mar 02 12:17PM

On 02/03/2018 04:19, Ian Collins wrote:
> If you used a goto in my team, you would probably end up wearing a
> road code on your head for the week!
 
even using goto in the above example?
JiiPee <no@notvalid.com>: Mar 01 05:47PM

On 01/03/2018 02:35, Bo Persson wrote:
> If you have 4 nested loops using 10 different variables, how are we
> going to know their values after the goto?
 
no but how about a very simple 4 nested loop (like doing only one
assigment and having 0-1 variables). Then goto would work pretty well?
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 02 09:31PM

On Fri, 2018-03-02, JiiPee wrote:
...
> mostly short ones. Sometimes I feel that in a long function I can see
> all clearly and if am sure that code does not need to be changed then I
> felt like making it long.
 
It depends on how it's done and how you look at it. Let's say you
have a 100-line function. If you split it into four 25-line
functions, the code is going to be worse. If you can extract a
function with a clear and memorable meaning, I think most people won't
mind that, even if the function is only used once.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
legalize+jeeves@mail.xmission.com (Richard): Mar 02 10:22PM

[Please do not mail me a copy of your followup]
 
Jorgen Grahn <grahn+nntp@snipabacken.se> spake the secret code
>> mostly short ones. Sometimes I feel that in a long function I can see
>> all clearly and if am sure that code does not need to be changed then I
>> felt like making it long.
 
C programmers write long functions because they have little to no
facilities for abstraction.
 
>It depends on how it's done and how you look at it. Let's say you
>have a 100-line function. If you split it into four 25-line
>functions, the code is going to be worse.
 
Meh. As stated in terms of statement counts, it's hard to say either
way. The reason "comments" are listed as a code smell by Fowler[1]
is that long functions are often naturally broken up into smaller
chunks separated by blank lines and a little comment:
 
void f()
{
// step 1: ...
...
 
// step 2: ...
...
 
// step 3: ...
...
}
 
This is already written as a sequence of higher level operations, they
just aren't using the facilities of the language to express that
directly in code. When f() has lots of intermediate state held in
many variables, then extracting the pieces in C is painful because it
imposes large argument lists on the extracted pieces.
 
In C++, if f() is a method then the intermediate state is more likely
to be held in instance variables for the enclosing class and
extracting more methods results in reasonable argument lists. In the
extreme case, you might do Replace Method with Method Object and push
all the local state into instance member state on the new method
object.
 
In my experience in refactoring long methods, pulling out the larger
chunks is usually quite easy and results in a method that clearly
states the larger steps taken to achieve the final result. The
original long function becomes a "sergeant" function: it doesn't do
the work directly, it delegates the work out to private methods that
do the work.
 
>If you can extract a
>function with a clear and memorable meaning, I think most people won't
>mind that, even if the function is only used once.
 
Stroustrup talks about how most functions should be about 5 lines
long or less. Imagine how you get to that from a 100 line function.
Practicing this transformation is not only instructive in practicing
refactoring, it is instructive in the design mindset. To get to 5
line functions you need to have lots of fine-grained abstractions that
you can easily reuse and you find yourself reaching for the standard
library algorithms more often. (Replace 5 lines of custom loop with 1
invocation of a standard library algorithm.) I think Ranges will make
this style of use of the standard library algorithms even more readable
as 99% of the time you operate on the entire container and not a
subrange.
 
It's the zero-overhead abstraction facilities of C++ that make this
possible. In C, we have no facilities for creating a value type that
encapsulates things like "2D point", "2D vector", etc., so we are
forced to write low-level details all the time. I hear C programmers
saying that this is a feature not a bug because "they know exactly
what is happening all the time", but IMO this is simply a
rationalization for not thinking at a level beyond low-level details.
It is possible to use abstractions in C, but the level of manual
mechanical fiddling is burdensome, repetitive and boring. C++
provides these mechanisms already, so just use it.
 
[1] Fowler, Martin: "Refactoring: Improving the Design of Existing Code"
<http://amzn.to/2oDj4aC>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Ralf Goertz <me@myprovider.invalid>: Mar 02 09:48AM +0100

Am 1 Mar 2018 20:24:14 GMT
 
> - You assume the port has to be numerical, but it costs nothing to let
> the user give standard service names. (This was one of the
> weaknesses in the OP's specification.)
 
Hm in https://en.wikipedia.org/wiki/URL it is explicitly stated: "An
optional port *number*, separated from the hostname by a colon"
[emphasis by me]
 
> - You could probably simplify the expression by using the non-greedy
> modifier here and there e.g. .+?: instead of [^:]+: to say "some
> text before a colon".
 
The reason I don't use non-greedy regexes is that I extensively program
using „flex" and that does not support non-greediness.
 
> - More weaknesses from the specification: I suspect a valid protocol
> name is matched by \w+ ("one or more word characters") but you
> accept for example a single space.
 
That's right of course. But the goal was to show how to extract the
various fields of a well-formed url.
 
> - The OP should add plenty of negative tests too.
 
ACK
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 02 09:43PM

On Fri, 2018-03-02, Ralf Goertz wrote:
 
> Hm in https://en.wikipedia.org/wiki/URL it is explicitly stated: "An
> optional port *number*, separated from the hostname by a colon"
> [emphasis by me]
 
Oh. Makes sense when you think about it: if you have to specify
anything, it's because you want to use a non-standard number. I
didn't really look at the RFC, because I was uncertain if the OP
really wanted to parse an URL.
 
But I still want to point out that in general, users expect to be able
to enter service names (just as they expect to be able to enter domain
names rather than IP addresses).
 
>> text before a colon".
 
> The reason I don't use non-greedy regexes is that I extensively program
> using „flex" and that does not support non-greediness.
 
I recommend getting familiar with them: in Perl and Python regular
expressions I tend to use them a lot. Those REs tend to be easier to
read, IMO.
 
But I'm happy to hear someone still uses flex.
 
> various fields of a well-formed url.
 
>> - The OP should add plenty of negative tests too.
 
> ACK
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
legalize+jeeves@mail.xmission.com (Richard): Mar 02 10:04PM

[Please do not mail me a copy of your followup]
 
Jorgen Grahn <grahn+nntp@snipabacken.se> spake the secret code
 
>But I still want to point out that in general, users expect to be able
>to enter service names (just as they expect to be able to enter domain
>names rather than IP addresses).
 
In the case of URLs I wouldn't start accepting service names instead
of port numbers because it confuses the issue of what is a URL.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
scott@slp53.sl.home (Scott Lurndal): Mar 02 03:40PM


>>I remember we had to do KWIC in COBOL at university. 1986. It was on a
>>Burroughs mainframe.
 
>B6700? :)
 
Not in 1986. Probably a 900-series (B2900/B3900/B4900/B5900/B6900/B7900)
or maybe a V-series.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 02 09:50PM

On Thu, 2018-03-01, Öö Tiib wrote:
> strange thing. Better erase it and write something that aids or
> simplifies with usage of Doxygen. I can't tell what could make it
> more trivial but judging by your work you have better fantasy than me.
 
It's unclear to me, but he *may* have created something that's
orthogonal to Doxygen and yet useful.
 
https://en.wikipedia.org/wiki/Key_Word_in_Context
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
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: