unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* binary-port?
@ 2011-04-22 22:28 Ludovic Courtès
  2011-04-23  1:48 ` binary-port? Andreas Rottmann
  0 siblings, 1 reply; 10+ messages in thread
From: Ludovic Courtès @ 2011-04-22 22:28 UTC (permalink / raw)
  To: guile-devel

Hello,

I just pushed 96128014bfaabe9e123c4f4928ce4c20427eaa53, which makes
‘binary-port?’ deterministic for ports intended to be binary.

However, I’m wondering whether we should not just squarely do away with
the binary/textual distinction, and just write:

  (define (binary-port? p) #t)

What do people with experience with pure R6RS code think?  Is the
distinction actually used, and how?

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-22 22:28 binary-port? Ludovic Courtès
@ 2011-04-23  1:48 ` Andreas Rottmann
  2011-04-23 19:56   ` binary-port? Ludovic Courtès
  0 siblings, 1 reply; 10+ messages in thread
From: Andreas Rottmann @ 2011-04-23  1:48 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

ludo@gnu.org (Ludovic Courtès) writes:

> Hello,
>
> I just pushed 96128014bfaabe9e123c4f4928ce4c20427eaa53, which makes
> ‘binary-port?’ deterministic for ports intended to be binary.
>
Glad to see that!

> However, I’m wondering whether we should not just squarely do away with
> the binary/textual distinction, and just write:
>
>   (define (binary-port? p) #t)
>
> What do people with experience with pure R6RS code think?  Is the
> distinction actually used, and how?
>
I can only find one example in the code I wrote:
`copy-port', which works (with the probably obvious semantics), on both
binary and textual ports.  On Guile, when `binary-port?' would return #t
for all ports, `copy-port' would break, losing the transcoding effect
you'd get when you pass two textual ports of different encodings.  With
the current behavior, you still have to watch the order of your port
type checks, testing for `binary-port?' first, whereas on systems
following R6RS strictly, you'd get the same behavior regardless of type
check order.  I can live with the latter, but the former would be
unfortunate, IMHO.

Regards, Rotty
-- 
Andreas Rottmann -- <http://rotty.yi.org/>



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-23  1:48 ` binary-port? Andreas Rottmann
@ 2011-04-23 19:56   ` Ludovic Courtès
  2011-04-24  6:39     ` binary-port? Marco Maggi
  2011-04-25 11:55     ` binary-port? Andreas Rottmann
  0 siblings, 2 replies; 10+ messages in thread
From: Ludovic Courtès @ 2011-04-23 19:56 UTC (permalink / raw)
  To: Andreas Rottmann; +Cc: guile-devel

Hi Andreas!

Andreas Rottmann <a.rottmann@gmx.at> writes:

> ludo@gnu.org (Ludovic Courtès) writes:

[...]

>> However, I’m wondering whether we should not just squarely do away with
>> the binary/textual distinction, and just write:
>>
>>   (define (binary-port? p) #t)
>>
>> What do people with experience with pure R6RS code think?  Is the
>> distinction actually used, and how?
>>
> I can only find one example in the code I wrote:
> `copy-port', which works (with the probably obvious semantics), on both
> binary and textual ports.  On Guile, when `binary-port?' would return #t
> for all ports, `copy-port' would break, losing the transcoding effect
> you'd get when you pass two textual ports of different encodings.

Interesting.  Can you post a link to the code?

Anyway, that’s probably enough to keep the current semantics in 2.0.

