rlewis wrote:
> object oriented
> structured
> functional
I think the main bonus of FBP compared to conventional sub-routines
and OO programming is that each FBP proc is sort of alive and independent,
with its own processing thread, and they can be connected very flexibly.
Some things I learned, and want to remember and use with FBP,
from other programming styles:
Functional:
- if components are simple and well-defined (not bizarrely eccentric with
side-effects), then the whole system will make more sense, be less buggy
and more 'provable'.
- be consistent... don't treat 0 or 1 as a special case, especially when
handling arguments (or array ports) e.g. sum() = 0, prod() = 1.
UNIX gets this wildly wrong in my opinion, most tools behave differently
if you give them 0 arguments. E.g. plain `cat` should concatenate 0 files,
giving nothing, but in UNIX it copies stdin to stdout! grep behaves in
three different ways for 0, 1 or many arguments. These 'features' can be
good for interactive use, but they make trouble when you try to build
programs out of them.
- lambda is an important concept! in FBP, defining a new composite component
should be nice and clean, like using lambda in a functional language.
Imperative:
- It should be simple to draw shapes and circles on your computer screen,
or play sounds and make music! no harder than it was with BASIC or LOGO.
e.g. MOVE 0, 0; DRAW 100, 100; This can be achieved with modern
languages too, but usually isn't. Old-style GL is not too bad.
In FBP we might have IPs describing shapes, and others describing
vertices, etc. I'm not too sure, but I do want to do graphics and GUIs
with FBP.
Subroutines should have access to context varibles without having to pass
lots of parameters. In OO, methods can access members, they are like
global variables but just within the object.
Structured:
- top-down: divide and conquer! works very well
- bottom-up: build a good toolkit of reusable components, as good as possible
- FBP is a better foundation for structured programming.
- GOTO is very useful. Don't abuse it, don't try to get rid of it!
UNIX:
- Keep it simple! components should do one thing well.
Unfortunately, BSD and GNU have strayed very far from this!
- Processes communicating over pipes, a simple sort of FBP
- UNIX has many useful tools such as comm, grep, sort, awk,
and we can get lots of ideas for useful FBP components from UNIX tools.
I've built a whole lot of small-scale tools too, some of which are useful
or unusual, and could be re-expressed as FBP components.
- The Makefile is a useful approach for data processing also,
it's a bit like FBP but with files instead of queues, each data point is an
infinite queue. Each proc processes all the data before going on to the
next proc although independent procs can run in parallel. If a make job
fails half way, producing wrong data, you can just delete the data that was
wrong, and run it again to continue from that point. There's no need to
run costly earlier steps again. This can speed up development and
debugging compared to conventional progamming or FBP with queues.
So I suggest in a FBP system, there could be a switch for debugging /
development, to enable infinite queues and continuing from a point of
failure. Once all the procs are working, we can switch from files to
queues, lowering latency and increasing parallelism. Or we can have an
option to do it both ways - keep all the intermediate data at each stage,
while feeding it on to the next process as it arrives - a sort of logging
pipe / stream. This could use lots of storage, but it's useful to have a
complete record of each stream at every point. If we save some sort of
serial numbers / timestamps, we could literally rewind and fast-forward
to see where things went wrong, and restart processing from any point
after fixing the problem. Maybe I'm getting carried away here...!
but a time-machine debugger would be incredibly useful I think,
and it would be much easier to implement that for FBP.
Relational:
- Like functional, but components can operate in several directions:
a 'splitter' op that splits lines into words can act as a 'joiner'
op if you run it in reverse. Add and Sub are the same op, just working
in different directions. The reduces the number of basic components,
and composite networks can perform different functions, depending what data
is available and what data is needed.
- A program is declarative, like a big maths equation. We can have rules
to manipulate or simplify it, a bit like a compiler's optimizer, or what
mathematica does with its symbolic algebra.
We can tell the computer what we know, and what we want to be done, and if
we gave it enough information, the computer can figure out exactly how to
do it. (but, we can still specify exactly how to do it, if the damn fool
computer is likely to get it wrong!).
- With FBP, we can think of procs as expressing relationships between
streams, this is like Haskell and the 'lazy functional' languages also,
where you can operate on infinite streams, which are computed only as
needed. I remember Paul mentioned a similar approach in the FBP book.
I want to use a declarative foundation for FBP, it is very good especially
at the low level, but we need streams, IO, and user-interfaces at the
higher level.
Ok, now I'd better stop raving and go and do some work!
Sam
> Instead of the mapping using BATs I just described, you can let a
> function (be it a C, C++, C#, or other function) be the PU. The body
> of the function being in a precompiled and included DLL makes the
> function (the PU) a black box. It is a black box because we cannot
> inspect the source code of the PU. Therefore, we are forced to rely on
> a simple description of the function PU's use.
Unfortunately, there are plenty of languages that can't deliver object
code in the form of DLLs.
> The Kernel accelerates my connecting my PUs and passing my IPs.
> The Kernel allows me to mix and match PUs which may be written by
> different programmers, each programmer writing in the programming
> language of his/her choice.
Unfortunately not; you'll be limited to compiled languages that have
implementations capable of delivering shared libraries that can work
without a fixed runtime.
--
John Cowan co...@ccil.org http://ccil.org/~cowan
Promises become binding when there is a meeting of the minds and consideration
is exchanged. So it was at King's Bench in common law England; so it was
under the common law in the American colonies; so it was through more than
two centuries of jurisprudence in this country; and so it is today.
--Specht v. Netscape
> UNIX gets this wildly wrong in my opinion, most tools behave
> differently if you give them 0 arguments. E.g. plain `cat` should
> concatenate 0 files, giving nothing, but in UNIX it copies stdin
> to stdout! grep behaves in three different ways for 0, 1 or many
> arguments. These 'features' can be good for interactive use, but
> they make trouble when you try to build programs out of them.
It's fairly easy to cleverly override this, however, using bash aliases.
> - Processes communicating over pipes, a simple sort of FBP
Pipes are fully general; they are not restricted to pipelines.
> - The Makefile is a useful approach for data processing also, it's
> a bit like FBP but with files instead of queues, each data point is
> an infinite queue. Each proc processes all the data before going
> on to the next proc although independent procs can run in parallel.
> If a make job fails half way, producing wrong data, you can just
> delete the data that was wrong, and run it again to continue from
> that point. There's no need to run costly earlier steps again.
> This can speed up development and debugging compared to conventional
> progamming or FBP with queues.
It would be very nice if DrawFBP had a mode to output such a Makefile,
inventing the temp file names as it goes.
> Relational:
>
> - Like functional, but components can operate in several directions:
> a 'splitter' op that splits lines into words can act as a 'joiner'
> op if you run it in reverse. Add and Sub are the same op, just
> working in different directions. The reduces the number of basic
> components, and composite networks can perform different functions,
> depending what data is available and what data is needed.
This sounds more like Prolog.
--
Cash registers don't really add and subtract; John Cowan
they only grind their gears. co...@ccil.org
But then they don't really grind their gears, either;
they only obey the laws of physics. --Unknown
> However, I believe Google is not able to abandon the old format for good
> reason. And the reason has nothing to do with accommodating people who
> prefer the old format.
The usual progression (with Gmail, for example) is "preview the new version",
"switch to the new version", "you have been switched to the new version
(click here to switch back)", and finally "the old version is unavailable."
--
Deshil Holles eamus. Deshil Holles eamus. Deshil Holles eamus.
Send us, bright one, light one, Horhorn, quickening, and wombfruit. (3x)
Hoopsa, boyaboy, hoopsa! Hoopsa, boyaboy, hoopsa! Hoopsa, boyaboy, hoopsa!
--Joyce, Ulysses, "Oxen of the Sun" co...@ccil.org
> John, if you send me the makefile format, and some examples, I would
> be happy to add a generator to DrawFBP. From the description, though,
> it sounds as if this is something like IBM mainframe JCL - i.e. every
> connection is "infinite", and you can only go left-to-right, i.e. no
> loop topologies. IMO this is not enough to do full FBP, although you
> can certainly do a subset of it. Over to you, John!
There are three limitations: no loops, all connections are infinite,
and components can have only one output port. However, multiple input
ports are fine. Each connection will have to be assigned a corresponding
filename, which can be derived from the component's name (not its
type, since there may be more than one component of a given type).
Then generate pairs of lines like this:
output-connection-name input-connection-names:
component-type input-connection-names > output-connection-name
Note that the indentation of the second line must be with a \t character;
spaces will not work. The order of line-pairs is not important,
except that the final output component should appear first. The order
of input-connection-names must be determined by the component type: a
simple approach would be to generate them in alphabetical order by port
name (the port name is not meaningful otherwise). The default name for
the generated file should be "Makefile".
So given a simple pipeline like this:
a | b | c
the corresponding Makefile would be:
c-output b-output:
c b-output > c-output
b-output a-output:
b a-output > b-output
a-output:
a a-input-1 > a-output
Typing "make" will then try to generate c-output, note that it depends
on b-output, note that b-output depends on a-output, run the a command,
run the b command, and run the c command. However, if a-input-1 does not
exist, then the process will fail.
That's the general idea, anyway. It may need some tweaking, particularly
when dealing with overall inputs and outputs.
--
In politics, obedience and support John Cowan <co...@ccil.org>
are the same thing. --Hannah Arendt http://www.ccil.org/~cowan
rlewis wrote:
> I think a very positive aspect of FBP is that it doesn't need to be
> expressed in source code at all.
>
> Even so, I feel I need some kind of mapping of FBP diagram to source
> code.
Most languages are parsed from text to give a parse-tree or graph.
Graphs are more expressive than text, and can closely represent meaning.
Text is often more concise, for simple phrases.
Graphs can be rendered into text (to store or communicate them),
e.g. http://en.wikipedia.org/wiki/Trivial_Graph_Format
We can make graph editors, and textual language front ends.
There's no dilemma - we can do it both ways.
Fred might write x = 2y - z, then Jane could edit the
equation as a graph, and Joe might export to 'mathml' or TeX,
then edit it with a tool. File format conversion can be automatic
and transparent.
The underlying graph for that equation looks like this, and closely
represents the meaning. I did not draw any nodes or arcs in ascii!
2
x + * y
z
There's no need for subtract or divide symbols in a relational graph,
and there is no bias toward 'x' as the special 'left hand side'
variable.
We can convert graphs to textual 'back end' languages,
such as Java, C or assembly, or run them directly.
Sam