Live data from Hacker News

EOF is not a character

ruslanspivak.com

11–20 of 136 posts

Re: EOF is not a character

#11

Earlier quoted context omitted.

What does "Procedural" vs "Functional" have to do with this? It's a choice in data type. If by procedural you mean, nonsense, then sure... I agree that a function named `getchar` returning an `int` is procedural. :P

> If by procedural you mean, nonsense, then sure Why are you being snarky? They clearly mean the issue of modelling partial functions which would normally be done by a side-effect in a procedural language but can’t in a functional language.

No, they imply that the handling is done by returning a negative number.

I'm being snarky, as is my nature, to highlight the madness of a function called `getchar` returning anything but a `char`.

Re: EOF is not a character

#12
post #5

Seems like the confusion arises because getchar() (or its equivalent in langauges other than c) can produce an out-of-band result, EOF, which is not a character. Procedural programmers don't generally have a problem with this -- getchar() returns an int, after all, so of course it can return non-characters, and did you know that IEEE-754 floating point can represent a "negative zero" that you can use for an error cod…

I taught myself C on MS-DOS in middle school, decades ago. Could have sworn that ASCII 26 was named “EOF” even if modern text files don’t include it.

This is a supplementary source of confusion.

Re: EOF is not a character

#13

So what is CP/M-style character 26? Isn’t that documented as end-of-file?

Perhaps a marginally better title would be "EOF is not a character [on Unix]". There are some OS that have an explicit EOF character, but it seems to have been the less common approach historically. CP/M featured an explicit end of file marker because the file system didn't bother to handle the problem of files which were not block-aligned, so the application layer needed to detect where the actual end of the file was located (lest it read the contents of the rest of the block). This is a pretty unusual thing to do, and was definitely a hassle for developers, so CP/M descendants like MS-DOS fixed it.

Re: EOF is not a character

#14
post #2

Recently (though mine was the only comment): https://news.ycombinator.com/item?id=22461647

Well then try explaining ctrl+c vs ctrl+d to someone who's never touched a terminal at all. Starts off so easily... "see one tells the program to stop" the other, well, if you're in a shell... or some programs... oh god. IDK anymore, just assume it works. What was the question?"

Maybe you can correct me if I'm wrong, but I've always considered Ctrl+C and Ctrl+D to be signals that you can send a process rather than explicit characters. You might also get some stdout for those key combinations because ???, but they should be thought of as signals rather than as characters you're sending via stdin.

Hoping Cunningham's Law comes into play with this comment. :)

Re: EOF is not a character

#15
post #5

Seems like the confusion arises because getchar() (or its equivalent in langauges other than c) can produce an out-of-band result, EOF, which is not a character. Procedural programmers don't generally have a problem with this -- getchar() returns an int, after all, so of course it can return non-characters, and did you know that IEEE-754 floating point can represent a "negative zero" that you can use for an error cod…

I taught myself C on MS-DOS in middle school, decades ago. Could have sworn that ASCII 26 was named “EOF” even if modern text files don’t include it. This is a supplementary source of confusion.

Yea, it's confusing. https://news.ycombinator.com/item?id=22572703, read EDIT 3, I found this pretty illuminating.

Re: EOF is not a character

#16
CP/M and DOS use ^Z (0x1A) as an EOF indicator. More modern operating systems use the file length (if available). Unix/Linux will treat ^D (0x04) as EOF within a stream, but only if the source is "cooked" and not "raw". (^D is ASCII "End Of Transmission or EOT" so that seems appropriate, except in the world of unicode.)

Re: EOF is not a character

#17
post #2

Recently (though mine was the only comment): https://news.ycombinator.com/item?id=22461647

Well then try explaining ctrl+c vs ctrl+d to someone who's never touched a terminal at all. Starts off so easily... "see one tells the program to stop" the other, well, if you're in a shell... or some programs... oh god. IDK anymore, just assume it works. What was the question?"

This actually doesn't seem that hard. In both, you are telling the computer, not the target program, something. One is to signal the running program you want to interrupt it. The other is to close the input to the program, as you are done giving it data.

Re: EOF is not a character

#18

Earlier quoted context omitted.

Well then try explaining ctrl+c vs ctrl+d to someone who's never touched a terminal at all. Starts off so easily... "see one tells the program to stop" the other, well, if you're in a shell... or some programs... oh god. IDK anymore, just assume it works. What was the question?"

Maybe you can correct me if I'm wrong, but I've always considered Ctrl+C and Ctrl+D to be signals that you can send a process rather than explicit characters. You might also get some stdout for those key combinations because ???, but they should be thought of as signals rather than as characters you're sending via stdin. Hoping Cunningham's Law comes into play with this comment. :)

Control-C is part of POSIX job control. If a stream (or "cooked" tty) sends a control-C (ASCII End-Of-Text or ETX), the foreground process will be sent a SIGINT signal. If that signal is not handled, the default action is to terminate the process (SIGTERM). Control-D is just another control character and not part of POSIX job control, but in the "cooked" case above, it will be interpreted as EOF and the process doing the "read" will receive that.

Re: EOF is not a character

#19
Like NULL, confusion over EOF is a problem which can be eliminated via algebraic types.

What if instead of a char, getchar() returned an Option? Then you can pattern match, something like this Rust/C mashup:

   match getchar() {
     Some(c) => putchar(c),
     None => break,
   }
Magical sentinels crammed into return values — like EOF returned by getchar() or -1 returned by ftell() or NULL returned by malloc() — are one of C's drawbacks.
Post reply on HN