Author Topic: Good Ideas, Through the Looking Glass  (Read 6976 times)

0 Members and 1 Guest are viewing this topic.

Online PlainName

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: va
Re: Good Ideas, Through the Looking Glass
« Reply #50 on: April 18, 2023, 01:46:27 pm »
How is setting some variable, purely to exit the loop, better than a simple break? The two do the same thing, but the variable is make work and verbose, there just to not have 'break'. With break you can at least search for it, and when you see it you know exactly what it means (which of is_donex actually terminates the loop? - easy to see the wrong one).
 
The following users thanked this post: newbrain, DiTBho

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #51 on: April 18, 2023, 07:08:00 pm »
Code: [Select]
private void app()
{
    loop_t    loop0;
    loop_t    loop1;
    loop_t    loop2;

    init { loop0, loop1, loop2 };
    bond { loop0, loop1, loop2 };

    loop0.i'range = { 0 .. 10 };
    loop1.i'range = { 0 .. 20 };
    loop2.i'range = { 0 .. 30 };

    during loop0
    {
        during loop1
        {
            during loop2
            {
                loop2.i++;
            }
            loop1.i++;
        }
        loop0.i++;
    }
}
(bad?) side effect: it works  ;D


The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online PlainName

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: va
Re: Good Ideas, Through the Looking Glass
« Reply #52 on: April 18, 2023, 08:50:07 pm »
Why is there 'loopn.i++'? Surely, a run around the loop counts as +1 so you shouldn't need to increment anything. In fact, having to increment the loop counter makes a mockery of it since you could make it any value: 1, 2, 24, -6, 3,...

Given that context, the C style of having the loop counter within the loop definition seems preferable: it's in one defined place, easily digested and no hidden gotchas buried in the loop somewhere (at least, there shouldn't be).
 
The following users thanked this post: DiTBho

Online SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 15257
  • Country: fr
Re: Good Ideas, Through the Looking Glass
« Reply #53 on: April 18, 2023, 09:18:54 pm »
How is setting some variable, purely to exit the loop, better than a simple break? The two do the same thing, but the variable is make work and verbose, there just to not have 'break'. With break you can at least search for it, and when you see it you know exactly what it means (which of is_donex actually terminates the loop? - easy to see the wrong one).

This is questionable - I'll again refer to the additional article I posted about exiting loops.

One reason to use flags to exit loops rather than instructions that directly control the flow is to have the loop "condition" at a single place in the loop's construct rather than spread out everywhere in the loop's body. The main idea is that the loop's condition should be the loop's invariant. The invariant should be unambiguous, written at a single place, and ideally easy to understand.

The problem is that while some algorithms lend themselves very well to this approach, others do not and would be pretty hard to write with this strict model.

And then, if you artifically set intermediate flags in the loop's body just to fit this strict model, you'll quickly run into a pretty similar situation as with additional flow control statements within the loop - just possibly even harder to read.

Sometimes, you can rewrite your loop in a way that better fits the "invariant" model. That may imply splitting one loop into several distinct ones.
As it doesn't come very naturally to most of us, we tend to prefer having a way to break out of loops in direct fashion, even if that makes analyzing the invariants much trickier.

But strictly speaking, if you can't exactly tell what your invariant is, you don't know what your loop does.
 
The following users thanked this post: DiTBho

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #54 on: April 18, 2023, 09:51:08 pm »
Why is there 'loopn.i++'?

as much as advanced the "auto loop" is, it still needs "a hamster to spin the wheel" (what? )
and you end up needing "something" that increments the counter  :o :o :o

Note, i++ is a saturated increment operator(2), which guarantees the counter never goes out of its range

having to increment the loop counter makes a mockery of it since you could make it any value: 1, 2, 24, -6, 3,...

the symbol ' means "property", you assign the range { lower .. upper }  property to the loop counter

always guaranteed:       lower <= counter <= upper

property is a great trick in my-c as it permits other tricks  ;D ;D ;D

This example uses a side effect to automatically re-initialize the counter when it encounters the keyword "during", and that's it, all the rest works exactly as the previous two examples, just it's all "hidden", but as soon as the counter is equal to the counter'range.upper, is_EOL becomes true,  is_done becomes also true, all auto-magically, and the loop ends.

