<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>"saving indentation"<br><br><br>So..let me try this yet one more time.<br>Modula-3 has some interesting and almost unique characteristics.<br>Optional safety and compiling to native code is fairly unique.<br><br><br>The syntax in general is limited. I have great difficulty getting comfortable with it.<br>I end up writing much less readable code.<br><br><br>I would really really like "to get easy cases out of the way early"<br>and "straightline" the code mostly -- I don't want to indent like crazy<br>and read through if after if after if.<br><br><br>Similarly, I want to initialize variables when I declare them, but not<br>indent like crazy.<br><br><br>Horizontal space is valuable.<br>Not leaving variables uninitialized is valuable.<br>Avoiding horrendous if/if/if/else if/else if/else "ladders" is often valuable.<br>It is hard to have all of these in Modula-3, but easy in C++ and C9x.<br><br><br><br>Here I have a string that I am checking if it <br>starts with one of two prefixes and followed by an integer.<br><br><br>I would LIKE to write it like so:<br><br><br> var-or-const name := M3ID.ToText(proc.name);<br> var-or-const length := Text.Length(name);<br> FOR i := FIRST(u.handler_name_prefixes) TO LAST(u.handler_name_prefixes) DO<br> var-or-const prefix := u.handler_name_prefixes[i];<br> var-or-const prefix_length := Text.Length(prefix);<br> IF length <= prefix_length OR NOT TextUtils.StartsWith(name, prefix) THEN<br> continue;<br> END;<br> var-or-const end = Text.Sub(name, prefix_length);<br> FOR i := 0 TO Text.Length(end) - 1 DO<br> IF NOT Text.GetChar(end, i) IN ASCII.Digits THEN<br> RETURN FALSE;<br> END;<br> END;<br> RETURN TRUE;<br>
END;<br> RETURN FALSE;<br>
<br><br>but Modula-3 doesn't have "continue", right, and var/with imply indentation,<br>So I have to write:<br> WITH name = M3ID.ToText(proc.name),<br> length = Text.Length(name) DO<br> FOR i := FIRST(u.handler_name_prefixes) TO LAST(u.handler_name_prefixes) DO<br> WITH prefix = u.handler_name_prefixes[i],<br> prefix_length = Text.Length(prefix) DO<br> IF length > prefix_length AND TextUtils.StartsWith(name, prefix) THEN<br> WITH end = Text.Sub(name, prefix_length) DO<br> FOR i := 0 TO Text.Length(end) - 1 DO<br> IF NOT Text.GetChar(end, i) IN ASCII.Digits THEN<br> RETURN FALSE;<br> END;<br> END;<br> RETURN TRUE;<br> END;<br> END;<br> END;<br> END;<br> END;<br> RETURN FALSE;<br>
<br><br>Isn't the first much more readable?<br><br>Is there anything to do about this?<br><br>Am I crazy? Introducing variables "anywhere", without a need to open a block,<br>is considered one of the most conservative features of C++.<br>It is in C9x.<br>The downside of it is that you can't as easily look at the top of a function<br>and guestimate how much stack it uses.<br><br><br>Furthermore, I want "const" to mean "relatively const" -- do whatever<br>codegen is needed to initialize it, but then don't let me change thereafter.<br>Not "the compiler can evaluate it at compile time".<br><br><br>It is useful, it reveals code to be "psuedo functional".<br>The more of this const there is, the easier it is for the compiler and human to reason about.<br>I guess this is what WITH is for though.<br>I guess I should try putting those at the start of functions instead of var.<br><br><br><br><br> - Jay </div></body>
</html>