Ah, that all makes sense.  My objections are met.  Thanks for the
clarifications.
     I also realize that if you made those assumptions I was talking about
in the caller, it would break binary class compatibility too.  If we change
the ensure/require and the app doesn't recompile with the new classlib,
there would be an inconsistency of assumptions.  Please *do* make sure you
don't use the caller's "ensure" in any null reference optimizations, if you
do them.

     Now, knowing all that, I have a request so that Classpath can be
compiled the same with either Kiev or javac and not have any adverse
effects:
     Problem: ensure/require checks will not show up when compiled with
javac.  If we copy/paste the assertions, then Kiev will do the checks
*twice*, slowing down the library.
     Possible Solution(s):
       1. Allow an alternate syntax for ensure/require within the code
itself: KievAdditions.ensure(boolean,String) and
KievAdditions.require(boolean,String).  When Kiev's parser saw it, it would
see the special reference and turn it into the equivalent
ensure/require/assert statement.  When javac compiled it, the compiler and
the runtime would look for the KievAdditions class with those methods, which
Kiev could provide and people could distribute with their apps.  (I'll write
that class *myself* if you want :)
       2. Don't-Compile-Me-Kiev Comments.  Say if /*NO_KIEV*/ ...
/*/NO_KIEV*/ is ignored in Kiev.  It will, however, be picked up by javac.
Any comment structure you desire is fine, this is just an example.

     I know that it's kind of annoying and would increase the size of
extensions, but if it's not too difficult to do #1, it would absolutely be
the most useful to us and to anyone else who desires compatibility with
javac.  #2 will work fine if not, though.

     I really like this, because you can optimize out all those sanity
checks in a production release of a product.  I am curious, though: does
ensure/require give you any other benefits besides the ability to turn
sanity checks on and off?

--John Keiser

> -----Original Message-----
> From: Maxim Kizub [mailto:[EMAIL PROTECTED]]
> Sent: Sunday, October 25, 1998 3:12 PM
> To: [EMAIL PROTECTED]
> Subject: Re: Free Java compiler - Kiev
>
>
> >I have many technical problems with the require / ensure thing
> and its use
> >in Java.
> >
> >To make the argument below simpler, I will pretend that
> Classpath is always
> >compiled using Kiev and its require/ensure keywords.
> >
> >Does Kiev optimize methods *assuming* that the requirements are
> met before
> >the method is called?  Does it optimize the caller based on *assumptions*
> >about the return value using "ensure"?  If it does, there are a number of
> >very serious problems that could arise.
>
>
> No, all checks are done within the called method itself, except
> private methods, where no invariants (class-level constraints) are
> checked. Also, there is no big posibility to optimize program
> by require/ensure constraints. The primary goal is compile-time
> error check (for those conditions that can be calculated at
> compile time) and debug run-time checks (for those constraints,
> that can be checked only at run time).
>
> >Consider compiling a Java app against the ordinary Sun library and then
> >running it on a VM with Classpath installed.  Unwarranted
> assumptions will
> >be made in Classpath's library (since they aren't checked at the caller),
> >and the program will not behave as expected.
> >
> >The other case is when the app is compiled against Classpath and run
> against
> >a normal VM.  Assumptions may be made about a library method's return
> value,
> >and the program, again, will not behave as expected.  This one
> we at least
> >have control over and can minimize by only using "ensure" when it ensures
> >exactly the same behavior as Sun, even though we may have better
> behavior.
>
> If I get you right, then here's what I think. The only "optimizeable"
> constraints
> are those, that can be checked at compile time. Also, since we can't know
> the
> caller of method - we can't optimize it. All checks, if they need to be
> done, are
> done *within* the called method, not in the caller method.
> So, if java app, compiled against Sun's classes will be runned on
> $classpath
> library - all checks will be done.
>
> Next, when compiled with $classpath application will be runned on Sun's
> classes... I think, normal exceptions will be thrown, instead of
> kiev.stdlib.AssertionFailedException. Of course, it's possible to make
> program optimization based on constraints, but anyway, it's not yet
> done, since there is no such library, thus, there is nothing to
> optimize yet. Anyway, I think about call-by-contract as debug feature,
> not the way to optimize programs.
>
> >Don't get me wrong here, I think ensure / require is a great idea.  The
> only
> >thing I can think of is some sort of switch in the VM to let
> Classpath know
> >not to make assumptions about parameters to public methods and apps know
> not
> >to make assumptions about return values from Classpath.  This
> would require
> >Kiev putting two sets of code into the final code and then having a flag
> >sitting somewhere that it checks at runtime to figure out
> whether or not to
> >make assumptions about the class library's methods.  It would, of course,
> >default to not making assumptions, since that is expected behavior in a
> >normal VM and that is what writers of non-Kiev apps would want.
> That would
> >be messy, but the only way for Kiev-compiled classes to be
> compatible with
> >Java.  I don't know if you're willing to put in that much work for such a
> >special case.  But I don't see anything we can do on this end.
>
> In fact, the structure of bytecode is:
>
> method:
>     code attribute
>         bytecode
>             require checks // depending on compile debug flag
>             the method's code
>             ensure checks // depending on compile debug flag
>         standard attributes of code attribute
>         extended require/ensure code attributes, required for
> child classes
>
> The structure and code generation is done in the way to JVM be able
> insert/remove require/ensure checks at run-time easyly.
> I try to generate constraint's checks in the way that the code of
> method itself do not depend on this checks (since I hope
> that earlier or later JVMs like japhar or kaffe will be able
> to switch this checks ob/off on the fly).
>
> >A question about Kiev that is sort of off-topic: is it possible for me to
> >write an ensure that *never* generates a runtime check?  Say I'm
> absolutely
> >certain the return value will work the way I say it does, but I just want
> to
> >let the caller know that so that Kiev can do some optimizations
> (retval !=
> >null would be a prime example of something like that) after the method
> call,
> >such as not checking for NullPointerException.
>
> I can't  say for shure, whether I made this kind of optimization,
> but even if not - it's not hard to add it. I check code flow control
> instantly, and always know for shure whether variable's value
> is/is not/uncertain == 'null'.
>
> The main problem, is that in child classes I need convert constraint
> check bytecode back into source code (to analize flow control
> and optimize generated code) - and I not yet wrote this.
> In child classes I just insert require/ensure checks *as is*, without
> (significant) analization and optimization. And, since it's not possible
> (currently) in general, I may comment out this optimization at all.
>
>
>

Reply via email to