4 ms·
Yeah, and if I went through the codebase for my current project and added a bunch of line breaks, I'd double the code "size" according to the LOC metric without
by jbooth 15y ago
Yeah, and if I went through the codebase for my current project and added a bunch of line breaks, I'd double the code "size" according to the LOC metric without changing anything about the complexity at all.
Macros kinda terrify me because they mean I can't glance at a random 5-line fragment and know exactly what's happening. I'm not convinced that they add to clarity, even while doing a lot for conciseness. To be fair, I've never used them on a project that was bigger than "tiny", so maybe I'm just casting aspersions on something I don't understand.
After macros, then what? Is the slightly redundant Foo foo = foos.next() in Java really hurting clarity that bad? I mean, yeah, the type should be inferred there but is that the reason big projects get unmanageable? Or is it higher-level architectural bloat?
EDIT: Wow. Any downvoters want to explain why this comment is so offensive to them? Perhaps they could contribute their own thoughts about complexity and code bloat?
- deleted 15y ago[deleted]
- bad_user 15y agoMacros kinda terrify me because they mean I can't glance at a random 5-line fragment and know exactly what's happening Higher-level languages like Java running on top of advanced VMs like the Hotspot JVM -- are high-level enough such that you NEVER know what's happening. Even dropping to JVM bytecode doesn't help you much, as that doesn't show you how data moves in and out of the registers, how decisions on compiling hotspots / inlining functions are made, or how allocated objects move through GC-generations. You also lose control a lot. When you drop down to assembly, tail-calls are trivial for instance, not to mention dealing with cache pressure becomes a lot simpler. What high-level languages give you (versus assembly) is a way to express intent, rather than details that you don't care about in general. Which is no different from having macros in your language, or other high-level abstractions, in which you invent your own language for expressing intent, rather than deal with useless details that you don't care about 99% of the time. Foo foo = foos.next() But that line isn't really clear. It's saying stuff like - give me a Foo right now. But what happens when there are no more Foos to be given? Does it return a Null? Does it trigger an exception? That line of code also doesn't express intent. So you've got a Foo. Now what? And have I mentioned that objects in "foos" may not be Foo instances? Basically that whole line of code is totally worthless boilerplate.
- jbooth 15y agoOn your first point, I meant logically what's happening, not the exact memory and heap layout. I'm pretty sure you can take that for granted in any discussion about programming ever unless the person says "in regards to the exact stack and heap layout". You don't know the heap layout in C either, at least not without some extreme measures like reading the values of pointers, and you don't usually care. You can't just say "oh this is sort of like this so we'll just collapse all the differences". Macros change your program logically (as in not just perf improvements) prior to compilation. Not-macros do not. That's a big difference. That line is crystal clear (as shorthand) to a Java developer because "foos" is most likely an Iterator<Foo> which will throw an exception when there are no more foos. In an actual program it will be very explicit that it's an Iterator<Foo>. That's a context thing that's specific to Java where all Iterators behave the same way. The difference between the standard java.util stuff and macros is that each shop or team has their own macros and in my limited experience with macros, it is not always easy to tell where they're in effect. And, the line isn't boilerplate. We're creating a reference to a Foo and assigning a value to the destination of that reference. Presumably, we're going to do some stuff with it later. Otherwise, yes, we would not be bothering to pop one out of the iterator. Is that clear now? What actual point are you trying to prove in this comment? My comment was sort of a request for actual constructive solutions. You've provided non-sequitors.
- gloob 15y agoIf you haven't seen Trusting Trust already, you should read it: http://cm.bell-labs.com/who/ken/trust.html http://cm.bell-labs.com/who/ken/trust.html . It's short and smart. The brief summary is, of course, you can almost never really know "logically what's happening", even in nice reliable languages like Java or Python or Haskell or Ruby or C.[0] The easy solution (and the one that every working programmer makes every day) is to say: well, let's assume that the compiler is non-malicious and has relatively few bugs that will impact me. That's a fair response. Next we run into the fact that just because you call a function, and that function happens to be called add(x,y), doesn't actually mean that the function will return the sum of x and y. In the absence of further evidence, it could be an HTTP server or fill your hard drive with infinite copies of Das Kapital or anything at all. The normal solutions proposed to this are (1) read the documentation, or (2) read the code. Those are both workable solutions. Then macros come into the picture. I fail to see how the already-heavily-used techniques of (1) reading documentation and (2) reading the implementation of the macro, which seem to be at least tolerable and mostly workable with functions suddenly fall apart with macros. [0] C and C++ have the preprocessor and macros anyway, which "change your program logically...prior to compilation", so I won't mention them further in this comment.
- PaulHoule 15y agoIn my mind excessive line breaks ARE a problem. A key skill in programming is holding a large number of concepts together at once and thinking about them together. It's like holding up a big stack of bowls, plates, silverware, glasses and other stuff. Large screen area makes it possible to scan this stuff with your eyes, which increases your effective working memory. If your code takes up 3x the space, you can fit less on your screen, so your effective working memory is smaller. Practically, it makes you less intelligent.
- bronson 15y agoCare to point out a serious project with a line break problem?
- jimbokun 15y agoThe "braces on separate lines" style contributes to a line break problem, in my opinion. If you use this style and have nice, concise methods and/or functions, the extra lines added for each start brace can take up a noticeable amount of your code window's real estate. There are other code style choices that increase line count which I dislike for the same reason, this is just the first one that came to mind.
- radu_floricica 15y agoYou don't really want to know everything that's going on. At some point, and over a certain project size, you just have to trust some stuff and use higher abstractions when reading/writing code. Macros are one of the tools you have for doing this in an orderly, not-want-to-kill-yourself way. So yeah, they hide stuff, but when you have no choice but to hide stuff they can do it quite well.