3 ms·
On 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
by jbooth 15y ago
On 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.
- jbooth 15y agoYeah, my distrust for macros is mostly informed by my experience with C/C++ preprocessors, which have led to really annoying facepalms in my personal history. But, as I said, I haven't actually used macros for a large project so maybe they're more workable than I give them credit for.
- bad_user 15y agoWhen I think of macros, I'm generally thinking about getting a syntax tree at runtime and doing transformations on it. The closest thing related to this in a mainstream language is LINQ in .NET. When passing a lambda expression, you can either get a method reference that you can execute, or you can get a syntax tree of that expression. It is effectively used in Linq to Sql to query databases using the same syntax you would use for querying in-memory collections of objects. You can also teach it to do pretty sweat things, like doing data transformations using the GPU. Check out this project for instance: http://brahma.ananthonline.net/ http://brahma.ananthonline.net/ Also, macros are not necessarily executed at compile-time as in C/C++ - in Lisp a macro has no boundaries to when or how it gets executed. A macro is just a piece of code that can call normal functions and that returns a piece of code that will then get executed. One common use-case is for achieving lazy evaluation in a language that isn't lazy and so most macros are trivial to understand. But you can have other use-cases, like in the above example with Linq, where the piece of code getting generated depends on runtime conditions. I do agree that macros can make code harder to understand, but then again, I've seen horribly over-engineered, poorly implemented and unreadable pieces of Java code and so I think it all comes down to having a culture for code readability than about having a language that forces you to do things in a certain way.
- pnathan 15y agoYes, but that (specific) example is a great example of a waste of space in the vast, vast, vast majority of cases. Let me show you examples of code that hides that whole iterator groadyness: Python for foo in Foos: baz(foo) Common Lisp: (loop for foo in Foos do (baz foo)) Perl: foreach my $foo (@Foos) { baz(foo); } C++ has a foreach construct as well, but it's a bit shoehorned. I'm relatively certain C# has some shorthand here for the same thing, and IIRC, it flows nicely. There is no "Most likely", no "exception", it's very straightforward. Rarely - very rarely - I care about the mechanisms of initialization, nexting, and termination. The rest of the time, (loop for var in list do) gets me by just fine. * Macros change your program logically (as in not just perf improvements) prior to compilation. Not-macros do not. That's a big difference.* It's no different than hunting through framework documentation.
- jbooth 15y agoUh. Java has a foreach operator. Has had it for almost a decade now. Almost the same as the C# operator. You might want to consider dialing down your self-assuredness if you don't know the basic commands in the language being discussed. And macros are vastly different from hunting through framework documentation, that's not the same ballpark or even the same sport. If you want macro-like behavior in Java, you can always break out AspectJ, which I strongly recommend against doing due to my biases against code that changes in between me typing it and it running.
- pnathan 15y agoNo, it's exactly the same. It's reading the things you are using to understand what they do.
- peteretep 15y agoIn Perl you'd be more likely to write: bar($_) for @Foos;