From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) Newsgroups: gmane.lisp.guile.devel Subject: Re: (r6rs io ports) Date: Sat, 10 Apr 2010 13:06:58 +0200 Message-ID: <87k4sfftwt.fsf@gnu.org> References: <784638.41402.qm@web37907.mail.mud.yahoo.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: dough.gmane.org 1270897640 7693 80.91.229.12 (10 Apr 2010 11:07:20 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 10 Apr 2010 11:07:20 +0000 (UTC) To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Apr 10 13:07:19 2010 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1O0YX0-0001hK-B0 for guile-devel@m.gmane.org; Sat, 10 Apr 2010 13:07:19 +0200 Original-Received: from localhost ([127.0.0.1]:44700 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O0YWz-0003y6-7Y for guile-devel@m.gmane.org; Sat, 10 Apr 2010 07:07:17 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O0YWv-0003y0-LB for guile-devel@gnu.org; Sat, 10 Apr 2010 07:07:13 -0400 Original-Received: from [140.186.70.92] (port=39795 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O0YWu-0003xs-6j for guile-devel@gnu.org; Sat, 10 Apr 2010 07:07:13 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O0YWs-0005x3-74 for guile-devel@gnu.org; Sat, 10 Apr 2010 07:07:11 -0400 Original-Received: from lo.gmane.org ([80.91.229.12]:55116) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1O0YWr-0005wp-Qd for guile-devel@gnu.org; Sat, 10 Apr 2010 07:07:10 -0400 Original-Received: from list by lo.gmane.org with local (Exim 4.69) (envelope-from ) id 1O0YWp-0001dZ-Kk for guile-devel@gnu.org; Sat, 10 Apr 2010 13:07:07 +0200 Original-Received: from acces.bordeaux.inria.fr ([193.50.110.5]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 10 Apr 2010 13:07:07 +0200 Original-Received: from ludo by acces.bordeaux.inria.fr with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 10 Apr 2010 13:07:07 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 104 Original-X-Complaints-To: usenet@dough.gmane.org X-Gmane-NNTP-Posting-Host: acces.bordeaux.inria.fr X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 21 Germinal an 218 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEA52ECF4 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 83C4 F8E5 10A3 3B4C 5BEA D15D 77DD 95E2 EA52 ECF4 X-OS: x86_64-unknown-linux-gnu User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:huBLFTlFvRWi61uVKx5emxqGkkI= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:10184 Archived-At: Hi Mike, Mike Gran writes: > First, let me note the ways that r6rs ports and Guile legacy ports are > different: > > 1. Encoding is a property of the port vs a property of a transcoder > > R6RS have transcoder objects that describe a conversion as well > as the state of the conversion. I wonder what the implications of having the conversion state in the transcoder are. For instance, what if the transcoder is shared among several ports? What if it’s passed from one port to another in the middle of a conversion? Section 8.2.4 of r6rs-lib says that transcoders are “possibly stateful”, but it also says that they are immutable. So I guess a possible implementation is to have transcoders stateless and immutable, e.g., (define (latin-1-codec) "ISO-8859-1") (define* (make-transcoder codec #:optional eol-style handling) (list coder eol-style handling)) If that is the case, implementing them on top of Guile’s ports should be easier. (The only thing is that there’s no distinction between binary and textual Guile ports.) > These can be attached to ports or removed from ports. > > 2. Pushback vs lookahead > > Guile legacy ports implement an ungetc operation. You can > always push a character back onto a port, even if the underlying > port doesn't support it. It does this by implementing a > pushback buffer for each port. Characters that are 'ungotten' > go into the pushback buffer, and the next getc checks the > pushback buffer first. The pushback code is rather complex. > > This behaviour is vital to operation of the legacy Guile parser, > which uses 'ungetc' repeatedly. > > (I suppose this would allow Guile to parse code from a pipe, > but, I've never tried that.) > > R6RS ports instead have the concept of 'lookahead' but no > 'ungetc'. Characters can not be pushed back onto a port, but, > one can lookahead to see what bytes or characters are next. Guile has ‘scm_peek_char ()’ and ‘lookahead-u8’ is implemented in terms of it in libguile/r6rs-ports.c. > Anyway. On to implementation... > > There are 4 types of R6RS ports: file, bytevector, string, and custom. > Each port is either binary or textual, and not both at the same time. > > So one possibility is the following.... > > 1. Expose scheme functions that are a set of low level file operations > that bypass Guile legacy ports and scm_getc. > > 2. Build the binary R6RS port system in Scheme using these functions, > and the bytevector and string functions that already exist. > > (There will be no pushback buffer or intermediate storage of port data. > If a file supports random access or rewind, the lookahead operation will > succeed. Otherwise, it will fail.) > > 3. Create a transcoder object in C that holds encoding and conversion > strategies, similar to those that we have attached to Guile legacy > ports. Add methods to the transcoder object to do conversion between > bytevectors and strings. > > 4. Build textual R6RS ports in Scheme on top of the binary R6RS port > system and the transcoder object. > > 5. And, ultimately, create a 'pushback buffer' object that supports > an ungetc operation. Rebuild Guile legacy ports as a combination > of R6RS ports and a pushback buffer object. I may well be missing something, but how about this hopefully simpler strategy: 1. Transcoders are (roughly) as simple as suggested above. 2. In r6rs-ports.c, when a transcoder is passed, just scm_set_port_encoding_x, etc. the port. 3. Implement EOL handling in Guile ports. 4. See whether/how binary and textual ports can be differentiated in Guile ports. 5. Have fun making sure the functions raise the right R6RS error conditions instead of ‘system-error’ et al. How much sense does it make? :-) Thanks, Ludo’.