Posted to tcl by aspect at Sat Jul 07 17:35:24 GMT 2018view pretty

namespace eval async {                                                                                                     
    proc read {chan {numChars ""}} {                                                                                       
        if {[chan configure $chan -blocking]} {                                                                            
            tailcall ::read $chan {*}$numChars                                                                             
        } else {                                                                                                           
            set was [chan event $chan readable]                                                                            
            chan event $chan readable [list [info coroutine]]                                                              
            finally [list chan event $chan readable $was]                                                                  
            if {$numChars eq ""} {                                                                                         
                yield                                                                                                      
                return [::read $chan]                                                                                      
            } else {                                                                                                       
                set data ""                                                                                                
                while {[string length $data] < $numChars} {                                                                
                    yield                                                                                                  
                    append data [::read $chan $numChars]                                                                   
                    if {[eof $chan]} break                                                                                 
                }                                                                                                          
                return $data                                                                                               
            }                                                                                                              
        }                                                                                                                  
    }                                                                                                                      
}