Here's my latest masterpiece :) /////////////// var a = 9,7,6,22,1;
proc p (inp:ischannel[opt[int]]) { again:> var x = read inp; match x with | Some ?i => println$ i; goto again; | None => println$ "END"; endmatch; } #(a.iterator.source |-> Spipe::sort[int] |-> p); #(a.isrc[int] |-> Spipe::sort[int] |-> p); #(a >-> Spipe::sort[int] |-> p); /////////////// What this does: the three pipelines all do the same thing. We convert an array into a stream by applying an iterator, and the stream into a source device by applying the source method. Then we feed the stream into the sort device, and feed its output into our printing device. [Note how, unfortunately, we have to specify the type of the sort] Unfortunately the pipe operator |-> cannot be overloaded to accept a data structure in the left component, so i had to add a new symbol >-> for that. It basically means "feed the values of this data structure down the pipeline". The steps to make this work are shown: we start with a streamable data structure and apply an iterator to it to get a generator. Then we convert the generator to an output channel driver device or source. [Our print device is a sink] Then we use one of the pipe overloads to connect that source to the sort transducer to make a new source, and then the other overload to connect that source to our sink to create a closed pipeline. With a bit more work, I expect to do the magic for sinks. So basically you would be able to take an array, sort it, and feed the result into a darray. This is easy to do now: just modify the print sink procedure to store the results in a darray. To make that any darray, just pass a pointer. But you have to write the code. You cannot just put a darray at the end of the pipeline and have it accumulate results by magic. We want to do that in the following sense: what we have done so far is provide an active device programming model which is polyadic: we have source and transducers in the model in the abstract. This means we have the equivalent of STL input iterators. Now we need output iterators. Unlike STL, our model is intensionally polyadic which means for a particular data type you can make binary libraries of reusable components. We can get intensional polymorphism too, by boxing, which would allow universal binary devices. Active programming with devices subsumes all other models. It is superior to function libraries (master/slave sucks). It is superior to Reactive programming (master/slave SUCKS TOTALLY). It is also superior to STL's iterator model (slave/master). In function libraries the client of the library is a master. But the author of the library needs to be a genius, so as to maintain any state required between calls. This is easy enough for very simple models, but even for Finite State Machines it rapidly becomes untenable. Just try parsing a string for a regular expression using a hand constructed finite state machine to see what I mean! [My flx2html tool does this and its a nightmare!] To do this for a recursive machine is even harder: you need to implement your own stack. For a general problem it is utterly intractable. Unless you work in a rigid problem class for which you have a generator tool, and such tools never support composition well. STL is better than your average library because it provides control inversion, which makes client programming via iterators easy, but the iterator developer is still screwed. [Just try writing an iterator that visits a tree data structure!] Felix device model is master/master. Each device is a master. Both the client of the components and the developer of the components write ACTIVE CODE. It's well known re-active code is intractable. Every "operating system" provides control inversion for reading and writing files. If you had to control invert your program to become a callback of the file driver, you'd be totally screwed. OS do control inversion by stack swapping. This is also how Felix does it -- but it only swaps the spaghetti stack procedures use, not the machine stack functions use. That constraint is ugly but its a result of developing with a C/C++ target, and using hardware designed to target that same market. Felix is an experimental language: we're using cooperating sequential processes with channels as a core construct. It remains to be seen how effective this technology actually is. The raw primitives are hard to use. Pipelines show what you can do with them. For general programming we probably need bidirectional pipes, and indeed feedback .. i.e. the ability to connect general circuits together. This is non-trivial: arbitrary connections don't work: you have to design the flow. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language