gusl: (Default)
[personal profile] gusl
Is it possible to write a function that does something only after its caller is finished?

I am writing a function that creates a temporary file, writes some stuff to it, and returns the filename. The expression where this is called gets the returned value, uses the file, but nobody does after that. The file should therefore be deleted, but by whom?

If I delete it inside the function that creates it, then the file can't be used by the expression that called it.

I can just delete the file on the next S-expression, right after the expression that calls the function, but that seems like a violation of modularity, since the creation and deletion are not in the same place (not to mention that this requires me to save the returned value, introducing a let).

It would be good if my function could stay in the background after returning, and somehow know when to delete the file. Of course, I would need to tell it when: however, something like "two levels up the call stack" sounds like a non-robust solution. Maybe you could have a scope for temporary files (i.e. a let): as soon as you fall out of that scope, all temporary files created inside get deleted.

Maybe there is a way of creating temporary files so that they get cleaned by a garbage collector as soon as the program ends.

--

This reminds me of an old debate, about a solution that seemed much easier by using GOTO. It was probably a reaction to "GOTO Considered Harmful".

(no subject)

Date: 2006-02-07 06:44 pm (UTC)
tiedyedave: (Default)
From: [personal profile] tiedyedave
One strategy used by some garbage-collecting languages is called "finalization". The programmer is allowed to specify code to be executed when a value would be garbage-collection; the collector invokes the finalization code just before collecting the memory.

In the case of temporary files, you'd simply attach the file closure/deletion code as a finalization of the file handle.

Finalization is available in Java (via implementation of the finalize() method provided by Object), OCaml (via the Gc.finalise library call), and possibly other GC'd languages.

Two problems with this: As far as I am aware, the semantics of finalization (especially with respect to what code can be executed during a finalization) are poorly specified. Additionally, finalization is limited by the garbage collector's ability to detect when a value is no longer reachable, and so all GC problems related to uncollected memory also apply to uninvoked finalizations.

(no subject)

Date: 2006-02-07 06:51 pm (UTC)
tiedyedave: (Default)
From: [personal profile] tiedyedave
Wikipedia has more info on this.

Also, you can do something similar in C++ by explicitly extending the destructor of a class. However, this is not the same as finalization since the invocation of a destructor (at least for heap-allocated values) is under the programmer's control via the 'free' operator. Specifically, the programmer is allowed to free a value while it is still technically reachable -- this is a notorious source of memory errors in C++.

(no subject)

Date: 2006-02-07 07:29 pm (UTC)
From: [identity profile] mindwalker.livejournal.com
Is your question specific to LISP or just a general programming question?

(no subject)

Date: 2006-02-07 09:24 pm (UTC)
From: [identity profile] ernunnos.livejournal.com
Under Unix you can create a file, open it, and immediately unlink it. You can continue to use it as long as it's open, but for all intents and purposes it doesn't exist, and will disappear completely as soon as the program exits or closes the file.

(no subject)

Date: 2006-02-07 11:05 pm (UTC)
From: [identity profile] smandal.livejournal.com
Kind of technical, but describes how to use a wrapper around this unlinking:

http://linux.omnipotent.net/article.php?article_id=11369

(no subject)

Date: 2006-02-08 06:02 am (UTC)
From: [identity profile] darius.livejournal.com
In Common Lisp it's conventional to do this sort of thing with a macro along the lines of with-open-file. Something like

(with-temporary-file (filename) (do-stuff-to filename))

(no subject)

Date: 2006-02-08 06:10 am (UTC)
From: [identity profile] williamallthing.livejournal.com
Ruby does the same thing; File.open can take a block (co-routine for non-Rubyists) which it calls once, then closes the file when the block ends.

File.open("file.txt") do |f|
f.readlines.each { |l| ... }
end

I think this ("inversion of control") is the Right Way to do it.

(no subject)

Date: 2006-02-08 10:58 am (UTC)

(no subject)

Date: 2006-02-08 01:31 pm (UTC)
From: [identity profile] gustavolacerda.livejournal.com
General. I think that Lisp is universal enough to naturally express a solution given in any other existing language.

(no subject)

Date: 2006-02-08 01:34 pm (UTC)
From: [identity profile] gustavolacerda.livejournal.com
hmmm... maybe that's how /dev/null is implemented?

Object Oriented:

Date: 2006-02-09 11:53 am (UTC)
From: [identity profile] jbouwens.livejournal.com
In C++, I'd do this by wrapping the temp-file in a class. You create a local variable of the type "TempFile" in a function where you need one, and when the function ends, the local variable goes out of scope and its destructor is called, which can close/delete the file.

February 2020

S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags