Just a few bullet points: -- I've always thought that C #include processing sucked. Why did they never introduce an "#includeonce" directive that would have eliminated all the #ifndef stuff to prevent double includes?? -- C macros suck. They obfuscate without really introducing much capability. I've worked on languages that had macros that were their own language -- you could have real variables in them, loop, do most normal programming things. Code was generated via "emit" statements. With such a macro language you can do some amazing things, and with reasonable use (always a problem, I know) the macros served to clarify rather than obfuscate. -- Post-processing of Java bytecodes is expensive and error-prone, and again obscures the logic. Not that cost should be a criteria, but post-processing is no panacea. -- Yes, one should have to "cost-justify" including a line-number pseudo-function in javac. But there are a hundred features of Java that don't seem to me to be "cost-justified", and several hundred other missing functions that ARE "cost-justified". I never have figured out how Sun decided what went into Java and what didn't (though in several cases it appears to have depended on what would hide the deficiencies in their implementation vs expose them).
On Aug 3, 10:23 pm, Bob Kerns <r...@acm.org> wrote: > You have a very limited view of the techniques available. > > On Aug 3, 10:39 am, Leigh McRae <leigh.mc...@lonedwarfgames.com> > wrote: > > > On 8/2/2010 10:49 PM, Bob Kerns wrote:> First of all -- if you want to list > > the faults of the C language, the > > > preprocessor is very near the top. > > > Just your opinion. > > False: > "Preprocessor usage should be eliminated." > -Bjarne Stroustrup, "An Overview of the C++ Programming Language", > page 3, under table "Language-technical rules:" > > This concept carried over into the C++ standard committee. Hardly > "just my opinion". It's not removed, because C compatibility is a > higher-priority concern. > > > > That's why C++ went to great lengths to mostly remove the need for > > > using it, with inline functions, constants, and the like. > > > Now your just talking specifically about macros which still can be > > useful and there are somethings that can only be done using a macro. > > No, I am not. I have nothing against macros -- on the contrary, I met > my wife teaching a class on macros. > > Preprocessors are not the place for them. Lots of languages have > macros without preprocessors. Macros are great! I wish Java had them. > > (They do have their drawbacks, but no on the scale of a preprocessor. > And the power of any macros I'd envision is substantially more than is > offered by the C/C++ preprocessor). > > > MS tools destroy what Java has to offer IMHO. Only the re-factoring is > > better for Java. It's all opinion either way. > > Are you comparing MS C++ tools to Java tools, or C# and friends? > > Anyway, it's not all opinion. Such comparisons can be done quite > objectively. Which tools you prefer to USE is opinion. > > > I think you have to realize that preprocesing is just a tool and isn't > > to be used to solve all problems. Just because I want a hammer doesn't > > mean I regard every issue as being a nail. It's very appropriate to > > handle cross platform issues, hardware issue, diagnostic code etc. All > > of these issues are very relevant to Android. Sure these issues might > > be handled differently for a desktop solution where resources aren't as > > big of an issue. > > Nobody has shown me a case where you need a preprocessor because of > resource issues. "Can use", yes, but "need", no. > > It is HIGHLY INAPPROPRIATE to handle platform issues and hardware > issues -- it makes porting to a new platform a royal nightmare. Your > best shot there is diagnostic code -- and there are better ways, > involving post-processors rather than preprocessors. > > > Why force everyone to do it the so called right way? > > Because of the cost to everyone else of the feature you are demanding. > Why not put in every hair-brained feature anyone thinks they'd like to > use? > > Because LONG experience shows, that approach makes for major problems > with languages, and makes them harder to use. Trust me -- that > approach has had its day in the language-design world. Even a poorly- > designed API, not part of the language, can have a major adverse > impact on the maintainability of a product. > > And in extreme cases (but only extreme cases), even personal code- > formatting idiosyncrasies can have a negative impact. > > "Let people do whatever they want" has, after decades of experience, > been found to not be a good idea. A more careful balance must be > sought. > > > Why does C# have conditional compile? > > To accommodate the masses of C programmers that Microsoft wanted to > attract, of course! > > > Just because SUN chose not to support > > preprocessing in javac doesn't mean they aren't behind it. Maybe they > > chose to support it through tools so that j2me code would still work > > with j2se? That would make a lot of sense to me. For something they > > aren't behind they sure put a lot of effort into it. > > Or maybe they wanted to attract all those C programmers who are used > to "solving" every problem with a #ifdef, and aren't willing to update > their approach? > > Or maybe because the J2ME people actually WERE former C programmers. > > Language purity is not the only design constraint. Soustroup makes > that point himself. Sometimes you make compromises for acceptance. > Computer languages are partly human languages, and human languages are > a cultural artifact that change slowly. > > > > > > It's also a major compilation performance hit. With a significant > > > amount of pain, you can get Visual Studio to avoid a lot of the > > > reparsing it requires, but the language basically says that to compile > > > any particular program file, you have to parse all the #includes, > > > recursively, processing the same file over and over and over again -- > > > possibly differently each and every time, because INTEGER may mean int > > > in one case, unsigned int in another, and unsigned long long in yet > > > another. > > > > And that's a problem for programmers, too. No, I don't mean a problem > > > for me, that a good C++ programmer knows how to avoid the problems. I > > > mean its a problem I've had to help MANY experienced C++ programmers > > > resolve time and time again -- often in vendor-supplied code, rather > > > than their own. Or when two different vendor's include files conflict > > > -- or one vendor's include files conflict with their own. > > > > My long experience is that every time someone tells me they need a > > > preprocessor -- there turns out to be a better way. Sometimes you > > > replace that with code generation -- but most of the time, code > > > generation isn't the ultimate solution, either. Often, proper use of > > > introspection and metadata (the annotation facility, for example) > > > provide a superior (more robust, more compact, and more maintainable) > > > solution. > > > Solve this one for me. BlackBerry has a version of atan2 that is > > fixed-point and is much faster that the Math.atan2. How can I take > > advantage of this without an interface or an extra function call? > > Well, first, "without an interface or an extra function call" is a > completely artificial constraint. If I were managing your project, you > would first have to prove to me that the cost of the interface or > extra function call is worth the cost -- including the ongoing > maintenance cost, of finding EVERY DAMNED PLACE you pull this kind of > stunt, to upgrade to the next platform on our list. > > But lets assume you've done that. You're calling it often enough (and > you picked a plausible case). > > My response: Do it with a post-processor. Not only will you pick up > this case you chose manually, but you will also apply the policy at > every other point that would benefit that you may not have picked up > on. > > That's my big hammer. Here's my little one; > > In Jar MyMath.jar > > public abstract class MyMath { > public static final float VecToHeading( float x, float y ) > { > float fAngle = ((float)Fixed32.atand2( (int)(x * > 65536.0f), (int)(y * 65536.0f) )) / 65536.0f; > if ( fAngle< 0.0f ) > return fAngle + 360.0f; > return fAngle; > } > > } > > In jar file MyMathBlackberry.jar > > public abstract class MyMath { > public static final float VecToHeading( float x, float y ) > { > float fAngle = ((float)Math.atan2( x, y )) * > 57.295779513082320876798154814105f; > if ( fAngle< 0.0f ) > return fAngle + 360.0f; > return fAngle; > } > > } > > If you're clever, you'll see that you can start to undermine this > approach if you make the methods more complicated with only a trivial > difference. But you also undermine your own "no extra function call" > criterion at the same time. But if you're really that wedded to "no > extra function call" -- that is, you're trying to do something that > the hardware BARELY is capable of, and even a tiny bit of extra > overhead will be significant (rare but possible -- but often falsely > assumed), then the bigger hammer is definitely what you want. > > You can even do global optimizations like eliminating all calls to > functions smaller than a certain size, provided they expand the total > code size by no more than X amount, or if they occur within designated > critical code paths -- and avoid the need for manually (and > inaccurately) maintaining those policies within that code. > > > Here is another one. The math function is in two different packages. > > > //#if PLATFORM_BLACKBERRY > > omega = (float)net.rim.device.api.util.MathUtilities.acos( cosom ); > > //#else > > //@ omega = (float)java.lang.Math.acos( cosom ); > > //#endif > > My first thought (10 seconds of thought) would be to define a common > method, with two versions, and let ProGuard (post-processor) inline > it. > > > Actually laying down some surgical preprocess strikes within my code has > > allowed me to finish the project without having to create more code that > > I would have to manage and pay for at run-time. > > Unnecessary surgery is a major cause of unnecessary mortality. Note > that none of the techniques I'e outlined here carry a runtime penalty. > They have their downsides, but runtime performance is not among them. > > I have spent HUGE amounts of time dealing with problems introduced by > C macros. I wrote my first C program in 1972, on a PDP-11. Your > typical small handset is huge by comparison. I don't think you're > going to find it very easy to throw something at me that I've not seen > before. > > Hell, before that, I was writing ASSEMBLER macros. With a better macro > environment than C provides, I might add. > > I've used source code generation I think 3 other times for Java. > (HUGELY more than that in other languages). I've used dynamic class > generation a lot -- your problems may be too simple to need that, but > it's very powerful, and can give you highly optimized code tuned for > the specific case at hand. The runtime version of that approach even > allows you to optimize for information that is not available until > runtime ... > > read more » -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en