Question: Was the book from the screenshots composed in Japanese, or composed in English and then translated into Japanese?
Since it's apparently from Fujitsu, I could see it being the former, but if so, I'm impressed with the quality of the English in the printf statements and code comments from non-native English speakers.
I wrote up the iterator-driven for back in 2011, because it was one of those things that had been long-since forgotten about; along with what it would look like were it to be incorporated into the (then) C++ standard.
I am fortunate enough to own a copy of the High C/C++ Language Reference in English. (-:
* http://jdebp.uk./FGA/metaware-iterator-driven-for.html
* http://jdebp.uk./Proposals/metaware-iterator-driven-for.html
Do you know how the break/return would get compiled down to? Would the yield function need to be transformed to return a status code and checked at the callsite?
It's a non-local goto, also a MetaWare language extension, out of the anonymous nested function that the for statement body becomes to (effectively) an anonymous label right after the for statement.
Another part of the High C/C++ Language Reference describes non-local labels and jumps to them. It doesn't go into great detail, but it does talk about stack unwinding, so expect something similar to how High C/C++ implemented throwing exceptions.
Previous submission with comments https://news.ycombinator.com/item?id=38938402
It has no doubt come up again here because Joe Groff just drew attention to it today on the FediVerse.
Seems that the author of the piece reposted the same contents at a different URL yesterday. Odd.
Because cohost is shutting down https://news.ycombinator.com/item?id=41492807
For anyone wondering why the string literals in the pictured examples end with ¥n rather than \n, it looks like these code examples were written in Shift-JIS, and Shift-JIS puts ¥ where ASCII has \.
Similarly, Japanese DOS prompts are C:¥ instead of C:\
Content aside, I'm fascinated by the typography in this book. It's simultaneously beautiful and horrendous!
I don't know enough about Japanese orthography or keming rules to be sure but it looks very much like they took a variable width font with both kanji and latin characters and then hard formatted it into fixed width cells?
Either way, it's nice that the code examples aren't in 8pt font like a lot of the books I have...
That's pretty common in Japanese typography that mixes in Latin characters, especially in older fonts. Pretty decent explanation here: https://www.reddit.com/r/typography/comments/vvfmpu/comment/...
Who was the genius behind these features? Someone was incredibly forward looking in that company. Too bad it never got out into the world and impacted the language standards. It is surprising to see that so long ago.
Also previously covered here on Hacker News: https://news.ycombinator.com/item?id=38938402
Is there a PDF copy of this somewhere?
Bitsavers has a copy of the HC 1.2 reference manual (1985)
It describes underscores in numbers, case ranges, named parameters, nested functions, and full function variables.
https://bitsavers.org/pdf/metaware/High_C_Language_Reference_Manual_1.2_Nov85.pdf
See Appendix A - 50 odd pages from the end of the file.This seems way ahead of its time, especially with generators. Maybe Fujitsu was able to just do it because they didn't bother with any of the lengthy standardization processes, but that's probably also why all these extensions seemed relatively unknown and had to be rediscovered and reinvented in modern C/C++ decades later.
C could have been a much nicer language if it wasn’t captured by people who insisted that not even two’s complement can be in the standard.
I don't think it was unreasonable at the time ANSI did the standardization originally. As with Common Lisp, they had to consider the numerous already-existing implementations and code written with them in mind.
I guess those people were parts of the embedded software industry before 2000 (maybe today, I don't know). It's a very good thing that C, the lingua franca of modern computing, actually runs on everything and not just on the stuff we use to browse the internet.
Coroutines and generators were already well-understood then (see Icon!), so I think it is indeed mostly about not having to worry about standardization.
It was not Fujitsu. It was MetaWare, which had a fair degree of experience with compilers. It had a contemporaneous Pascal compiler, which was quite well known, and Pascal already had nested functions.
Old memories, I had access to the MS-DOS version of it, still preferred Borland though.
I for one think that we have lost a number of good opportunities to make C language a better and .ore powerful one.
IMHO what I would need with C is a powerful pre-processor like jinja2 and some symbol manipulation features too.
Including having proper slices, but not even one of the language authors was able to change WG14 mind on the matter.
That is what happens to languages that leave their authors behind and embrace design by committee.
I’m interested in that, do you happen to have a link or reference to that discussion?
This has the old days, what exists is Dennis's fat pointers proposal.
As a side note, these days you can fake named arguments in C, if you’re OK with every argument being 0 by default:
// Declaration:
void plot(float xlo, float xhi, float ylo, float yhi, float xinc, float yinc);
struct plot_a { float xlo, xhi, ylo, yhi, xinc, yinc; };
static inline void plot_i(struct plot_a _a) {
// inline thunk to allow arguments to be passed in registers
plot(_a.xlo, _a.xhi, _a.ylo, _a.yho, _a.xinc, _a.yinc);
}
#define plot(...) (plot_i((struct plot_a){ __VA_ARGS__ }))
// Call:
plot(alo, ahi, blo*2.0, bhi*2.0, .yinc = y, .xinc = f(x+z));
Note: this breaks if you want to pass struct literals:
plot((myfoo){x,y})
Macros will take the struct literals as multiple parameters: plot(
.arg0=(myfoo){x,
.arg1=y}
)
C macros are best left unused when possible.Nope! In general, that can be a problem, but not for this specific technique:
$ cpp -P
void plot(float xlo, float xhi, float ylo, float yhi, float xinc, float yinc);
struct plot_a { float xlo, xhi, ylo, yhi, xinc, yinc; };
static inline void plot_i(struct plot_a _a) {
// inline thunk to allow arguments to go in registers
plot(_a.xlo, _a.xhi, _a.ylo, _a.yho, _a.xinc, _a.yinc);
}
#define plot(...) (plot_i((struct plot_a){ __VA_ARGS__ }))
plot((myfoo){x,y})
plot(.yinc=(myfoo){x,y})
^D
[...]
(plot_i((struct plot_a){ (myfoo){x,y} }))
(plot_i((struct plot_a){ .yinc=(myfoo){x,y} }))
You could argue this is excessively clever, but when you need it, you really need it, so it could deserve known idiom status in the right situation.Say that to the Linux kernel or any embedded system
C macros are best left unused when possible.
Blame the committee for failing to specify an obvious and widely-demanded feature like named parameters.
The only explanation is that the people in charge of the language don't write much code.
Or they do and don’t want to learn stuff as “everything can be done the old way anyway”
There are a lot of syntactic sugar improvements the committee could make that they simply refuse to. Named parameters and function pointer syntax are compile-time fixes that would have zero runtime costs, yet it's 2024 and we've hardly budged from ANSI C.
So ... GCC has had some of these for ages.
Pascal lets you match a range of values with case low..high; wouldn't it be great if C had that feature? High C does, another feature standard C and C++ never adopted.
https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html Nested functions
https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html Generators
GCC doesn't do those --- looks like a fun feature though!My favourite, which was sadly removed was doing:
foo ? zork : bork = 123;
Oh well...Not "ages" in comparison to how long MetaWare had them. High C had this stuff back in the early 1990s and 1980s.
The headlined article doesn't mention it, but High C/C++ had modules all of those years ago, too. Anybase literals, as well. Tom Pennello participated in the standardization efforts back then, too, but none of this stuff made it in.
Is the manual online anywhere? The one for version 1.2 on Bitsavers[1] doesn’t mention any of those.
[1] https://bitsavers.computerhistory.org/pdf/metaware/High_C_La...
A later version is available here (along with the compiler itself): https://winworldpc.com/product/metaware-high-c-cpp/33x
I suspect not. I am lucky enough to be consulting this copy: https://mastodonapp.uk/@JdeBP/113199154771277394
(-:
You can still do
*(foo ? &zork : &bork) = 123;
GCC’s different implementation is mentioned in the article.
> foo ? zork : bork = 123;
That's kind of horrifying.GCC nested functions are atrocious and deserve being banned from existence. Like the article rightfully says they've been implemented using weird hacks that make basically impossible to use them safely. There's a reason why Clang has categorically refused to implement them.