pio: phrase_to_file/2
:- meta_predicate( phrase_to_file(2,+) ).
Essentially this is the opposite of phrase_from_file/2, except that its complete meaning is not that evident.
phrase_to_file(Phrase__0, File) is well defined in the case where there is a single answer string for phrase(Phrase__0, Cs). In this case the characters of Cs are written onto File. The File with those characters appears upon success. The idea is now to write out those Cs as they are generated. So much for the most important intended use case.
But there are many more cases to consider:
-
In case the generation of
Csbecomes non-determinate it seems best to wait. -
As long as there are some variables in
Cs, waiting is needed as well. -
For a finally non-ground
Cs, an instantiation error is needed. -
While
phrase_to_file( [non_character], File)should produce atype_error(character, non_character), the goalphrase_to_file( ( cs1, ( cs2, [non_character], cs3, { false } | cs4 ) ), File), withcsibeing well formed character sequences, must not produce a type error. No matter how long these sequences might be.
What is the blocker for this issue?
I have filed #1045 with a rudimentary version that works for the most important case of a deterministic grammar rule body that describes a list of characters, as long as the list fits entirely into memory. The intention of this pull request is to make a basic version of this feature available so that it can be tried out and used in cases where it already works. This is analogous to phrase_from_file/2, where @notoria initially supplied a basic working version that was already useful in practice, garnering more interest in the functionality and eventually leading to an improved version that actually read the file lazily.
Are there any opinions about merging this for a start? If so, please comment. Thank you a lot!
Revisiting this:
The current implementation works well if the whole string fits into memory at once (which fits many use-cases).
I wonder if we can take some of the tricks that are used in phrase_from_stream and apply it to phrase_to_stream as well.
For instance, rather than writing 'characters as soon as they become available' (which is difficult to make fast enough), what about writing characters in blocks and recursing, having to (only) keep track of these blocks' positions as we continue writing if the need to backtrack and re-write (moving back to a previous position and writing from there) arises.
My logic is probably incomplete because otherwise it might have been added already. Is there a problem with this approach?