> With the current behavior, you still have to watch the order of your
> port type checks, testing for `binary-port?' first, whereas on systems
> following R6RS strictly, you'd get the same behavior regardless of
> type check order.  I can live with the latter, but the former would be
> unfortunate, IMHO.

Do you know what Industria, Nausicaa, & co. do?

Likewise, any idea which Schemes have disjoint binary/textual ports, and
which don’t?

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-23 19:56   ` binary-port? Ludovic Courtès
@ 2011-04-24  6:39     ` Marco Maggi
  2011-04-24 13:03       ` binary-port? Ludovic Courtès
  2011-04-25 11:55     ` binary-port? Andreas Rottmann
  1 sibling, 1 reply; 10+ messages in thread
From: Marco Maggi @ 2011-04-24  6:39 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

Ludovic Courtès wrote:

>>> However,  I’m  wondering  whether  we  should  not  just
>>> squarely do away with the binary/textual distinction

How would you handle port position?  From R6RS[1]:

  (port-has-port-position? port) procedure
  (port-position port) procedure

    The port-has-port-position? procedure  returns #t if the
    port  supports  the   port-position  operation,  and  #f
    otherwise.

    For a  binary port, the  port-position procedure returns
    the index of  the position at which the  next byte would
    be  read  from  or  written  to the  port  as  an  exact
    non-negative  integer   object.  For  a   textual  port,
    port-position     returns     a     value    of     some
    implementation-dependent  type  representing the  port’s
    position;  this value  may  be useful  only  as the  pos
    argument  to   set-port-position!,  if  the   latter  is
    supported on the port (see below).

    If   the   port   does   not  support   the   operation,
    port-position  raises an  exception with  condition type
    &assertion.

      Note: For a textual port, the port position may or may
      not be an integer object.  If it is an integer object,
      the integer object  does not necessarily correspond to
      a byte or character position.

  (port-has-set-port-position!? port) procedure
  (set-port-position! port pos) procedure

    If port is  a binary port, pos should  be a non-negative
    exact  integer object. If  port is  a textual  port, pos
    should be the return value of a call to port-position on
    port.

  I  do  not  know  how  current  Guile  handles  ports;  if
internally  you mark a  binary port  to handle  the position
char-wise (so  that it  is meant to  be a textual  port) and
BINARY-PORT? returns #t: what does GET-U8 do?

> Do you know what Industria, Nausicaa, & co. do?

  Nausicaa uses  BINARY-PORT?  and TEXTUAL-PORT?   only when
establishing the conventional class  of a port value; as far
as  I remember  it does  it in  the same  way GOOPS  does to
dispatch multimethods.

  IMHO this R6 statement:

  (textual-port? port) procedure 
  (binary-port? port) procedure 

    The  textual-port?  procedure  returns  #t  if  port  is
    textual,  and  returns  #f otherwise.  The  binary-port?
    procedure returns  #t if port is binary,  and returns #f
    otherwise.

should be enough to derive that:

  (cond ((binary-port? p)
         ---)
        ((textual-port? p)
         ---))

and:

  (cond ((textual-port? p)
         ---)
        ((binary-port? p)
         ---))

must  be  equivalent;  if  they are  not,  confusion  arises
because of violation of the rule of least surprise.

[1] <http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-9.html#node_sec_8.2.6>
-- 
Marco Maggi



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-24  6:39     ` binary-port? Marco Maggi
@ 2011-04-24 13:03       ` Ludovic Courtès
  0 siblings, 0 replies; 10+ messages in thread
From: Ludovic Courtès @ 2011-04-24 13:03 UTC (permalink / raw)
  To: Marco Maggi; +Cc: guile-devel

Hi Marco,

Marco Maggi <marco.maggi-ipsu@poste.it> writes:

> Ludovic Courtès wrote:
>
>>>> However,  I’m  wondering  whether  we  should  not  just
>>>> squarely do away with the binary/textual distinction
>
> How would you handle port position?

Currently port position is in bytes for all kinds of ports (info
"(guile) Random Access").  It seems to be a valid implementation of R6
port positions, no?

[...]

>   IMHO this R6 statement:
>
>   (textual-port? port) procedure 
>   (binary-port? port) procedure 
>
>     The  textual-port?  procedure  returns  #t  if  port  is
>     textual,  and  returns  #f otherwise.  The  binary-port?
>     procedure returns  #t if port is binary,  and returns #f
>     otherwise.
>
> should be enough to derive that:
>
>   (cond ((binary-port? p)
>          ---)
>         ((textual-port? p)
>          ---))
>
> and:
>
>   (cond ((textual-port? p)
>          ---)
>         ((binary-port? p)
>          ---))
>
> must  be  equivalent;  if  they are  not,  confusion  arises
> because of violation of the rule of least surprise.

Yes, and that’s a problem.

OTOH, what I wonder is when in practice would you need to use such an
idiom, or to use these predicates at all?

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-23 19:56   ` binary-port? Ludovic Courtès
  2011-04-24  6:39     ` binary-port? Marco Maggi
@ 2011-04-25 11:55     ` Andreas Rottmann
  2011-04-25 14:08       ` binary-port? Ludovic Courtès
  1 sibling, 1 reply; 10+ messages in thread
From: Andreas Rottmann @ 2011-04-25 11:55 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

ludo@gnu.org (Ludovic Courtès) writes:

> Hi Andreas!
>
> Andreas Rottmann <a.rottmann@gmx.at> writes:
>
>> ludo@gnu.org (Ludovic Courtès) writes:
>
> [...]
>
>>> However, I’m wondering whether we should not just squarely do away with
>>> the binary/textual distinction, and just write:
>>>
>>>   (define (binary-port? p) #t)
>>>
>>> What do people with experience with pure R6RS code think?  Is the
>>> distinction actually used, and how?
>>>
>> I can only find one example in the code I wrote:
>> `copy-port', which works (with the probably obvious semantics), on both
>> binary and textual ports.  On Guile, when `binary-port?' would return #t
>> for all ports, `copy-port' would break, losing the transcoding effect
>> you'd get when you pass two textual ports of different encodings.
>
> Interesting.  Can you post a link to the code?
>
Sure, it's in `(spells ports)':

