• AdmiralAsshat a minute ago

    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.

    • JdeBP 3 hours ago

      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

      • jkcxn an hour ago

        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?

        • JdeBP an hour ago

          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.

      • stefanos82 3 hours ago

        Previous submission with comments https://news.ycombinator.com/item?id=38938402

      • JoshTriplett 2 hours ago

        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 \.

        • nazgulsenpai 2 hours ago

          Similarly, Japanese DOS prompts are C:¥ instead of C:\

        • lexicality 2 hours ago

          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...

        • bhouston 2 hours ago

          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?

          • dfawcus 21 minutes ago

            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.
          • omoikane 2 hours ago

            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.

            • ahoka 2 hours ago

              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.

              • int_19h 39 minutes ago

                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.

                • dxuh an hour ago

                  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.

                • int_19h an hour ago

                  Coroutines and generators were already well-understood then (see Icon!), so I think it is indeed mostly about not having to worry about standardization.

                  • JdeBP an hour ago

                    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.

                  • pjmlp 2 hours ago

                    Old memories, I had access to the MS-DOS version of it, still preferred Borland though.

                    • notorandit 2 hours ago

                      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.

                      • pjmlp 2 hours ago

                        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.

                    • mananaysiempre 3 hours ago

                      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));
                      • ori_b 3 hours ago

                        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.
                        • mananaysiempre 2 hours ago

                          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.
                          • szundi 2 hours ago

                            Say that to the Linux kernel or any embedded system

                            • CamperBob2 2 hours ago

                              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.

                              • szundi 2 hours ago

                                Or they do and don’t want to learn stuff as “everything can be done the old way anyway”

                                • jimbob45 41 minutes ago

                                  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.

                            • amszmidt 3 hours ago

                              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...
                              • JdeBP 2 hours ago

                                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.

                              • pistoleer 2 hours ago

                                You can still do

                                    *(foo ? &zork : &bork) = 123;
                                • adastra22 2 hours ago

                                  GCC’s different implementation is mentioned in the article.

                                  • ronsor an hour ago

                                        > foo ? zork : bork = 123;
                                    
                                    That's kind of horrifying.
                                    • qalmakka 2 hours ago

                                      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.