The Artima Developer Community
Sponsored Link

Weblogs Forum
Myths of Memory Management

81 replies on 6 pages. Most recent reply: Sep 12, 2005 3:10 PM by Max Lybbert

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 81 replies on 6 pages [ « | 1 ... 3 4 5 6 ]
Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Maybe there's a Java workaround Posted: Sep 8, 2005 7:18 PM
Reply to this message Reply
Advertisement
Ick. And I'm not just talking about the curly placement.

Vesa Karvonen

Posts: 116
Nickname: vkarvone
Registered: Jun, 2004

Re: Maybe there's a Java workaround Posted: Sep 9, 2005 1:30 AM
Reply to this message Reply
> Ick. And I'm not just talking about the curly placement.

What are you talking about then?

I can't say that I'd particularly like it either. Java is much too verbose for my taste. However, one could argue that the Cleaner slightly simplifies things compared to the textbook approach:

import java.io.FileWriter;
 
public class DirtierExample {
  public static void main(String[] args) throws Exception {
    FileWriter writer1 = null;
    FileWriter writer2 = null;
    try {
        writer1 = new FileWriter("output1.file");
        writer1.write("The file will be closed at the end of block.\n");
 
        writer2 = new FileWriter("output2.file");
        writer2.write("The other file will also be closed.\n");
    } finally {
      if (null != writer2) writer2.close();
      if (null != writer1) writer1.close();
    }
  }
}

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Re: Maybe there's a Java workaround Posted: Sep 9, 2005 5:59 AM
Reply to this message Reply
Well, my point is that I wasn't being all that fair to Java. I had read the syntax for finally and thought, "That admits there's a problem, but it doesn't really solve anything." I still don't like the finally clause, but it's not as burdensome as I had thought. I would like to think that if I had been forced to use it, I would have thought of the workaround. I'm sure I'm not the first to consider the concept.

That doesn't mean I like the C++ way of doing things either. Vesa has me interested in ML again, although I haven't decided if it's better at this task. My conceptual hack on C++ (building a model and flagging potential exception-throwing methods/functions) doesn't go far enough, especially since the current guidance is to not advertise which exceptions your method/function throws (http://www.boost.org/more/lib_guide.htm#Exception-specification ). I haven't figured out a good method to handle the problem, and the methods I'm familiar with (C, C++, Java, Perl mainly) solve part of the problem, but not enough to suit me.

Vesa Karvonen

Posts: 116
Nickname: vkarvone
Registered: Jun, 2004

Re: Maybe there's a Java workaround Posted: Sep 9, 2005 7:34 AM
Reply to this message Reply
> [...] interested in ML again, although I haven't decided
> if it's better at this task.

Well, depends on what you mean by better. If you intend to ask whether it makes all resource management go away, then the answer is obviously no. What ML is considerably better at than Java is higher-order programming. Below is an example of the use of higher-order programming.

ML has exceptions (raise, handle), but the core language has nothing equivalent to Java's finally. However, using higher-order programming it is quite easy to implement it and the syntax remains quite readable. Below is one way to do it. Note that the below code is copy-pasted from my utility library. All of the definitions are useful on their own. You only need to write them once (or use a library).

  datatype ('a, 'b) either = LEFT of 'a | RIGHT of 'b
  fun either (fa, fb) = fn LEFT a => fa a | RIGHT b => fb b
  fun eval th = LEFT (th ()) handle e => RIGHT e
  fun throw exn = raise exn
  fun past ef x = (ignore (ef ()) ; x)
  fun try (th, fv, fe) = either (fv, fe) (eval th)
  fun finally (th, ef) = try (th, past ef, throw o past ef)


You can now use finally like this:

  finally (fn () =>
              (print "Where?\n"
               ; raise Fail "Bye..."),
           fn () =>
              print "Here! Here!\n")


The above would look like this in Java:

  try {
    System.out.print("Where?\n");
    throw Exception("Bye...")
  } finally {
    System.out.print("Here! Here!\n");
  }


An interesting aspect of the ML implementation of finally is the use of the try-in-unless construct (of Benton and Kennedy [1]). The try function implements it. I wish you luck in trying to implement try-in-unless in Java in a convenient and reusable form. (Note that the handle construct of Standard ML is roughly equivalent to try-catch in Java (without finally). Java's try-catch has the same problems as ML's handle.)

Needless to say, higher-order programming allows you to codify resource management patterns.

[1] http://research.microsoft.com/~akenn/sml/ExceptionalSyntax.pdf

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Re: Maybe there's a Java workaround Posted: Sep 9, 2005 9:42 AM
Reply to this message Reply
Thank you, Vesa.

In the interest of completeness, I have determined that there are certain aspects of my Cleaner concept that get a little sticky.

Basically (IMO), there should be a class hierarchy that handles the various objects that need cleaning up (all derived from, say, DirtyObject and cleanable w/ a clean() method). Then a single Cleaner array would act as a stack to hold all the DirtyObjects.

Why? Because when you open a file (and get a fileid from a finite pool) after locking that same file, you must close it BEFORE unlocking. That is, the order you acquire resources that can leak can be important, and so cleaning up MUST BE in reverse order to avoid potential bugs.

Which is exactly why low-level languages call this "stack unwinding," and why C++ guarantees that automatic objects are destroyed in the reverse order of creation. Again, not to say I like C++, only to say that this is effectively imitating the behavior in regards to resource cleanup.

Vesa Karvonen

Posts: 116
Nickname: vkarvone
Registered: Jun, 2004

Re: Maybe there's a Java workaround Posted: Sep 9, 2005 11:29 AM
Reply to this message Reply
> there should be a class hierarchy

Not everything needs to be a class hierarchy and

> (all derived from, say, DirtyObject and cleanable w/ a
> clean() method).

there is no need to force every resource to implement a specific interface in this case.

> cleaning up MUST BE in reverse order to avoid potential
> bugs.

I'm not sure what you are getting at, but if you examine the Cleaner implementation I posted, you'll see that it performs cleanup actions in reverse order. (It is not by accident.)

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Oops Posted: Sep 12, 2005 3:10 PM
Reply to this message Reply
I'm sorry. I took a second look at your implementation, and it's much better than what I suggested. You're right.

Flat View: This topic has 81 replies on 6 pages [ « | 3  4  5  6 ]
Topic: How Much Profit is Enough? Previous Topic   Next Topic Topic: QA and TDD


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2017 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us