https://github.com/rotty/spells/blob/master/spells/ports.sls

> Anyway, that’s probably enough to keep the current semantics in 2.0.
>
>> With the current behavior, you still have to watch the order of your
>> port type checks, testing for `binary-port?' first, whereas on systems
>> following R6RS strictly, you'd get the same behavior regardless of
>> type check order.  I can live with the latter, but the former would be
>> unfortunate, IMHO.
>
> Do you know what Industria, Nausicaa, & co. do?
>
I don't have a copy of nausicaa lying around here, but in the R6RS code
I have on my machine, xitomatl/ports.sls is the only other occurance of
`binary-port?' (besides spells/ports.sls):

http://bazaar.launchpad.net/~derick-eddington/scheme-libraries/xitomatl/view/head:/ports.sls

It's use there is in `open-compound-input-port':

    ;; A compound input port is a custom port which represents the logical
    ;; concatenation of other input ports.  It starts out with an ordered
    ;; collection of input ports and reads from the first one until end of file
    ;; is reached, whereupon it reads from the second one, and so on, until end
    ;; of file is reached on the last of the contained input ports, and then
    ;; subsequent reads from the compound input port will return end of file.
    ;; After each component port is exhausted, it is closed.  Closing a compound
    ;; input port closes all remaining component ports.  get-position and
    ;; set-position! are not supported.

So, my impression is that while `binary-port?' and `textual-port?' are
not used widely, they do have their uses, and there is definitly code
out there that relies on the binary/textual distinction.

> Likewise, any idea which Schemes have disjoint binary/textual ports,
> and which don’t?
>

- Ikarus and Ypsilon definitly have disjoint ports.

- Racket natively has ports that will accept both binary and textual
  operations, but it's R6RS support wraps these ports so that the
  resulting R6RS ports are not compatible with Racket's native port
  operations, but do provide the binary/textual disjointness.

