Replies: 15 comments 4 replies
-
Not a trivial subject.
A Modula3 procedure states the set of possible exceptions that
could be raised, so client code knows what to expect. The
signature of IO.<something> (I can't regenerate the line numbers
for sure--most likely IO.GetLine,since there is only one
warning message) will say RAISES {Error,...}.
However, it is not possible in general statically, whether a
procedure obeys its own RAISES clause or allows unstated
exceptions to propagate out. So if this fails, it is a
runtime error. The warning happens because your Hello2 neither catches
nor claims to raise IO.Error, so if it happened, it would be
a runtime error occurring inside your code. The RT error message
is something like "IO.Error not in RAISES clause" or such.
If you surround the GetLine call by TRY...EXCEPT that names IO.Error
or has an ELSE, that prevents your code from allowing it to propagate
out, and you won't get this warning. A caller of your code could
still catch it.
If the exception propagates all the way out from the main program,
passing through RAISES clauses at every level, that is a different
RT error, called something like "unhandled exception".
You can also use a <*FATAL IO.Error*> pragma before a BEGIN.
That just means I'm not going to catch it, and I'm not naming
it in my RAISES clause either, I just expect that to be a
fatal runtime error, so please don't nag me with a warning
about it.
Unfortunately, the language doesn't provide a way to put a
RAISES clause on the BEGIN..END of a module, where your code
is in this example, and the if I recall, the implementation
won't accept the pragma on it either. I usually put very
little in a module body except a call on a procedure, which
does most of the real work, for this reason, among others.
The IO.Error exception would be raised by something like
the line not being deliverable, due to prematurely closed
file, or something like that. So for little single-use programs,
I usually just let the warnings come out for io-problems and
ignore the warning.
For multi-user strength programs, I will either handle it or
put in <*FATAL*> pragmas, if I expect it to go unhandled.
If your code were inside a procedure, you could put a
RAISES {IO.Error} in your procedure, which would allow the
exception to propagate on out. It it got
…On 12/29/21 4:04 PM, Duke Normandin wrote:
|--- building in AMD64_LINUX --- new source -> compiling hello2.m3 "../hello2.m3", line 10: warning: potentially unhandled exception: IO.Error 1 warning encountered **** PARALLEL BACK-END BUILD, M3_PARALLEL_BACK = 20 -> linking hello2 |
|MODULE hello2 EXPORTS Main; IMPORT IO; VAR name: TEXT; BEGIN IO.Put("Gimme your name: "); name := IO.GetLine(); IO.Put("Your name was entered as: " & name & "\n"); END hello2. |
What is it warning me about? That I should use try/catch?
—
Reply to this email directly, view it on GitHub <#791>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABSVZNBF2INZMJECHZIPUDTUTOAVVANCNFSM5K6VDRZQ>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Back again! CM3's error catching is a bit complicated for a noob. :)
Don't know exactly where the "RAISES" statement goes. |
Beta Was this translation helpful? Give feedback.
-
Since you now catch the exception if/when it comes out of IO.GetLine,
it won't further propagate out of your code, so neither a RAISES
nor the FATAL are relevant.
Aside from that, even if you needed/wanted to, RAISES goes
only on a PROCEDURE, and your code is not in one. The language
does not provide any way to put RAISES on the body of a module.
Just speculating here, but I imagine the language designers
thought there was no need, because a module body is outermost,
and there can be no code outside of it that could catch or care
about any exceptions coming out of it.
I was unaware that a FATAL pragma could be located where you
did, so that's new to me. But it apparently applies to the
module body, so is really irrelevant for the same reason and
just produces an unnecessary warning.
On a different note, there is a potential problem here. If
IO.GetLine were to raise OS.Error, this would happen before
the assignment to 'name' and execution would go to the do-nothing
location. Then on to the second IO.Put, beyond the TRY-EXCEPT block.
There, the attempt to concatenate 'name' would fail, because 'name'
would be NIL, and & (which means Text.Cat) tries to dereference
its operands. So the second IO.Put should go before EXCEPT, where
it would be skipped, if the exception were raised.
…On 12/30/21 12:44 PM, Duke Normandin wrote:
Back again! CM3's error catching is a bit complicated for a noob. :)
|cm3 -build <1> --- building in AMD64_LINUX --- new source -> compiling hello2.m3 "../hello2.m3", line 4: warning: exception is never raised: IO.Error 1 warning encountered **** PARALLEL BACK-END BUILD, M3_PARALLEL_BACK = 20 new "hello2_m.o" -> linking hello2 |
|MODULE hello2 EXPORTS Main; IMPORT IO;<* FATAL IO.Error *> VAR name: TEXT; BEGIN TRY IO.Put("Gimme your name: "); name := IO.GetLine(); EXCEPT IO.Error => (*do nothing*) END; IO.Put("Your name was entered as: " & name & "\n"); END hello2. (* HELP - where do I put RAISES {IO.Error} *) |
—
Reply to this email directly, view it on GitHub <#791 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABSVZNENIUE6KWPDCHJXE6DUTSR7PANCNFSM5K6VDRZQ>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
On Fri, 31 Dec 2021 09:32:57 -0800 "Rodney M. Bates" ***@***.***> wrote:
Since you now catch the exception if/when it comes out of
IO.GetLine, it won't further propagate out of your code, so
neither a RAISES nor the FATAL are relevant.
Aside from that, even if you needed/wanted to, RAISES goes
only on a PROCEDURE, and your code is not in one. The language
does not provide any way to put RAISES on the body of a module.
Just speculating here, but I imagine the language designers
thought there was no need, because a module body is outermost,
and there can be no code outside of it that could catch or care
about any exceptions coming out of it.
Thanks for your comments Rodney!
I'm trying to solve the initial compiler warning that I received
concerning a potential error condition. I used TRY/EXCEPT to do
that, but then it squawks that RAISE is never called or some such.
So how do I check for valid input in M3? I can do a loop to keep on
asking for input, but what about checking the input itself? Is that
what the compiler yelled about initially?
--
Duke
** Text only please. Bottom post is best for me **
|
Beta Was this translation helpful? Give feedback.
-
On 12/31/21 11:55 AM, Duke Normandin wrote:
On Fri, 31 Dec 2021 09:32:57 -0800
"Rodney M. Bates" ***@***.***> wrote:
> Since you now catch the exception if/when it comes out of
> IO.GetLine, it won't further propagate out of your code, so
> neither a RAISES nor the FATAL are relevant.
>
> Aside from that, even if you needed/wanted to, RAISES goes
> only on a PROCEDURE, and your code is not in one. The language
> does not provide any way to put RAISES on the body of a module.
> Just speculating here, but I imagine the language designers
> thought there was no need, because a module body is outermost,
> and there can be no code outside of it that could catch or care
> about any exceptions coming out of it.
Thanks for your comments Rodney!
I'm trying to solve the initial compiler warning that I received
concerning a potential error condition. I used TRY/EXCEPT to do
that, but then it squawks that RAISE is never called or some such.
So how do I check for valid input in M3? I can do a loop to keep on
asking for input, but what about checking the input itself? Is that
what the compiler yelled about initially?
--
Either a <*FATAL IO.Error*> or a RAISES {IO.Error} (No need for both)
are about what should happen if IO.Error propagates *out* of your code.
In the first version, without TRY-EXCEPT, this could happen if the
exception were to fly *in* to your code, out of IO.GetLine when you call it.
That's the only way, since you have not RAISE statement nor do you
call anything else that could raise IO.Error.
Now that you are catching it with a TRY-EXCEPT surrounding the call on
IO.GetLine, it will not propagate on out of your code, so you don't need
either a RAISES nor a FATAL. Now the compiler is warning you because
you are telling it, with the FATAL, what to do about something that it
can determine can't happen. A RAISES would give you a similar warning,
if there were a place to put the RAISES.
It's picky. If the exception could possibly come out of your code,
it will warn unless you tell it, with either a RAISES or FATAL, what
to do about that. On the other hand, if the compiler can ascertain
that the exception can't propagate *out* of your code, as is the case
now, with the TRY-EXCEPT, then it will warn over that. To avoid warnings,
you have to get it right either way, but you can always do that, knowing
only what is in your code itself and the RAISES clauses of any procedure
you call.
So in the current version, just remove the FATAL pragma.
As for checking, I presume you mean determining whether IO.GetLine
worked at all. If it fails, it will raise the exception. If it
didn't, execution will continue after the call, then skip over from
EXCEPT to the matching END. If you want to do something about the
failure, put it where you say "do nothing", say a message like
"Sorry, I couldn't get a name." Trying again in a loop will probably
keep on failing, in this case, so I just terminate the program then.
If IO.GetLine doesn't raise it, I think you can be pretty sure that
you got a character string into variable 'name'. But it could be
empty: "".
… Duke
** Text only please. Bottom post is best for me **
—
Reply to this email directly, view it on GitHub <#791 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABSVZNEN4XSAKYSYEYSK5QDUTXVCJANCNFSM5K6VDRZQ>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
On Fri, 31 Dec 2021 12:33:17 -0800 "Rodney M. Bates" ***@***.***> wrote:
[snip]
If IO.GetLine doesn't raise it, I think you can be pretty sure
that you got a character string into variable 'name'. But it
could be empty: "".
I got it to compile cleanly by removing all error-catching stuff
except for:
TRY
...
EXCEPT
....
END
Doesn't seem to work worth a "zxyk" the way I've got it coded. I
entered an integer for a name and it didn't raise an exception.
I have to admit that this compiler is very fast. I like it, but the
language docs are very sketchy and not for a beginner with the
language. Too bad because I bet a whack of Oberon/Oberon2/Modula2
folks would jump on this compiler if the learning resources were
more polished. As it is, it's too complicated to figure out.
I'll keep on going with it, but ...
Thanks for all your input!
--
Duke
** Text only please. Bottom post is best for me **
|
Beta Was this translation helpful? Give feedback.
-
On 12/31/21 3:46 PM, Duke Normandin wrote:
On Fri, 31 Dec 2021 12:33:17 -0800
"Rodney M. Bates" ***@***.***> wrote:
[snip]
> If IO.GetLine doesn't raise it, I think you can be pretty sure
> that you got a character string into variable 'name'. But it
> could be empty: "".
I got it to compile cleanly by removing all error-catching stuff
except for:
TRY
...
EXCEPT
....
END
Doesn't seem to work worth a "zxyk" the way I've got it coded. I
entered an integer for a name and it didn't raise an exception.
GetLine's function is to get a string of characters. An integer
is such a string. It doesn't analyze what the characters are.
You should expect an exception only if it can't do its job, e.g.,
maybe the input file got closed, and thus no characters at all
were available. From IO.i3:
PROCEDURE GetLine(rd: Rd.T := NIL): TEXT RAISES {Error};
(* Read a line of text from "rd" and return it. *)
(* A line of text is either zero or more characters terminated by a
line break, or one or more characters terminated by an end-of-file.
In the former case, "GetLine" consumes the line break but does not
include it in the returned value. A line break is either {\tt
\char'42\char'134n\char'42} or {\tt
\char'42\char'134r\char'134n\char'42}. *)
The only analysis of the characters GetLine does is to look for a
line-terminating sequence.
In contrast, IO.GetInt scans for an integer, and applies some rules
for what characters that could be, raising the Error if the input
doesn't match those rules. But you would have to assign it to an
INTEGER variable, not a TEXT.
There is no IO.GetName. How would you define general-purpose rules
for what character strings constitute syntactically valid names?
…
I have to admit that this compiler is very fast. I like it, but the
language docs are very sketchy and not for a beginner with the
language. Too bad because I bet a whack of Oberon/Oberon2/Modula2
folks would jump on this compiler if the learning resources were
more polished. As it is, it's too complicated to figure out.
I'll keep on going with it, but ...
Thanks for all your input!
--
Duke
** Text only please. Bottom post is best for me **
—
Reply to this email directly, view it on GitHub <#791 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABSVZNBEYAWF7N6M5VRANIDUTYQBZANCNFSM5K6VDRZQ>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
On Sat, 01 Jan 2022 10:05:41 -0800 "Rodney M. Bates" ***@***.***> wrote:
[SNIP]
The only analysis of the characters GetLine does is to look for a
line-terminating sequence.
Thx - but if that's all GetLine will squawk about, then why did the
compiler issue that warning about potential problems with GetLine.
Sure TRY/EXCEPT silenced the warning, but why bother if all it does
is check for a newline!
--
Duke
** Text only please. Bottom post is best for me **
|
Beta Was this translation helpful? Give feedback.
-
On 1/1/22 12:19 PM, Duke Normandin wrote:
On Sat, 01 Jan 2022 10:05:41 -0800
"Rodney M. Bates" ***@***.***> wrote:
[SNIP]
> The only analysis of the characters GetLine does is to look for a
> line-terminating sequence.
Thx - but if that's all GetLine will squawk about, then why did the
compiler issue that warning about potential problems with GetLine.
Sure TRY/EXCEPT silenced the warning, but why bother if all it does
is check for a newline!
Because the signature of GetLine says RAISES {Error}. The coder of
the procedure has to provide this information and give it in the
RAISES clause.
It would be unfeasibly complicated to define a language that analyzes
the code in the body of a procedure to see what, if any exceptions it
could raise, or under what conditions. Moreover, in general, what
exceptions might be raised has to be denoted in the INTERFACE, where
the body isn't available.
… --
Duke
** Text only please. Bottom post is best for me **
—
Reply to this email directly, view it on GitHub <#791 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABSVZNHUJAN4L6CLHAHDBGDUT5ARPANCNFSM5K6VDRZQ>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Keep in mind that the The intent behind the exception specification here is that you don't forget to deal with it when it matters, and there are easy ways to squelch it when it doesn't. For toy programs, I usually put Anyway, Another pattern is to read the raw input with It would be nice to have a regular expression library but, well, that's on my to-do list. |
Beta Was this translation helpful? Give feedback.
-
On Sat, 01 Jan 2022 13:20:56 -0800 Eric Sessoms ***@***.***> wrote:
Keep in mind that the `Error` in `GetLine` is less about a
missing terminator than an "unexpected end-of-file" (as
documented). It's annoying to deal with in small console
programs where the end-of-file is usually deliberate, but this
module is also used to interact with files, pipes, and sockets
where such exceptions are more of a problem.
I see!
... I usually
put `<*FATAL ANY*>` somewhere in the module declaration section
and have done with it.
Anyway, `IO` is really *just* about input and output. The
standard modules tend to be very specific "do one thing well" and
all that.
That's all I want to learn to do well to begin with!
For higher-level verification you probably want to
look at `Scan` or `Lex` (see
http://modula3.github.io/cm3/help/interfaces.html#format ). A
common pattern is to read the raw input with `GetLine` and then
convert it with `Scan`.
Got it! Thx for the reference. I wouldn't have known to look there.
Another pattern is to read the raw input with `GetLine`,
construct a "reader" with `TextRd.New` (see
http://modula3.github.io/cm3/help/interfaces.html#io ), and then
inspect it with `Lex`.
Another advanced option. Thx
…--
Duke
** Text only please. Bottom post is best for me **
|
Beta Was this translation helpful? Give feedback.
-
Ah for an intro text, get Harbison's book. It's not as good as the Green
Book but it is more of a tutorial.
The exception stuff is really extremely similar to Java. Not identical,
exceptions aren't objects, but at least syntactically similar.
For simple line-based parsers I always used Rd.GetLine
I have a small example attached. It parses mazes in the format
4
5
_ s _ _ _
x x x x _
_ x x x _
_ _ g _ _
s is start, x is obstacle, g is goal
input parser starts on line 58. Added m3makefile so you should be able to
run it too.
Admittedly it does generate some compiler warnings but for a quick example
it's good enough.
Mika
On Fri, Dec 31, 2021 at 1:46 PM Duke Normandin ***@***.***>
wrote:
… On Fri, 31 Dec 2021 12:33:17 -0800
"Rodney M. Bates" ***@***.***> wrote:
[snip]
> If IO.GetLine doesn't raise it, I think you can be pretty sure
> that you got a character string into variable 'name'. But it
> could be empty: "".
I got it to compile cleanly by removing all error-catching stuff
except for:
TRY
...
EXCEPT
....
END
Doesn't seem to work worth a "zxyk" the way I've got it coded. I
entered an integer for a name and it didn't raise an exception.
I have to admit that this compiler is very fast. I like it, but the
language docs are very sketchy and not for a beginner with the
language. Too bad because I bet a whack of Oberon/Oberon2/Modula2
folks would jump on this compiler if the learning resources were
more polished. As it is, it's too complicated to figure out.
I'll keep on going with it, but ...
Thanks for all your input!
--
Duke
** Text only please. Bottom post is best for me **
—
Reply to this email directly, view it on GitHub
<#791 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABKYNJPKZ2YCDCBS6JFPIZLUTYQB3ANCNFSM5K6VDRZQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
For simple parsing (say space-delimited, comma-delimited or whatnot) you
can use the following
https://github.com/modula3/cm3/blob/master/caltech-parser/cit_common/src/TextReader.i3
we wrote it because we wanted something to solve simple problems in a
flexible way.
For more complicated stuff we have a OO parser generator library, it's in
the tree as "parserlib". I have tons of examples of both these in action
if anyone is interested.
https://github.com/modula3/cm3/tree/master/caltech-parser
When you build CM3, the latter generates a bunch of HTML documentation on
how to use it.
Mika
On Sat, Jan 1, 2022 at 1:57 PM Duke Normandin ***@***.***>
wrote:
… On Sat, 01 Jan 2022 13:20:56 -0800
Eric Sessoms ***@***.***> wrote:
> Keep in mind that the `Error` in `GetLine` is less about a
> missing terminator than an "unexpected end-of-file" (as
> documented). It's annoying to deal with in small console
> programs where the end-of-file is usually deliberate, but this
> module is also used to interact with files, pipes, and sockets
> where such exceptions are more of a problem.
I see!
> ... I usually
> put `<*FATAL ANY*>` somewhere in the module declaration section
> and have done with it.
> Anyway, `IO` is really *just* about input and output. The
> standard modules tend to be very specific "do one thing well" and
> all that.
That's all I want to learn to do well to begin with!
> For higher-level verification you probably want to
> look at `Scan` or `Lex` (see
> http://modula3.github.io/cm3/help/interfaces.html#format ). A
> common pattern is to read the raw input with `GetLine` and then
> convert it with `Scan`.
Got it! Thx for the reference. I wouldn't have known to look there.
> Another pattern is to read the raw input with `GetLine`,
> construct a "reader" with `TextRd.New` (see
> http://modula3.github.io/cm3/help/interfaces.html#io ), and then
> inspect it with `Lex`.
Another advanced option. Thx
--
Duke
** Text only please. Bottom post is best for me **
—
Reply to this email directly, view it on GitHub
<#791 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABKYNJITQ6F6ZLNFGPB7J4DUT52C5ANCNFSM5K6VDRZQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
My literature list again, sorry: Much of spwm3 (the Green Book) is available online. Language spec obviously is. The threads chapter https://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-35.pdf Trestle https://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-69.pdf Network Objects https://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-115.pdf I/O Streams https://hplabs.itcs.hp.com/techreports/Compaq-DEC/SRC-RR-53.pdf probably others I missed (HP's web site interface is terrible...) Then there are a bunch of related papers, not strictly Modula-3 but closely related: https://hplabs.itcs.hp.com/techreports/Compaq-DEC/SRC-RR-64.pdf
interesting rationale here https://hplabs.itcs.hp.com/techreports/Compaq-DEC/SRC-RR-3.pdf and there are some interesting papers on Obliq and Juno, and the Extended Static Checker. I'm sure others I have forgotten. |
Beta Was this translation helpful? Give feedback.
-
On Sun, 02 Jan 2022 01:12:23 -0800 Mika Nyström ***@***.***> wrote:
Ah for an intro text, get Harbison's book. It's not as good as
the Green Book but it is more of a tutorial.
That's what I need to get if I'm to pursue this learning project.
Thanks for all the links to the advanced M3 topics.
I'll be studying your code when I get the very basics down pat. Thx!
--
Duke
** Text only please. Bottom post is best for me **
|
Beta Was this translation helpful? Give feedback.
-
What is it warning me about? That I should use try/catch?
Beta Was this translation helpful? Give feedback.
All reactions