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

Reply via email to