[HN Gopher] Translation Units Considered Harmful?
       ___________________________________________________________________
        
       Translation Units Considered Harmful?
        
       Author : ingve
       Score  : 72 points
       Date   : 2020-10-07 17:34 UTC (5 hours ago)
        
 (HTM) web link (cor3ntin.github.io)
 (TXT) w3m dump (cor3ntin.github.io)
        
       | still_grokking wrote:
       | >But, you are a very great engineer, so you wouldn't let a source
       | file grow above a few hundred lines of code, would you? I bet
       | your code is beautiful, like this small self-contained super
       | useful program                 #include <iostream>        int
       | main () {            std::cout << "Hello world\n";        }
       | 
       | >Which on my system expands to about 33000 lines of code.
       | 
       | Really great rant! Much underrated.
        
       | chromatin wrote:
       | > In practice, we use the preprocessor - a tech implemented by a
       | drunk bell labs intern on LSD sometime in the late 60s, early 70s
       | - to stitch together a collection of files that we are never
       | quite sure where in the system they come from. We call them
       | headers and source files, but really, you can include a .cpp file
       | in a .h or elect to use the .js extension for headers, .rs for
       | sources files and your tools would not care. You can, of course,
       | create circular header dependencies.
       | 
       | The whole section is gold
        
         | throwaway_pdp09 wrote:
         | Umm. I'll read the article but as far as preprocessors go, I'm
         | doing some C# and I'd really, really like one so as not to have
         | to reproduce loadsa boilerplate.
         | 
         | The removal of such things seems to be driven by dogma as much
         | as good reasons, of which there definitely are.
        
           | emmanueloga_ wrote:
           | Can partial classes help? I always thought it was a great
           | feature to have, and as far as I know only C# implements
           | something like it.
           | 
           | https://stackoverflow.com/a/3601918/855105
        
           | dnautics wrote:
           | you don't want preprocessors. Of all the metaprogramming
           | choices, the preprocessor (C or erlang) is the worst, since
           | it operates on lexical forms, and is sort of its own DSL. Not
           | only do you have to learn two languages for the benefit of
           | one, but you're gonna have bugs and it's much harder to
           | automated tools to do code analysis.
           | 
           | You could have lispish ast transforms (rust, julia, elixir)
           | You could have comptime (zig, elixir)
           | 
           | both of these are far nicer than preprocessor.
        
             | jcelerier wrote:
             | if you don't give a preprocessor to people they will either
             | hack it (see cpp being used for parsing .Xresources and
             | affiliated) or write their custom preprocessor in an unholy
             | mess of bash / python / ruby / cmake anyways.
        
               | andrepd wrote:
               | Why? Anything you want to do on a textual preprocessor
               | you can also do on an AST rewriter (like ocaml ppx or
               | rust macros).
        
               | a1369209993 wrote:
               | > Anything you want to do on a textual preprocessor you
               | can also do on an AST rewriter
               | 
               | That is blatantly and obviously false:
               | #define BEGIN {       #define END }       int main(void)
               | BEGIN int x = 0; return x; END
        
               | sebbertsen wrote:
               | I don't want to do that
        
             | throwaway_pdp09 wrote:
             | You may be right but prepros are what I'm familiar with and
             | AST-mungers I'm not. The best solution is better language
             | features. I get the PP = DSL (not a problem) that makes the
             | link between original DSL code and the produced code very
             | obscure (big problem) but they are needed at times.
             | 
             | Thanks for pointing me at AST transformers.
        
           | Jtsummers wrote:
           | I'd rather have boilerplate than C's preprocessor system.
           | Perhaps a different macro system would be nice for C#, but
           | not C's.
        
           | marcosdumay wrote:
           | Some people look at a problem and say "I know how to solve
           | that! I'll write a code generator!". They then have a problem
           | generator, that will output fresh interesting problems every
           | time it runs.
           | 
           | It is the only advanced tool available in C and C++, where
           | people hate it. But for some reason Java developers are great
           | fans (even though reflection is available), and their
           | generators will always accept XML. It's still the first time
           | I see a C# developer asking for it.
        
             | qsort wrote:
             | The problem isn't even code generation. It's the fact that
             | the C preprocessor adopts the most retarded model one can
             | possibly think of, text replacement.
             | 
             | Read the paragraph following point 3. in the following
             | link, and laugh or cry (your choice):
             | https://man7.org/linux/man-
             | pages/man3/pthread_cleanup_push.3...
             | 
             | Thinking in terms of strings of text instead of the
             | abstract syntax tree is literally the roman numerals of
             | computer science.
        
               | throwaway_pdp09 wrote:
               | To be fair you're rolling in the luxury of hindsight. It
               | wasn't that log ago that a supercomputers had only a few
               | MB of memory.
               | 
               | Price US$7.9 million in 1977 (equivalent to $33.3 million
               | in 2019) Weight 5.5 tons (Cray-1A) Memory 8.39 Megabytes
               | 
               | https://en.wikipedia.org/wiki/Cray-1#Cray-1M in the
               | 1970s.
               | 
               | Dig up the spec of the PDP and be, well, something'd. Not
               | sure what. Glad you were born now, I guess.
        
               | qsort wrote:
               | Not sure how this is relevant to the topic at hand. Sure,
               | there are many features of C that are easy to laugh at
               | but in context make a lot of sense, but the macro system
               | is _not_ one of them. Hart /Levin LISP had hygienic
               | macros, just saying... And you don't even need the full
               | generality of a compiler to have limited but still useful
               | AST-rewriting macros, there are a ton of ways this could
               | be implemented very cheaply in terms of both memory and
               | cpu, none of which are rocket science.
               | 
               | Seriously, the fact that textual macros are terrible
               | isn't even a controversial point. Maybe I'm too young to
               | be a Real Programmer(tm), but this 'everything is text'
               | idea never made sense to me.
        
               | Joker_vD wrote:
               | POSIX.1 permits pthread_cleanup_push() and
               | pthread_cleanup_pop() to         be implemented as macros
               | that expand to text containing '{' and '}',
               | respectively.
               | 
               | I'm sorry, what? Why would you permit _that_?
               | On Linux, the pthread_cleanup_push() and
               | pthread_cleanup_pop()         functions *are* implemented
               | as macros that expand to text containing         '{' and
               | '}', respectively.  This means that variables declared
               | within         the scope of paired calls to these
               | functions will be visible within         only that scope.
               | 
               | Yeah, and people call _me_ a joker. But I wouldn 't
               | manage to invent this even if I tried to.
        
               | qsort wrote:
               | To be fair that particular example isn't as terrible as
               | it looks because that's (generally) the intended
               | behavior. But yeah, this is the type of arcane bullshit
               | that comes up all the times in system-level C
               | programming. C is a great language, but the environment
               | you find yourself programming in is layers upon layers of
               | barely intelligible nonsense that nobody needs nor wants.
        
           | MereInterest wrote:
           | I'd rather have language features to cover those use cases
           | than a preprocessor.
           | 
           | As an example of what I mean, in Java and C++, class
           | properties are typically accessed by getters and setters,
           | since you might want to change the internal structure of a
           | class without changing the interface. In Python and C#, you
           | can get the same benefit by changing a member variable to a
           | property. As a result, the boilerplate of getters/setters
           | isn't needed.
        
       | choeger wrote:
       | I don't agree fully with the idea of getting rid of compilation
       | units, object files and libraries. I think their existence is
       | necessary for fundamental technical reasons. I also consider the
       | "link everything statically" approach failed, because in the end
       | you want at least _some_ run-time linking (vdso for instance and
       | actually also the fundamental system libraries).
       | 
       | But also languages like rust and swift and before them OCaml and
       | Haskell show that the current prevalent C/C++ ABI is not powerful
       | enough. And in principle, there is not much of a difference
       | between the reason for header-only libraries in C++ and rust not
       | having a composable ABI. It is always about the lack of
       | information one can pass through the ABI.
       | 
       | Interestingly, one does not even _need_ to exchange the
       | definition of a rust function or that of a C++ template for
       | monomorphisation. One could easily define an extensible library
       | that will create the new specialisation for any given input. One
       | would only need to  "freeze" the compiler that was used to create
       | the library and ship it with that library. Ok, easier said than
       | done, of course.
        
         | fouric wrote:
         | Would you describe these "fundamental technical reasons"?
        
       | esc_colon_q wrote:
       | > But as the C++ community dreams of better tools, and dependency
       | managers, maybe it would help to define the fundamentals more
       | accurately: Our programs are a set of definitions, some of which
       | are provided and maintained out-of-tree by other people. I think
       | the more closely our tools adhere to that model, the better off
       | we will fare in the long run.
       | 
       | > So maybe we need to ask fundamental questions about the
       | compilation model and examine some beliefs we hold (For example
       | "Compilers and build system need to be kept separated". Do they?
       | To what extent?).
       | 
       | I think you just put your finger on why Google is a monorepo -
       | Blaze/Bazel kinda suck horribly (they feel super dated and could
       | have been made much friendlier if they'd been designed from the
       | ground up knowing what the pain points are, and _esp_ if they
       | weren 't basically an ad-hoc set of new languages/syntaxes), but
       | they're also awesome. The huge benefit is that you can make tools
       | that work across _everything_ and track monstrous dependency
       | graphs.
        
         | [deleted]
        
       | toolslive wrote:
       | regarding noexcept. Honestly, `noexcept` is more documentation
       | than anything else. Its specification merely guarantees that if
       | the function does throw, you get a call to `std::terminate`
       | (which aborts). It's just another thing you cannot really really
       | trust.
        
         | senkora wrote:
         | noexcept is also important for optimization.
         | 
         | If a template function is guaranteed to be exception-safe, and
         | it's called with a type whose move constructor isn't noexcept,
         | then the function needs to fallback to the copy constructor to
         | maintain exception-safety.
         | 
         | This happens a lot with the standard library.
        
         | nicoburns wrote:
         | It would be better if it could actually statically guarantee
         | that the function doesn't throw though!
        
       ___________________________________________________________________
       (page generated 2020-10-07 23:01 UTC)