CBFalconer wrote:
Pascal is somewhat unique in the way it encourages use of input streams. All input parsing leaves the terminating char in f^, so that the reason for rejection, or the existance of further data in a line, can be detected from that and the eoln condition. [...]
Once you have this sort of input routine, there is very little need for a string parsing mechanism. The problem is largely that C programmers are used to such a technique, and many will be lost without it.
I don't follow your last paragraph. Do you mean that any input data must come from files, or that if you have data in a string, you'd rather want to put it to a (temporary?) file first to parse it?
In the first case, I can only say that this is just not true. There are many other input sources (whether self-written graphical input routines, various communication-protocols and much more) which return the data in the form of strings (i.e., sequences of chars) naturally.
In the second case, I think it's very inefficient, even if you don't have to use actually temporary files, but say in-memory "virtual" files. That's because using a file involves several operations to start with (Rewrite, Write, Reset, Read for a minimum), and because the internal overhead in using files in Pascal is quite high (exactly because of `f^' and `EOLn', among other things). Sure, there may be lower-overhead implementations than GPC's current one, but I'm generally skeptical of using "virtual" files as a means in string processing.
In fact, I do string-processing a lot in my programs, and I'm quite happy to be able to do so, and it's not C-like at all.
I don't know -- perhaps you only know C's string routines (with pointer arithmetic, 0 terminators, hand-made memory allocation and all that dirty stuff). This might explain your aversion, but that's not a property of string handling in general, just of C's particular implementation. Even if you don't like Extended Pascal, you might want to look at its string handling routines (or, if you prefer, at BP's which are mostly the same with slightly different syntax), to see that it can be comfortable and not dangerous (no pointer arithmetics etc.).
So my question is really not whether to convert between strings and numbers, but only how to (most elegantly). Numbers to strings are easy to do with standard functions (such as `Integer2String') because the integer is a value parameter and thus quite flexible, and there are no error conditions (since the result type can be chosen big enough to hold any possible value). Strings to numbers is a little more tricky, since there are error conditions, so the result and the error cannot both be the result.
Therefore I would try to make any such string parser logically equivalent to the use of readx*(f, var), maybe with sreadx*(s, var). There is no need for seof, and seoln(s) can detect the string end.
If anything, then otherwise. Though it may seem unfamiliar to you, a string can store several lines of text. Even standard Pascal doesn't prohibit an "end of line" character value. (It does require reading a char from a `Text' file to yield space at end-of-line, but not so for `file of Char'.)
It may be useful to include a var parameter for the current string index, by which time the function looks much like your proposal above,
Not really. My intention (with the Boolean return value) is, e.g., to be able to use the function in conditionals, and not having to declare an extra variable, when (as most of the time) I just want to convert a string to a number and reject anything invalid. (Corrective action can be nice sometimes, but since it's necessarily heuristic, I often find it better to just reject invalid input and let the user correct things.)
In PascalP I used the rule that extensions should almost always be in the form of standard functions or procedures, so that the only porting effort to purely standard Pascal was the writing of such functions. Thus there were no such things as unsigned integers, instead there was the "uadd(a, b : integer) : integer;" function, which ignored overflow and implemented the usual modulus rules.
I see your point about porting, but apart from that, this idea seems quite uncomfortable to me. When you want to have an "unsigned integer" this way, if I get you right, you'd declare is as a regular `Integer', but you had to remember to always use `uadd', `uread', `uwrite' (or whatever you call them, i.e. special I/O routines that handle unsigned integers) and similar for all the other operations.
IMHO, this doesn't look very nice (not being able to use operators for `+', `-' etc., or `ReadLn'/`WriteLn' with a sequence of values), and it's quite dangerous because the compiler can't tell you when you once forget to use the special routines. In fact it's what assembler programmers have to do (there are no signed and unsigned types in assembler, just signed and unsigned operations).
There's no question that any extension *can* be written in a standard declaration scheme, but is it always a good idea? Isn't this just the C way where any "compiler magic" is frowned upon, and even the dubious varargs declarations were introduced, just so `printf' etc. could be declared in a standard way? IMHO, Pascal (or perhaps any higher-level language) is also about writing things in a more comfortable syntax and to let the compiler/interpreter do many nasty little things for you (such as here remembering whether your variable is signed or unsigned, once declared).
Frank