However, in this example there is also a second side effect, and a difference a difference from the previous first example: this time, if the loop ends without an error then the counter is ***exactly*** equal to the upper bound.

C/89 loop:
for (i=0; i<10; i++) { } ;
/* i'range = { 0 .. 9 }
the counter i is equal to 10 at the end of the loop ----------> potentially an "out by one" bug(1)

C/99 loop:
for (uint32_t i=0; i<10; i++) { } ;
/* i'range = { 0 .. 9 }
the counter i is ... no more existing after the loop :o :o :o

my c previous first example:
the counter is equal to 10 at the end of the loop ------------> potentially an "out by one" bug(1)

my C auto loop:
loop.i'range = { 0 .. 9 };
during loop { loop.i++; }
/* i'range = { 0 .. 9 }
loop.i = 9 at the end of the loop


Given that context, the C style of having the loop counter within the loop definition seems preferable: it's in one defined place, easily digested and no hidden gotchas buried in the loop somewhere (at least, there shouldn't be).

in C you can go over the counter range and you can be "out of one"; in my-c it is impossible as being strict in-range is guaranteed.

In C you have to think a way to "exit" from an inner loop (goto? break?), in my-c you just need to invoke .is_EOL or .is_done, that's good as it facilitates step-by-step manual debugging and ICE-testcases.



edit:
(1) when the counter is used in some following statement under the belief that it is in-range
(2) you can override its reactive code callback and invoke "panic()" or a "console_out_warning()" to be warned that a counter has gone out of its range -> probably a bug.
« Last Edit: April 19, 2023, 10:46:05 am by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #55 on: April 18, 2023, 09:56:18 pm »
One reason to use flags to exit loops rather than instructions that directly control the flow is to have the loop "condition" at a single place in the loop's construct rather than spread out everywhere in the loop's body. The main idea is that the loop's condition should be the loop's invariant.

that's what an ICE wants.
So, it's better for test-cases.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online PlainName

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: va
Re: Good Ideas, Through the Looking Glass
« Reply #56 on: April 19, 2023, 11:26:30 am »
Quote
One reason to use flags to exit loops rather than instructions that directly control the flow is to have the loop "condition" at a single place in the loop's construct rather than spread out everywhere in the loop's body.

Yes, I accept that. That lets you know at least what you are looking for, but it's then still a hunt for where it is being set. The use of an exit flag doesn't actually help much more in knowing why the loop is done. I mean, what does the variable "done" mean? There is also scope for gymnastics in  trying not to do things in the loop after the exit determination but before the end of the loop body so the flag can trigger the exit. Of course, if one had designed the thing better in the first place...

Quote
But strictly speaking, if you can't exactly tell what your invariant is, you don't know what your loop does.

Indeed. However, one may not own the loop (that is, it is not 'my' loop but someone elses that I am trying to figure out what it does), so the probability is that one doesn't know anyway.
 
The following users thanked this post: DiTBho

Offline Ed.Kloonk

  • Super Contributor
  • ***
  • Posts: 4000
  • Country: au
  • Cat video aficionado
Re: Good Ideas, Through the Looking Glass
« Reply #57 on: April 19, 2023, 11:38:05 am »
Why is there 'loopn.i++'?

as much as advanced the "auto loop" is, it still needs "a hamster to spin the wheel" (what? )
and you end up needing "something" that increments the counter  :o :o :o

Note, i++ is a saturated increment operator(2), which guarantees the counter never goes out of its range

having to increment the loop counter makes a mockery of it since you could make it any value: 1, 2, 24, -6, 3,...

the symbol ' means "property", you assign the range { lower .. upper }  property to the loop counter

always guaranteed:       lower <= counter <= upper

property is a great trick in my-c as it permits other tricks  ;D ;D ;D

This example uses a side effect to automatically re-initialize the counter when it encounters the keyword "during", and that's it, all the rest works exactly as the previous two examples, just it's all "hidden", but as soon as the counter is equal to the counter'range.upper, is_EOL becomes true,  is_done becomes also true, all auto-magically, and the loop ends.

However, in this example there is also a second side effect, and a difference a difference from the previous first example: this time, if the loop ends without an error then the counter is ***exactly*** equal to the upper bound.

C/89 loop:
for (i=0; i<10; i++) { } ;
/* i'range = { 0 .. 9 }
the counter i is equal to 10 at the end of the loop ----------> potentially an "out by one" bug(1)

C/99 loop:
for (uint32_t i=0; i<10; i++) { } ;
/* i'range = { 0 .. 9 }
the counter i is ... no more existing after the loop :o :o :o

my c previous first example:
the counter is equal to 10 at the end of the loop ------------> potentially an "out by one" bug(1)

my C auto loop:
loop.i'range = { 0 .. 9 };
during loop { loop.i++; }
/* i'range = { 0 .. 9 }
loop.i = 9 at the end of the loop


Given that context, the C style of having the loop counter within the loop definition seems preferable: it's in one defined place, easily digested and no hidden gotchas buried in the loop somewhere (at least, there shouldn't be).

in C you can go over the counter range and you can be "out of one"; in my-c it is impossible as being strict in-range is guaranteed.

In C you have to think a way to "exit" from an inner loop (goto? break?), in my-c you just need to invoke .is_EOL or .is_done, that's good as it facilitates step-by-step manual debugging and ICE-testcases.



edit:
(1) when the counter is used in some following statement under the belief that it is in-range
(2) you can override its reactive code callback and invoke "panic()" or a "console_out_warning()" to be warned that a counter has gone out of its range -> probably a bug.

I just wish that if the coder is aware/worried of the potential off-by-one, please just put an if statement with the boundaries specified in the code and better yet, comment it so we know what you were thinking/expecting the code to do.

Ok. Off my soap box.  :)
iratus parum formica
 
The following users thanked this post: PlainName, DiTBho

Online PlainName

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: va
Re: Good Ideas, Through the Looking Glass
« Reply #58 on: April 19, 2023, 11:38:43 am »
Why is there 'loopn.i++'?

as much as advanced the "auto loop" is, it still needs "a hamster to spin the wheel" (what? )
and you end up needing "something" that increments the counter  :o :o :o

Surely the loop, ah, looping would step through the desired range. Where you've specified the upper and lower limits, shouldn't you also specify the step?

Quote
Note, i++ is a saturated increment operator(2), which guarantees the counter never goes out of its range

Quite, but you still have to manually move it along, and move it along at a specific place (to prevent problems similar to off-by-one), and can still mess with it going forward or backward or missing sub-ranges, or even using the same value three times before moving on.

Quote
C/99 loop:
for (uint32_t i=0; i<10; i++) { } ;
/* i'range = { 0 .. 9 }
the counter i is ... no more existing after the loop :o :o :o

I don't see the problem with this. You have the option to restrict the loop counter to the loop (sensible IMO) but can opt to make it available outside if you want. It's just another means of specifying scope. If you don't like this then you should also be horrified at defining variables within the loop body, which go out of scope (and disappear) at the end. But isn't this kind of thing why the idea of scope exists, or are we meant to prefer the idea of global variables?
 
The following users thanked this post: DiTBho

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #59 on: April 19, 2023, 11:56:39 am »
the step can be achieved with +=step
            loop.i += step;
and the counter will be still constrained to the upper range boundary.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8754
  • Country: fi
Re: Good Ideas, Through the Looking Glass
« Reply #60 on: April 19, 2023, 12:30:58 pm »
How is setting some variable, purely to exit the loop, better than a simple break? The two do the same thing, but the variable is make work and verbose, there just to not have 'break'.

Yeah. The variable way is how it's taught at school infested by "goto considered harmful" -tier professors, or if the language lacks the control instructions. And it's again more surface area for bugs.

Classic mistake is using a variable to avoid using goto:
Code: [Select]
bool continue = true;
for(int i = 0; continue && i < i_end; i++)
{
   // some code 1
   for(int o=0; continue && o < o_end; o++)
   {
      // some code 2
      if(break_condition)
         continue = false;

      // more code 2
   }
   // more code 1
}

The issue here is that "more code 1" and "more code 2" run after the break_condition. If this is what you want, then fine, you should use the variable, and the variable name would communicate it. But if you want to break, then adding the variable itself and modifying the loop exit condition is not enough, but you need to modify the code more:

Code: [Select]
bool continue = true;
for(int i = 0; continue && i < i_end; i++)
{
   // some code 1
   for(int o=0; continue && o < o_end; o++)
   {
      // some code 2
      if(break_condition)
         continue = false;

      if(continue)
      {
         // more code 2
      }
   }
   if(continue)
   {
      // more code 1
   }
}

Which is getting quite nasty (see Don't Repeat Yourself.)

The purpose of language is to provide things programmers need to make their code more readable, writable and understandable. Status variables and breaks/gotos are not alternatives, they cater to different purposes and are both needed. Besides, that termination condition (continue && i < i_end) easily goes wrong.
« Last Edit: April 19, 2023, 12:34:09 pm by Siwastaja »
 
The following users thanked this post: newbrain, DiTBho

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #61 on: April 19, 2023, 12:33:36 pm »
Quite, but you still have to manually move it along, and move it along at a specific place (to prevent problems similar to off-by-one), and can still mess with it going forward or backward or missing sub-ranges, or even using the same value three times before moving on.

I don't get your point  :-//

but, anyway, you can change the range property when and where you wish, it's not immutable.
Also, inside the loop you can check if the loop is going to end.

          if (loop.is_done isEqualTo True) { ... }

as well as you can check the reason of its ending
- an "error" inside the current loop
- an "error" inside the inner loop (here you need to "bound" monads)
- the counter has reached it's upper boundary
- other reasons (here you need to "bound" monads)

          if (loop.is_err isEqualTo True) { ... }
          if (loop.is_other_causes isEqualTo True) { ... }

is_done is true when one of them is true

I don't see the problem with this.

I see a lot of bugs with this, especially with strings and arrays/matrices  :o

defining variables within the loop body, which go out of scope (and disappear) at the end

indeed "defining variables within the loop body" is banned in my-c as the ICE needs to know the stack size in the worst case, as well as a counter is usually re-cycled and used even *after* the loop.

That means all the variables (including counters) must be declared immediately in the head of the function body (80s C coding style, I know, I know  ;D ) rather than here and there along the algorithm.

The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #62 on: April 19, 2023, 12:44:43 pm »
Classic mistake is using a variable to avoid using goto:

only if you are not good at planning your code  :o :o :o
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online PlainName

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: va
Re: Good Ideas, Through the Looking Glass
« Reply #63 on: April 19, 2023, 04:16:36 pm »
Quite, but you still have to manually move it along, and move it along at a specific place (to prevent problems similar to off-by-one), and can still mess with it going forward or backward or missing sub-ranges, or even using the same value three times before moving on.

I don't get your point  :-//

Code: [Select]
during loop0
    {
        during loop1
        {
            during loop2
            {
                loop1.i++;
                ...
                if (weather == WS_WARM) loop2.i -= 3;
                ...
            }
            loop1.i++;
        }
        loop0.i++;
    }

defining variables within the loop body, which go out of scope (and disappear) at the end

indeed "defining variables within the loop body" is banned in my-c as the ICE needs to know the stack size in the worst case, as well as a counter is usually re-cycled and used even *after* the loop.
[/quote]

Sounds like you are writing the language to suit a specific tool. Which is kind of OK as a tool-specific, er, tool but a bit detrimental for a general purpose language. There is no reason why you can't use the style that scope-locks the counter if that's what you want. There are good reasons not to access the loop counter outside the loop too.
 
The following users thanked this post: DiTBho

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #64 on: April 19, 2023, 05:44:36 pm »
Code: [Select]
                if (weather == WS_WARM) loop2.i -= 3;

inside the loop, each incrementer has saturated logic, guaranteed to always be in-range.
I always spend a lot of time AAL-designing the code to avoid to introduce things like in your example, when possible, and usually it's possible, and when it's not ... I write a dispatcher.



With my-c I have already written
  • a b+tree filesystem, nothing special, proof of concept, but the b+tree module is polymorphic
  • a gauss-full-pvoting-based polymorphic systems of equations, the matrix cells can be complex, real, natural, ...
  • a lib tokenizer, uses safestring, it's used by { my-ucshell, my-c }
  • safestring and its utils, massively replaces "string_t"
  • filename utils for bash-scripting (uses safestring)
  • a micro shell (uses safestring)
  • my-c itself has been rewritten in my-c (--level2, the next gen will be --level3, so ... with auto loops, prologues and epilogues, end more new stuff), the initial code was c-89

I know it requires shocking constraints such as {no goto, no continue, no for(), ... }, but, as those projects have some level of complexity, from having them done with less frustration than their c/89 versions, I also know it can be done with final benefits.


Sounds like you are writing the language to suit a specific tool. Which is kind of OK as a tool-specific, er, tool but a bit detrimental for a general purpose language. There is no reason why you can't use the style that scope-locks the counter if that's what you want. There are good reasons not to access the loop counter outside the loop too.

my-c is a personal and private project without the pretext of having any authority. It's used to design advanced AI-assisted ICEs, which is my second core business, and I only sometime mention the work environment (avionics) in which I operate, where many of the things I report for my "toy compiler" are actually prohibited by the DO178B guideline.

is my-c even "detrimental" for a general purpose language? bah ...  so I'm right not to release it  ;D
That's what I am afraid of: it works for me, it works for my ICE, but will it work for others?!?

                         Mumble

I don't want to wake up in the morning and find a dead horse's head in bed (funny saying(1)) for the arrogance of claiming that, if not only it "de facto" works but also makes less stressing most of the constrains I have to consider in my job, then it's somehow "superior/better" to traditional compilers  :-//



(1) plus, OpenSource is becoming "dangerous" in Europe. a law of the European parliament is being discussed these days which, if approved, will make "single-person projects" very disadvantageous to release opensource because the authors will be held legally responsible for any damage caused by their software.
(brrrrrrrrrr)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online PlainName

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: va
Re: Good Ideas, Through the Looking Glass
« Reply #65 on: April 19, 2023, 07:04:22 pm »
Quote
guaranteed to always be in-range

The point I was trying to make was that 'in-range' does not equate to 'valid'. I tried to show this by having various silly values, all of which could be in-range but are obviously nonsensical.
 
The following users thanked this post: DiTBho

Online PlainName

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: va
Re: Good Ideas, Through the Looking Glass
« Reply #66 on: April 19, 2023, 07:07:48 pm »
Quote
my-c is a personal and private project without the pretext of having any authority

That's fine, and absolutely valid. But I'm not sure of the value of promoting such things in other contexts, which is why I bring up the points I have. For what you want from it, it is surely ideal  :)
 
The following users thanked this post: DiTBho

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8754
  • Country: fi
Re: Good Ideas, Through the Looking Glass
« Reply #67 on: April 20, 2023, 05:40:08 am »
my-c is a personal and private project

You talk about it publicly so much and in such great detail I don't think it's purely personal and private anymore :)
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
Re: Good Ideas, Through the Looking Glass
« Reply #68 on: April 20, 2023, 11:36:54 am »
You talk about it publicly so much and in such great detail I don't think it's purely personal and private anymore :)

well, for pure enthusiasm and because in this forum you are all far away from constrained environment (like DO178B) so, I thought it was "informative" at least, but I was wrong.

Sorry.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8754
  • Country: fi
Re: Good Ideas, Through the Looking Glass
« Reply #69 on: April 20, 2023, 01:27:19 pm »
No need to be sorry. Just expect to see it being treated like any public project in discussions.
 

Online SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 15257
  • Country: fr
Re: Good Ideas, Through the Looking Glass
« Reply #70 on: April 20, 2023, 07:01:17 pm »
Not everyone has the opportunity to get their project backed by Mozilla and then become the absolute best thing since sliced bread. ;D
 

Online SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 15257
  • Country: fr
Re: Good Ideas, Through the Looking Glass
« Reply #71 on: April 20, 2023, 08:12:55 pm »
You talk about it publicly so much and in such great detail I don't think it's purely personal and private anymore :)

well, for pure enthusiasm and because in this forum you are all far away from constrained environment (like DO178B) so, I thought it was "informative" at least, but I was wrong.

Expect to get occasional negative comments in general for anything personal you talk about/show off on forums and social media. That's just what's bound to happen.
Most people tend to be more vocal about their negative thoughts than their positive ones.

That said, in this specific case, probably the point that doesn't "help" is that you are more or less answering very general programming questions with very specific solutions oriented towards your own needs and particular tools, so you can expect people to point it out.
 
The following users thanked this post: DiTBho


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf