TIP #208: Add a 'chan' Command 
Author Message
 TIP #208: Add a 'chan' Command

 TIP #208: ADD A 'CHAN' COMMAND
================================
 Version:      $Revision: 1.1 $
 Author:       Jeff Hobbs <jeffh_at_activestate.com>
 State:        Draft
 Type:         Project
 Tcl-Version:  8.5
 Vote:         Pending
 Created:      Friday, 02 July 2004
 URL:           http://www.*-*-*.com/
 WebEdit:       http://www.*-*-*.com/
 Post-History:

-------------------------------------------------------------------------

 ABSTRACT
==========

 This TIP proposes adding a *chan* command that would serve as a
 top-level command container for all the related channel commands that
 have proliferated over time, as well as future new channel-based
 commands.

 RATIONALE
===========

 Tcl's channel system has evolved over time from a thin layer on top of
 the OS into a very complex, multi-platform system. There are numerous
 top-level commands for channels already, with more being proposed for
 Tcl 8.5. This command would centralize them, making it easier for new
 users to see all the related channel commands, much as *string* or
 *file* operate today.

 The name *chan* was chosen over /channel/ because it is a clearly
 recognizable abbreviation, much like /eval/ vs. /evaluate/ and /interp/
 vs /interpreter/.

 SPECIFICATION
===============

 A new command *chan* will be added with the following syntax:

         chan blocked    ; # fblocked
         chan close      ; # close
         chan configure  ; # fconfigure
         chan copy       ; # fcopy
         chan eof        ; # eof
         chan event      ; # fileevent
         chan flush      ; # flush
         chan gets       ; # gets
         chan puts       ; # puts
         chan read       ; # read
         chan seek       ; # seek
         chan tell       ; # tell

 Each represents the existing command that is commented. The arguments
 to each would remain what the current command takes.

 Note that *open* is not included above, as it is a channel creation
 function, just like *socket*.

 FUTURE POSSIBILITIES FOR EXTENDING THE 'CHAN' COMMAND
-------------------------------------------------------

 I would also recommend that [TIP #206] be integrated as *chan
 truncate*. Further TIPs may also recommend subcommands such as *chan
 transform*, *chan stack* and *chan unstack* (exposing the channel
 stacking subsystem available in the C API), among other possibilities.

 DEPRECATION OF EXISTING COMMANDS
----------------------------------

 In addition, I would recommend only the following commands be marked
 deprecated so as to help systematize their names better:

         fblocked
         fconfigure
         fcopy
         fileevent

 REFERENCE IMPLEMENTATION
==========================

 The implementation of this TIP is really a simple command that makes
 use of the existing command implementations. It could be a namespace
 ensemble or a C-based command.

 COPYRIGHT
===========

 This document has been placed in the public domain.  

-------------------------------------------------------------------------

 TIP AutoGenerator - written by Donal K. Fellows


  Announcements archived at http://www.*-*-*.com/

  Tcl/Tk at http://www.*-*-*.com/ ]]



Wed, 03 Jan 2007 01:25:29 GMT  
 TIP #208: Add a 'chan' Command

Quote:

>  TIP #208: ADD A 'CHAN' COMMAND
> ================================

[snip]

I'm a little surprised that there hasn't been any discussion of this TIP.
But let me chime in with my concurrence with the TIP. The continuing
re-organization of related commands into ensembles is welcome.

Andrew



Sun, 07 Jan 2007 12:21:11 GMT  
 TIP #208: Add a 'chan' Command
I suggest to make channel act like object commands. It is more convinient, IMHO.
Look at my demo below:

#!/usr/bin/tclsh

# another variant of TIP #208: ADD A 'CHAN' COMMAND

package provide tip208

rename unknown tcl::unknown

namespace eval tip208 {

        set oldCommands {
                fblocked        close           fconfigure      fcopy
                eof             fileevent       flush           gets
                puts            read            seek            tell
        }

        foreach cmd $tip208::oldCommands {
                rename ::$cmd ::tcl::${cmd}
        }

        interp alias {} ::puts {} ::tcl::puts
        interp alias {} ::gets {} ::tcl::gets

Quote:
}

proc unknown {cmd args} {

        set channel $cmd
        set command [lindex $args 0]
        set newArgs [lrange $args 1 end]

        if {[lsearch [file channels] $channel] != -1 &&
            [lsearch $::tip208::oldCommands $command] != -1} {
                eval tcl::${command} $channel $newArgs
        } else {
                eval ::tcl::unknown $cmd $args
        }

Quote:
}

### end of package

if {[info ex argv0] && [file tail [info script]] == [file tail $argv0]} {
        puts "Begin test."
        puts "Available commands: [lsort [info commands]]"
        puts "Your /etc/passswd:"
        set passwd [open /etc/passwd r]
        while {![$passwd eof]} {
                stdout puts [$passwd gets]
        }
        stdout puts "Size of /etc/passwd: [$passwd tell]"
        $passwd close
        puts "Press Enter..."
        gets stdin

Quote:
}



Sun, 07 Jan 2007 12:34:49 GMT  
 TIP #208: Add a 'chan' Command

Quote:

> I suggest to make channel act like object commands. It is more convinient, IMHO.

Basically its just a question of style, there is no real user visible
difference between:

close $chan
$chan close

Its a cultural difference like the grammar structure in natural
languages, you can have subject predicate object (SPO) or predicate
subject object (PSO), or any other combination and all versions exist in
natural languages.

If we use a thing like:
chan close $chan

it is directly clear what happens, while it isn't if using an object style:

$xyz close

So you have to lookup what is stored in xyz, while the chan close would
just throw an error if it isn't whats expected.

You could argue that it is a good thing, as one can use common subsets
of subcommands, but at least I find myself always looking through
documentation of object interfaces to find out "what methods does this
object have", while i quite easily graps what objects i can pass to a
command i know of.

If Tcl adopts OO as a basic language principle i would say it would be
sensible to do everything OO, but as you demonstrated with your example
implementation you are free to do so right now, if it fits your mindset
without major problems.

Michael



Sun, 07 Jan 2007 19:36:16 GMT  
 TIP #208: Add a 'chan' Command

Quote:


> > I suggest to make channel act like object commands. It is more convinient, IMHO.

> Basically its just a question of style, there is no real user visible
> difference between:

> close $chan
> $chan close

I think that new C API (I mean Object commands) suggest to use
objects, so I assume that Tcl will use this way in near future. I am
not an opponent of procedural or functional style.

Quote:
> Its a cultural difference like the grammar structure in natural
> languages, you can have subject predicate object (SPO) or predicate
> subject object (PSO), or any other combination and all versions exist in
> natural languages.

> If we use a thing like:
> chan close $chan

> it is directly clear what happens, while it isn't if using an object style:

> $xyz close

> So you have to lookup what is stored in xyz, while the chan close would
> just throw an error if it isn't whats expected.

> You could argue that it is a good thing, as one can use common subsets
> of subcommands, but at least I find myself always looking through
> documentation of object interfaces to find out "what methods does this
> object have", while i quite easily graps what objects i can pass to a
> command i know of.

I try to unify interface of different parts of Tcl: Tk use object
commands, Tcl use procedural style. It is not a big problem, but not
very convinient.

You use documentation, because Tcl has not enough introspection
capabilities. I mean this no way (IMHO, may be I forget?) to ask
command about subcommands or subcommand about options(required or
optional). Example from Ruby:

STDOUT.methods

return method of object STDOUT. If you would have such possibility you
would use documentation rare. I would like to have such feature in
Tcl. But it is a subject of another TIP.

- Show quoted text -

Quote:

> If Tcl adopts OO as a basic language principle i would say it would be
> sensible to do everything OO, but as you demonstrated with your example
> implementation you are free to do so right now, if it fits your mindset
> without major problems.

> Michael



Mon, 08 Jan 2007 12:49:14 GMT  
 TIP #208: Add a 'chan' Command
well, "not enough introspection" ...
Here are two short studies for implementing the discussed
features in xotcl.

---

study 1: as specified in the TIP (can be easily extended to
the full set of subcommands):

  Object chan
  chan proc unknown {m args} {
    chan puts "unknown chan method '$m $args' called \
        defined: [lsort [my info commands]]"
  }
  rename fblocked   ::chan::blocked
  rename close      ::chan::close
  rename fconfigure ::chan::configure
  rename open       ::chan::open
  rename puts       ::chan::puts

  set c [chan open /tmp/junk w]
  chan puts $c "hello"
  chan close $c
  chan xxx

this will produce the following output:
   unknown chan method 'xxx ' called
        defined: blocked close configure open puts unknown
... and of course the file in /tmp

Note, that one can define in a incremental step new
subcommands (in tcl or c) which can be
registered/redefined/deregistered dynamically
for the object "chan", the unknown will return the correct
set of methods.

---

study 2: define a class for channels, where every channel
is an instance; this is the "OO manner", where open creates
a stream and close destroys it.

  Class chan -parameter stream -array set map {
    blocked fblocked
    configure fconfigure
    puts puts
  }
  # create stream and object
  chan proc open args {
    set stream [eval open $args]
    my create $stream -stream $stream  ;# make an object
  }
  # close stream and destroy object
  chan instproc close {} {
    close [my stream]
    [self] destroy
  }
  # handle other subcommands (methods) via unknown
  chan instproc unknown {m args} {
    [self class] instvar map
    if {[info exists map($m)]} {
      eval $map($m) [my stream] $args
    } else {
      set valid [lsort [concat \
                     [chan info instprocs] \
                     [array names map]]]
      stderr puts "unknown chan method '$m' $args called;
        defined: $valid"
    }
  }
  chan create stdout -stream stdout
  chan create stderr -stream stderr

  set c [chan open /tmp/junk w]
  $c puts "hello"
  $c xxx
  stderr puts "currently open streams: [chan info instances]"
  $c close
  stderr puts "currently open streams: [chan info instances]"

The output here is:
  unknown chan method 'xxx'  called;
        defined: blocked close configure puts unknown
  currently open streams: ::stderr ::stdout ::file5
  currently open streams: ::stderr ::stdout

as you see, you get introspection about the current open
streams as well. xotcl allows you to define per object
methods (procs) such that certain special streams can
have special handlings. you get the whole set of methods
via e.g. [stderr info methods]. then you can have per-class
and per-object mixins, such you can do things like tee-streams
quite easy.

Concerning the implementation: Certainly the definition
of the methods can be done as well  in C, such that the
overhead can be quite low. Future versions of xotcl
will have more powerful forwarding capabilities such that the
second verison can be made simpler as well...

This shows that defining a full-fledged tcl in oo style
is not so complicated and can co-exist with function
based style (e.g. for using "legacy" components)

-gustaf



Mon, 15 Jan 2007 16:23:54 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. TIP #49: I/O Subsystem: Add API Tcl_OutputBuffered(chan)

2. TIP #210: Add 'tempname' to file

3. TIP #239: Enhance the 'load' Command

4. TIP #53: Addition of 'assert' Command

5. Wanted: Hints'n'Tips'n'Bits'n'Bobs

6. TIP #39: Add New Standard Tk Option: -component

7. TIP #19: Add a Text Changed Flag to Tk's Text Widget

8. TIP #44: Move Tk's Private Commands and Variables into ::tk Namespace

9. TIP #210: Add 'tempname' Subcommand to 'file'

10. TIP #188: Add 'string is wide' to the 'string is' Subcommand

11. TIP #80: Additional Options for 'lsearch'

12. TIP #214: Add New Object Introspection Command

 

 
Powered by phpBB® Forum Software