These are the only implementations (besides Guile), that I'm familiar
with.  Ideally, Guile's R6RS support would provide real disjointness for
binary and textual ports -- I think the only artefact that hampers this
is that there's no way to distinguish Latin-1 encoded ports from "pure"
binary ports (as both have `port-encoding' being #f).

Regards, Rotty
-- 
Andreas Rottmann -- <http://rotty.yi.org/>



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-25 11:55     ` binary-port? Andreas Rottmann
@ 2011-04-25 14:08       ` Ludovic Courtès
  2011-04-25 14:20         ` binary-port? Andy Wingo
  2011-04-26  0:16         ` binary-port? Andreas Rottmann
  0 siblings, 2 replies; 10+ messages in thread
From: Ludovic Courtès @ 2011-04-25 14:08 UTC (permalink / raw)
  To: Andreas Rottmann; +Cc: guile-devel

Hi,

Andreas Rottmann <a.rottmann@gmx.at> writes:

> ludo@gnu.org (Ludovic Courtès) writes:

>>>> However, I’m wondering whether we should not just squarely do away with
>>>> the binary/textual distinction, and just write:
>>>>
>>>>   (define (binary-port? p) #t)
>>>>
>>>> What do people with experience with pure R6RS code think?  Is the
>>>> distinction actually used, and how?
>>>>
>>> I can only find one example in the code I wrote:
>>> `copy-port', which works (with the probably obvious semantics), on both
>>> binary and textual ports.  On Guile, when `binary-port?' would return #t
>>> for all ports, `copy-port' would break, losing the transcoding effect
>>> you'd get when you pass two textual ports of different encodings.
>>
>> Interesting.  Can you post a link to the code?
>>
> Sure, it's in `(spells ports)':
>
> https://github.com/rotty/spells/blob/master/spells/ports.sls

I see, thanks.

[...]

> So, my impression is that while `binary-port?' and `textual-port?' are
> not used widely, they do have their uses, and there is definitly code
> out there that relies on the binary/textual distinction.

OK.

> - Ikarus and Ypsilon definitly have disjoint ports.
>
> - Racket natively has ports that will accept both binary and textual
>   operations, but it's R6RS support wraps these ports so that the
>   resulting R6RS ports are not compatible with Racket's native port
>   operations, but do provide the binary/textual disjointness.

So Racket really has 3 disjoint port types, right?  That looks
inconvenient to me.

> These are the only implementations (besides Guile), that I'm familiar
> with.  Ideally, Guile's R6RS support would provide real disjointness for
> binary and textual ports -- I think the only artefact that hampers this
> is that there's no way to distinguish Latin-1 encoded ports from "pure"
> binary ports (as both have `port-encoding' being #f).

And beyond that, you can put-bytevector on any port, read-char on any
port, and so on.

I wouldn’t want the “native” port type to be disjoint from the R6RS port
types, notably because there’s no “native” equivalent to the R6RS binary
I/O API, and also because it would hamper composition of R6RS and
non-R6RS code.

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-25 14:08       ` binary-port? Ludovic Courtès
@ 2011-04-25 14:20         ` Andy Wingo
  2011-04-26  0:16         ` binary-port? Andreas Rottmann
  1 sibling, 0 replies; 10+ messages in thread
From: Andy Wingo @ 2011-04-25 14:20 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

On Mon 25 Apr 2011 16:08, ludo@gnu.org (Ludovic Courtès) writes:

> I wouldn’t want the “native” port type to be disjoint from the R6RS port
> types, notably because there’s no “native” equivalent to the R6RS binary
> I/O API, and also because it would hamper composition of R6RS and
> non-R6RS code.

There is (ice-9 binary-ports).  Of course that doesn't much help the
composition argument.

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-25 14:08       ` binary-port? Ludovic Courtès
  2011-04-25 14:20         ` binary-port? Andy Wingo
@ 2011-04-26  0:16         ` Andreas Rottmann
  2011-04-26 15:00           ` binary-port? Ludovic Courtès
  1 sibling, 1 reply; 10+ messages in thread
From: Andreas Rottmann @ 2011-04-26  0:16 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

ludo@gnu.org (Ludovic Courtès) writes:

> Hi,
>
> Andreas Rottmann <a.rottmann@gmx.at> writes:
>
>> - Ikarus and Ypsilon definitly have disjoint ports.
>>
>> - Racket natively has ports that will accept both binary and textual
>>   operations, but it's R6RS support wraps these ports so that the
>>   resulting R6RS ports are not compatible with Racket's native port
>>   operations, but do provide the binary/textual disjointness.
>
> So Racket really has 3 disjoint port types, right?  That looks
> inconvenient to me.
>
It is, at least if you don't deal with R6RS-mode code only.  It's a
similiar situation (although not as pervasively inconvinient) as the
mutable/immutable pair division.

>> These are the only implementations (besides Guile), that I'm familiar
>> with.  Ideally, Guile's R6RS support would provide real disjointness for
>> binary and textual ports -- I think the only artefact that hampers this
>> is that there's no way to distinguish Latin-1 encoded ports from "pure"
>> binary ports (as both have `port-encoding' being #f).
>
> And beyond that, you can put-bytevector on any port, read-char on any
> port, and so on.
>
> I wouldn’t want the “native” port type to be disjoint from the R6RS port
> types, notably because there’s no “native” equivalent to the R6RS binary
> I/O API, and also because it would hamper composition of R6RS and
> non-R6RS code.
>
Well, I'm not advocating making them disjoint in the sense that the
textual or binary operations are only possible on "matching" ports.
Allowing to mix binary and textual I/O on any port, is, IMHO, a fine and
reasonable implementation-specific extension that Guile provides.  What
I'm after is making `textual-port?' and `binary-port?' establish a
partition on the set of possible ports; i.e.

(textual-port? X) = (not (binary-port? X))

for any port X (or at least for any port obtainable via R6RS-specified
procedures).  For that to work, we somehow need to distinguish between
Latin-1 ports and "pure" binary ports.  Perhaps by adding a flag
indicating this to the port objects?  This flag would then be set by all
R6RS procedures specified to create binary ports, and would be checked
by `binary-port?' and `textual-port?'.  Additionally, we might want to
clear that flag when the port's encoding is changed to non-#f.  WDYT?

Regards, Rotty
-- 
Andreas Rottmann -- <http://rotty.yi.org/>



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: binary-port?
  2011-04-26  0:16         ` binary-port? Andreas Rottmann
@ 2011-04-26 15:00           ` Ludovic Courtès
  0 siblings, 0 replies; 10+ messages in thread
From: Ludovic Courtès @ 2011-04-26 15:00 UTC (permalink / raw)
  To: Andreas Rottmann; +Cc: guile-devel

Hi Andreas,

Andreas Rottmann <a.rottmann@gmx.at> writes:

> Well, I'm not advocating making them disjoint in the sense that the
> textual or binary operations are only possible on "matching" ports.
> Allowing to mix binary and textual I/O on any port, is, IMHO, a fine and
> reasonable implementation-specific extension that Guile provides.  What
> I'm after is making `textual-port?' and `binary-port?' establish a
> partition on the set of possible ports; i.e.
>
> (textual-port? X) = (not (binary-port? X))
>
> for any port X (or at least for any port obtainable via R6RS-specified
> procedures).  For that to work, we somehow need to distinguish between
> Latin-1 ports and "pure" binary ports.  Perhaps by adding a flag
> indicating this to the port objects?  This flag would then be set by all
> R6RS procedures specified to create binary ports, and would be checked
> by `binary-port?' and `textual-port?'.  Additionally, we might want to
> clear that flag when the port's encoding is changed to non-#f.  WDYT?

I think we could just as well change ‘textual-port?’ to

  (define (textual-port? p) (not (binary-port? p)))

So you would have the illusion of disjoint types, with the important
difference that:

  1. All I/O operations can be used on all ports.

  2. Using textual operations or ‘set-encoding!’ irreversibly makes a
     port pass ‘textual-port?’ if it didn’t already.

WDYT?

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-04-26 15:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-22 22:28 binary-port? Ludovic Courtès
2011-04-23  1:48 ` binary-port? Andreas Rottmann
2011-04-23 19:56   ` binary-port? Ludovic Courtès
2011-04-24  6:39     ` binary-port? Marco Maggi
2011-04-24 13:03       ` binary-port? Ludovic Courtès
2011-04-25 11:55     ` binary-port? Andreas Rottmann
2011-04-25 14:08       ` binary-port? Ludovic Courtès
2011-04-25 14:20         ` binary-port? Andy Wingo
2011-04-26  0:16         ` binary-port? Andreas Rottmann
2011-04-26 15:00           ` binary-port? Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).