Skip to content

While loop statements & invariant #153

@palainp

Description

@palainp

Dear @davidgiven, thank you for developing that language, that's very enjoyable and interesting!
Reading some code in, e.g. strings.coh, I noticed that you often use "loop+break" idioms, and rarely rely on "while loop invariants", for example:

sub StrLen(s: [uint8]): (size: intptr) is
       var p := s;
       loop
                var c := [p];
                if c == 0 then
                        break;
                end if;
                p := p + 1;
        end loop;
        size := p - s;
        end loop;
end sub;

could also be written as:

sub StrLen(s: [uint8]): (size: intptr) is
	var p := s;
        # invariant: forall x in [s..p[: [x] != 0
	while [p] != 0 loop
                # here we know that [s..p[ != 0 (invariant) and [p] != 0 (loop condition)
                # so it's safe to increase p and consider [s..p[ != 0 (invariant is restored)
		p := @next p;
	end loop;
	size := p - s;
end sub;

Maybe the underlying assembly is easier to generate with breaks?

Another thought is that some loop condition can be really terrible as with StrICmp (not sure about syntax errors, I'm just starting to learn the language):

sub StrICmp(s1: [uint8], s2: [uint8]): (res: int8) is
	while ((ToLower([s1]) - ToLower([s2])) == 0) and ([s1] != 0) loop
		s1 := @next s1;
		s2 := @next s2;
	end loop;
        # if [s1] = 0 we reached the end of the strings (second condition),
        # otherwise the strings are different (first condition)
	res := [s1] as int8;
end sub;

EDIT: the last res value is wrong here as s1 can be shorter than s2. Therefore another computation is needed and this is avoided with the "break template". Maybe that's a fair enough reason to keep breaks :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions