From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,5afe598156615c8b X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!t-online.de!tiscali!newsfeed1.ip.tiscali.net!proxad.net!proxad.net!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Get_Line problem (GNAT bug?) Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <1c1gbc5u9cpvp.1wj1zhhn7q86j$.dlg@40tude.net> <1tua3ke1kfoog.1wqou5d9mwtly.dlg@40tude.net> Date: Thu, 7 Dec 2006 17:29:27 +0100 Message-ID: <121egf5isyr6y$.1xabuj3pbre7l$.dlg@40tude.net> NNTP-Posting-Date: 07 Dec 2006 17:29:27 CET NNTP-Posting-Host: a06c7de4.newsspool4.arcor-online.net X-Trace: DXC=1kJ>cKO0AoheoCI^f\Y]Ea4IUK On Thu, 07 Dec 2006 15:51:50 +0100, Maciej Sobczak wrote: > Dmitry A. Kazakov wrote: > >>>> When End_Of_File meets a CR (Ctrl-M) it cannot know if this CR manifests >>>> the end of the current line or both the line end and the file end. >>> I understand. But then I consider the specs to be broken, see below. :-) >> >> No. It is the concept, which is broken. And that wasn't Ada, who broke it, >> but crippled operating systems like Windows and Unix. In a proper OS the >> line terminator is not a character. > > That's a brave concept. ;-) > Why do you assign the special meaning to the line terminator? Because a line can contain any character. Purely mathematically referential recursion is known to be flawed beyond repair. "All Cretans are liars." > Is it > *that* special in, for example, your previous post? Why not assign the > special meaning to word or sentence terminator? Or anything else for > that matter. Isn't it domain-specific? Do you want support from "proper > OS" for all this stuff? Yes. A properly designed OS would have a container object to represent formatted things. >>>> 1. Never ever use End_Of_File with text files; >>> This is broken. For me, End_Of_File is a concept that is completely >>> orthogonal to what the file contains and how it is interpreted. >> >> Right, so see above. You need a file system which has EOF state >> determinable without look ahead. > > No. I might be using pipes or fifos or sockets or whatever else where > EOF is not really determinable by position. It's not file system issue. But OS doesn't need pipes, sockets as well as files. It needs objects with clearly defined behavior. If the behavior is defined to support iteration and string items, that's called a container of strings. >> [Though I don't defend End_Of_File. I would simply remove it from Text_IO.] > > But then it would be somewhere else. There would be an opportunity to > specify it correctly, without messing with interpretation of the file > structure. Yes, it should be a container. >>>> 2. If you yet use End_Of_File then do it for *each* character of the file; >>> I don't see how it might solve this problem - End_Of_File would block >>> after first anyway. >> >> Yes, but then at least you would know what's going on. End_Of_File happened >> to be lower level (in OSI hierarchy terms) than Get_Line. > > This is exactly what I would expect. End_Of_File should not mess with > file structure. But the package is called Text_IO. Texts have a structure. So the problem. >> My answer is no. Exception is not an error. It indicates an exceptional >> state. Note that an exceptional state is a *valid* state. While an error >> (bug) has no corresponding program state at all. > > It's not about bugs. I have presented an example of truncated XML file - > there's no bug in a program that happened to be given a broken file to > digest. It's an error in a sense that the program cannot read the data > that it genuinely expects. Still, the program should handle this case > reasonably, so we have valid state. It is an error in a file, it is not an error in the program. Consider a defect HDD. Were an exception appropriate here? > Now, if the program specs says: "read the lines from input until EOF", > then this for me immediately translates into a loop with some exit > condition. A while loop, probably, or something in this area. "Read > until" - you have a regular end-of-sequence condition here. Close to > iterators. How do you write iteration routines? Do you use exceptions > for the end-of-sequence condition to break the loop? In what way > iteration over the container is different from reading lines from input? > > (Probably the best thing would be to just have "line iterators".) See below. > Sorry, I'm not convinced that exception might be a correct design choice > for breaking the loop that reads data from well formatted file. Not only that. I am using exceptions for parsing sources. It fits very nicely for recursive descent parsing, makes things a lot cleaner and easier. >> This is because you consider it from the C++ stand point. > > Which is, of course, evil by definition. ;-) > >> In Ada exceptions >> are efficient. > > So how do you write iteration routines? If you mean the case when the number of iterations is statically indeterminable, then yes, using exceptions. Especially when iteration is mixed with recursion. >> They are highly recommended for use in place of return >> codes. > > Good point. There is no return code here. Everything is managed at the > same level. The red-light here is that with exceptions I would need to > use empty "where" clause. Empty clause at the same level? Umm, I didn't understand it, but the skeleton code looks like: Protocol_Error : exception; begin loop Line := Get_Line (Source); -- do something. This may raise an exception as well end loop; exception when End_Error => -- done due to file end when Data_Error => -- due to I/O error when Protocol_Error => -- due to protocol error ... end; > Looks like goto in disguise. Any execution flow control is. So exceptions are as well. >> End_Of_File in your program serves the >> purpose of return code. > > Nope. It's the end-of-sequence condition. Just like with iterators. But Get_Line already has a result, which is a string. String is not a condition. >> What is even worse, from the software design >> perspective, is that one operation "give me next line" is split into two, >> so that the side effect of one determines the outcome of another and >> reverse. > > Same with iterators. That's a different idiom. Iterators assume an indexed container. You could use iterators for dealing with a container of strings. But a stream isn't one. It is again about mixing abstraction levels. You can convert a character stream into a sequence of strings, but the stream itself is a container of characters, not lines. While a text file is a third thing. >> And what for? To defend a myth, that each >> loop should have only one exit? > > If the specs says "read until end", then this means single exit > condition to me. No. This is mixing problem and solution spaces. What if I had a concurrent program, which would map the file into virtual memory. Then I could split that memory into 10 pieces and let 10 tasks "read it until end." >> Your code didn't managed that either! > > Why? Because it contained a hidden goto: "exit when!" (:-)) >> Neither manages it inputs longer than 99 characters. > > Good point. How should I solve this? By making the main loop dealing with lines instead of reads. This is another reason, why it is not a clean iteration idiom. >> Further, even in C you wouldn't use it either. > > You're right, I wouldn't. Why would I use C if C++ gets it right? ;-) > > string line; > while (getline(cin, line)) > { > // play with line here > } That's OK to me. However, it is not that clean. line outlives the loop. But it is not equivalent to your Ada code, because you chose fixed-length strings. An Ada equivalent of your C++ example would use Unbounded_String. Then what happens upon read error, reading the system paging file? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de