[moved old docs to libpf_stuff repo
doelie@zzz.kotnet.org**20060302164846] {
hunk ./doc/old/devdoc.html 1
-
-
-
- PDP Developer Documentation
-
-
-
- PDP Developer Documentation
-
- Introduction
-
- There is not yet much developer information, partly because pdp is not that big and since the goals are
- not completely clear yet, a lot will probably change on the inside in the future. I believe it is
- not too hard to figure out how it works, once you get started somewhere. This document is a minimalistic
- attempt to provide that starting point. For full prototypes see the header files. I suggest you have a look at the pdp_base base class, and some simple
- modules: pdp_add, pdp_noise and pdp_gain for examples.
-
-
PDP architecture
- Architecture is a big word, but pdp is organized as modules. A packet pool module (a reuse pool memory manager),
- a packet class, a processing queue module, a high level type conversion module, an image packet class, and some
- low level modules for image type conversion, image resampling and all sorts of other image processing. Besides that
- there are 2 extension libraries: pdp_scaf, a cellular automata extension and pdp_opengl, a 3d rendering extension.
- These are separate because of portability issues. The different pdp_* externs in the main pdp library use the
- core modules' functionality to minimize code duplication. I'm relatively happy with how it fits together,
- but some things need to change for future plans. Most objects are written in the object oriented c style of pd.
- To prevent namespace conflicts, (almost) all routines start with the pdp_ prefix. The second name is the name of the
- object or module they belong to. The first argument is always a pointer to an object or an integer (for packets).
-
-
-
PD ties
- PDP is written as an extension for PD. One of the goals of pdp is to evolve to a separate library that can
- be reused in other software. The architecture will be split into two parts. A pd-independent part (the packet classes,
- the packet pool, the type conversion system and the forth system) and a part with pd specific stuff (the process queue and interfaces to the
- pd system like the base classes and the pd communication protocol). In order to do this the packet class will probably
- evolve to a proper object model, supporting run time attribute binding (inspired by the python object model).
-
-
There are some things that put a stamp on the current pdp design. Most importantly pd's processor object model and
- communication protocol. (i.e. the fact that pd only supports unidirectional messaging creates the awkward concept
- of a "passing packet" to eliminate excessive data copying.)
-
-
In pd, the pdp messaging protocol is implemented as pd messages. The protocol is however 3 phase.
- With a read only register phase, a read/write register phase and a process phase. This functionality
- is part of the base class or the forth processor object. The dpd protocol is entirely different,
- and is used in the opengl library. It is
- not based on parallel dataflow but serial context passing.
-
-
Packets
- PDP introduces a new atom: the data packet. This can contain all kinds of data. Images (16bit/8bit), cellular
- automata (1bit), matrices (real/complex float/double), opengl textures and 3d rendering contexts. Packets
- are stored in a pool to ensure fast reuse, and to enable sharing. The paradigm is centered around a
- combination of an object oriented approach and a dataflow approach.
-
The methods operating on packets
- (pdp_packet_*) are mainly for administrative purposes: memory management (construction, registering, copying)
- and getting or setting info.
-
All processing is done in the pd modules. Processors can be defined using
- the forth scripting language, but this is still experimental. The forth system can be accessed
- from the guile library.
-
There is a central mechanism for packet type conversion. This is to facilitate the combination of different
- media types. Whenever a packet class is constructed (i.e. in an extension library), a number of conversion
- routines should be defined to convert the added type to one or some of the main pdp types.
-
-
-
-
-
-
-
PDP API Overview
-
- The pdp public api contains only a single class: the packet. (The internal api has more classes, that can be used
- too if necessary, but i won't document them.) A packet is a class in pdp. The table below lists the supported methods.
- The first argument of a call is a packet id.
-
-
- | pdp_packet_*
- |
|---|
| new | construct a raw packet (depreciated)
- |
| new_* | construct packet of specific type/subtype/...
- |
| mark_unused | release
- |
| mark_passing | conditional release (release on first copy ro/rw)
- |
| copy_ro | readonly (shared) copy
- |
| copy_rw | private copy
- |
| clone_rw | private copy (copies only meta data, not the content)
- |
| header | get the raw header (t_pdp *)
- |
| data | get the raw data (void *)
- |
| pass_if_valid | send a packet to pd outlet, if it is valid, and mark unused
- |
| replace_if_valid | delete packet and replace with new one, if new is valid
- |
| copy_ro_or_drop | copy readonly, or don't copy if dest slot is full + send drop notify
- |
| copy_rw_or_drop | same, but private copy
- |
| get_description | retrieve type info
- |
| convert_ro | same as copy_ro, but with an automatic conversion matching a type template
- |
| convert_rw | same as convert_ro, but producing a private copy
- |
-
-
- The pool object methods. All the packets are stored in a central packet pool.
-
-
- | pdp_pool_*
- |
|---|
| collect_garbage | manually free all unused resources in packet pool
- |
-
- The process queue object methods. PDP supports a separate processing thread.
-
-
- | pdp_queue_*
- |
|---|
| add | add a process method + callback
- |
| finish | wait until a specific task is done
- |
| wait | wait until processing queue is done
- |
-
- The control methods. General pdp control messages.
-
-
- | pdp_control_*
- |
|---|
| notify_drop | notify that a packet has been dropped
- |
-
- The type mediator methods.
-
- | pdp_type_*
- |
|---|
| description_match | check if two type templates match
- |
| register_conversion | register a type conversion program
-
-
- |
-
-
- NOTE: it is advised to derive your module from the pdp base class defined in pdp_base.h
- instead of communicating directly with the pdp core
-
-
-
-
pdp_base class
- If you want to write a pdp extern, you can derive it from the pdp_base class, instead of t_object.
- This class abstracts a lot of the hassle of writing ordinary (inplace) packet processors. The base
- allows you to register process callbacks. There are 3 kinds of callbacks: preproc, process and postproc.
- The preproc method is called inside the pd thread. This can be used to setup some things that can only
- be done inside the pd thread. The process method should do most of the work, and is called from the
- pdp processing thread if it is enabled, after the preproc method is finished. You can't use most
- of pd's calls in this method. The postproc method is called
- from the pd thread after the process method is finished, and can be used to send data to pd outlets. Simple
- packet processors only need the process method (packet input/output is handled by the pdp_base class).
-
- pdp_imageproc_* modules
- Most of the image processing code is organized as planar 16 bit signed processors.
- This is crude and oversimplified, but it helps to keep the code size small and fast
- at the same time (platform dependent assembly code is reduced to a bare minimum). These
- routines can be used to build higher level image processing objects that are more (cache)
- efficient than an abstraction using separate pdp modules. If you plan to write your own image
- processing routines, you can use the pdp_imageproc_dispatch_ routine to support all 16bit image
- types at once (greyscale, subsampled YCrCb, multichannel planar). This requires you write the
- image processing routine as a planar (greyscale) processor using the pdp_imageproc_
- interface. (see pdp_imageproc.h)
-
- pdp_llconv call
- Low level image conversion routines. (operating on raw data buffers). You probably won't need this,
- since the high level type conversion (pdp_packet_convert_ro/rw) covers most of its functionality.
-
-
-
-
- Tom Schouten
-
-
-Last modified: Fri Sep 19 04:52:12 CEST 2003
-
-
-
rmfile ./doc/old/devdoc.html
hunk ./doc/old/layers.txt 1
-pdp 0.13 design layers + components
------------------------------------
-
-from version 0.13 onwards, pdp is no longer just a pd plugin also
-an embeddable unix library (libpdp) and commind line interpreter (pf).
-this documents is an attempt to describe the design layers.
-
-A. PD INTERFACE
----------------
-
-on the top level, libpdp is interfaced to pd using a glue layer which
-consists of
-
-1. pdp protocol for pd
-2. process queue
-3. base classes for pdp/dpd
-4. some small utility pd objects
-5. pf for pd
-
-
-1. is the same as previous versions to ensure backwards compatibility in
-pd with previous pdp modules and extensions that are written as pd
-externs or external libs. this includes parts of pdp that are not yet
-migrated to libpdp (some of them are very pd specific and will not be
-moved to libpdp), and pidip. if you intend to write new modules, it is
-encouraged to use the new forth based api, so your code can be part of
-libpdp to use it in other image processing applications. for an example
-of how to use this api, have a look at the pidip source code.
-
-2. is considered a pd part. it implements multithreading of pdp inside
-pd. multithreading is considered a host interface part, since it usually
-requires special code. this is not tested with 0.13.x
-
-3. the base classes (pd objects) for pdp image processing remain part of
-the pd<->pdp layer. the reason is the same as 1. a lot of the original
-pd style pdp is written as subclasses of the pdp_base, pdp_image_base,
-dpd_base and pdp_3dp_base classes. this is depreciated and only there
-to support my old code. this part of the api is not documented.
-
-4. is small enough to be ignored here. it is there to support some
-pdp abstractions.
-
-5. is the main link between the new libpdp (pf) and pd. it is used to
-instantiate pdp processors in pd which are written in the packet forth.
-i.e. to create a mixer, you instantiate a [pf mix] object, which would
-be similar to the previous [pdp_mix] object. each [pf] object creates
-a small forth environment, which is initialized by calling a forth init
-method. [pf mix] would call the forth word load-pd-mix to create the local
-environment for the mix object.
-
-
-
-B. LIBPDP SYSTEM CODE
----------------------
-
-1. basic building blocks
-2. packet management
-3. packet forth
-4. additional libraries
-
-
-1. pdp makes intensive use of symbols and lists (trees, stacks, queues).
-pdp's namespace is built on the symbol implementation. a lot of other
-code uses the list object, including the forth, which is not built on
-arrays but on lists and pdp's basic atoms.
-
-2. the pdp packet model is very simple. basicly nothing more than
-constructors (new, copy, clone), destructors (mark_unused (for reuse
-later), delete). there is no real object model for processors. this is a
-conscious decision to keep the language model close to a functional
-programming language.
-
-3. All of pdp is glued together with a scripting language called packet
-forth. This is a "high level" forth dialect that can operate on floats,
-ints, symbols, lists, trees and packets. It is a "fool proof" forth,
-which is polymorphic and relatively robust to user errors (read: it
-should not crash or cause memory leaks when experimenting). It is
-intended to serve as a packet level glue language, so it is not very
-efficient for scalar code. This is usually not a problem, since packet
-operations (esp. image processing) are much more expensive than a this
-thin layer of glue connecting them.
-
-All packet operations can be accessed in the forth. If you've ever
-worked with HP's RPN calculators, you can use packet forth. The basic
-idea is to write objects in packet forth that can be used in pd or in
-other image processing applications. For more information on packet
-forth, see the code (pdp_forth.h, pdp_forth.c and words.def)
-
-pdp processor objects can be implemented as packet forth programs.
-see the RAMBLINGS.txt file for more information on the 'abstract
-objects vs. local dictionaries' issue.
-
-4. This contains code to glue pf to all kinds of operating system
-services or services provided by other libraries to packet forth
-in the form of forth words. Dependency decoupling is ensured by a
-module system. The core pdp library depends only on libc, libm,
-libdl and libpthread.
-
-
-
-C. LOW LEVEL PROCESSING CODE
-----------------------------
-
-Except for some basic conversion code and some snippets that
-did not find a proper home, all data processing code that needs
-to be fast is implemented using some external, optimized code
-libraries, leaving the integration to pf.
-
-C.1 IMAGE PROESSING: LIBTILE
-
-Libtile's purpose of being is the solution of 3 problems:
-* image processing code factoring
-* quasi optimal processor pipeline & instruction usage
-* locality of reference for maximum cache performance.
-
-Currently only the first bullet is used in libpdp. Once the libtile
-compiler is ready, there will be a way to import fast libtile image
-processing programs as processing words.
-
-C.2: MATRIX PROCESSING: LIBGSL
-
-All matrix processing packet forth words are (will be) basicly wrappers
-around gsl library calls, which uses cblas as it's matrix processing core.
-Very straightforward.
-
-C.3: OPENGL DRAWING OPERATIONS
-
-Most functionality is implemented as operations on the current opengl context,
-so it should be compatible with most application
-that do their own opengl intialization and surface management.
-This is used to implement 3dp.
-
-
-
-
-
-
rmfile ./doc/old/layers.txt
hunk ./doc/old/overview.html 1
-
-Pure Data Packet
-
-
-Pure Data Packet
-
-
-Introduction
-
-Pure Data Packet (PDP) is an extension library for the computer music
-program Pure Data (PD), by Miller Puckette and
-others. Its goal is to provide a way to use arbitrary data types (data
-packets) as messages that can be passed around inside PD, along side the
-standard PD numbers and symbol types. In short it puts any data object on
-the same level as a float or a symbol.
-
-
PDP runs on Linux and OSX. The OSX version depends on Fink, which is not in the "point &
-click" stage yet, so setting it up will require some efford. There is no
-windows version. The reason for this is simple: i don't use windows myself.
-Porting would require writing code for input/output and getting the
-libraries PDP depends on to work. If anyone is willing to do this, just let
-me know. PDP can run without X Window, using SDL.
-
-
Currently, PDP's focus is on images and video, but there is no reason it
-should stay like that. There is limited support for matrix processing
-included in the main library (like Jitter or Gridflow). There is an
-extension library for 1D and 2D binary cellular automata, opengl rendering
-(like Gem). Some plans include audio buffers (like Vasp), ascii packets,
-text buffers, ... Finally there's a library that enables you to connect a
-scheme interpreter (guile) to PD/PDP. For more image processing objects,
-have a look at Yves Degoyon's PiDiP library.
-
-
Getting Started
-
-If you're used to working with PD, the the documentation and example
-patches should be enough to get you started. Have a look at the README file
-in the distribution to find out how to compile and setup. The file
-doc/reference.txt contains a list of objects. If you have installed PDP
-properly, you can just press the right mouse button on an object and select
-help to get a help patch. If this doesn't work, look in the directory
-doc/objects for a collection of help patches. The directory doc/examples
-contains some more demos. The directory doc/objects contains two
-abstractions that are used to setup the input and output in the help
-patches. You might want to cut and connect some wires to use the
-input/output setup that works for you.
-
-Packets and Types
-
- PDP is centered around the concept of packets and operations on
-packets. There are several types of packets. The default type for most
-objects is image/P411/320x240. This is a single video
-frame, encoded in the internal 16bit YUV format, measuring 320 by 240
-pixels. Another image type is the grayscale image
-image/grey/320x240. Important notes: All image processing objects that
-combine two or more packets need to be fed with the same packet types, i.e.
-encoding (P411/grey) and dimensions need to be the same. Image dimensions need to be a
-multiple of 8x8.
-
-
The
-bitmap/*/* type is another image representation type
-supporting several encodings. I.e. bitmap/rgb/*,
-bitmap/rgba/*, bitmap/yv12/*, ...
-
-This type cannot be processed directly by most of the image processing
-objects, but it can be used to store in delay lines, or to send over the
-network. It's main use is to support all kinds of input/output devices, and
-opengl textures, without introducing too many conversions, but it can serve
-as a space and bandwidth saver too (especially
-bitmap/yv12/*).
-
-
One of the interesting
-features in PD is the possibility of connecting everything with everything.
-If you want to generalize this to all kinds of media objects, the complexity
-of managing the different types starts to grow quite fast. Therefore PDP has
-a type conversion system that can take care of most of the conversions
-using the [pdp_convert] object. You can manually convert
-packets to a certain type by specifying a type template as a creation
-argument. I.e. [pdp_convert image/grey/*] will convert
-any packet to a greyscale image. Most of the conversion will become
-automatic later on.
-
-
An example: You can use the basic PDP library together with the
-cellular automata library and the opengl rendering library to use a cellular
-automaton as an input to a video processing chain. You can convert the
-processed image to a texture that can be applied to a 3d object, which then
-can be drawn to the screen, captured as a texture, converted back to an
-image, which can then be converted to a sound, processed and converted back
-to an image, etc... You get the point. The possibilities are endless.
-
-
-
-
- Tom Schouten
-
-
-Last modified: Thu Sep 25 20:51:44 CEST 2003
-
-
-
rmfile ./doc/old/overview.html
hunk ./doc/old/pdp_forth.html 1
-
-
-
- PDP Forth Scripting
-
-
-
- PDP Forth Scripting
- Introduction
-
- This document describes the rationale behind the pdp forth scripting
- language, aka "pdp's rpn calculator".
-
-
-
The point is to be able to decouple the packet processors from the pd
- object model, in order to be able to port the functional part of pdp to other
- systems. Therefore pdp needs its own processor model.
-
-
A requirement for this is that it is both flexible and simple. pd's object
- model is very flexible, but it is hard to port to other architextures, because
- of the tight bindings to the pd kernel. What is needed is a way to abstract the
- functionality of a pdp object in such a way that a pd class can be
- generated from the pdp processor model.
-
-
There are a lot of ways to solve this problem. One is to extend a packet
- class to support methods. This seems like a very clean solution, however
- when a processor has more than one packet as internal state, this poses
- a problem. It would require to define an operation like biquad (which has 1 input
- packet and 2 extra state packets) as a method of a packet collection. To
- do this properly requires a much more advanced object model, or a separate
- object model for processors.
-
-
-
In short: it is not always clear if a packet processor can be seen as a metod
- 'of' or an operation 'on' a single packet, so extending a packet with methods
- would require a separate packet processor class anyway. Therefore we do not
- define packet operations as methods of packets. (no object oriented solution)
-
-
Another approach is to write operators in a pure functional way: a processor
- accepts a list of arguments and returns a new list of arguments. To do this
- cleanly it would require the calling style to be pass by value: i.e. the arguments
- passed will not be modified themselves. Since most of the image processors in
- pdp all use in-place processing for performance reasons (minimal L2 cache
- usage), this would require
- a lot of workarounds or a big kludge mixing const and non const references
- (like it would be done in C++).
-
-
Since one of the goals is to automate
- the generation of wrappers of pdp processors (i.e. pd classes, python classes,
- scheme functions, ...) the interface can best be kept as simple as possible.
- (no pure functional solution)
-
-
The most natural solution, given the underlying code base, seems to be to embrace
- an in place processing approach. What comes to mind is to use a data stack to solve
- the communication problem. I.e. the forth language model. A packet operation is then
- a forth word that manipulates a data stack. A data stack is nothing more than a list
- of atoms containing the basic data building blocks: floats, ints, symbols and packets.
-
-
An additional advantage is that dataflow and forth mix very well. This would enable
- the possibility to create new words by chaining old ones, without the disadvantage
- that pd abstractions using pdp objects have: passive packets are contained in internal
- processor registers longer than necessary, leading to inefficient cace memory
- usage. The forth uses a copy on write strategy. Together with in place processing
- this is optimal for effects chains without fanout.
-
-
Several practical problems need to be solved to implement this. The first being
- description of the stack effect. Each primitive word has a mandatory description of
- the number of stack elements it consumes and produces.
-
-
The forth words will support
- polymorphy: each word has a type template to describe the type of atoms it can operate
- on. The type is determined by some word on the stack, or a symbol indicating the type for
- generators.
-
-
To solve the additional problem of mapping forth words to processors, the concept
- of a forth process is introduced. A forth process has a stack (representing it's
- state), an init method that constructs a stack, a process method that operates
- on the stack and some description of how to map inputs to stack and stack to output.
- The mapping between a forth process and a pd object is represented by a pdmap.
-
-
There is one last class of objects that don't fit the forth description
- very well: it is the input/output classes. These will probably stay as special
- cases, since they really need an internal state represented as an object,
- incorporating them into the system would require them to be defined as an
- object (quicktime packet, v4l packet, xv packet, ...). More later.
-
-
Implementation
- Have a look at pdp_forth.h
-
-
-
- Tom Schouten
-
-
-Last modified: Fri Sep 19 04:49:11 CEST 2003
-
-
-
rmfile ./doc/old/pdp_forth.html
hunk ./doc/old/pf.xml 1
-
-
-
-Packet Forth
-
-
-
-Introduction
-
-You know, there's something strange going on with forth. In the
-last 2 years, my attitude towards forth has changed from being intrigued
-by that language with the strange succession of words, through the process
-of trying to write several forths myself, and inspecting a miracle of engineering:
-ColorForth. Chuck Moore is a genious.
-
- All in all forth is a hack. It is very much determined by design
-decisions mostly aimed at keeping it simple. It is very pragmatic.
-But, it is a hack that solves one of those hard problems: finding a good
-compression scheme for human and machine readable concepts. Aka code and
-data. Packet Forth takes forth somewhat out of it's original "can't be too simple" context
-by turning it into a more highlevel, typed language, while forth is usually
-situated at the bit and machine instruction level. Somehow this typed approach
-makes it feel more contemporary. Direct consequences are that it's slower, but less
-error prone. Different, more in tune with other tools in the basket, and i'm looking
-at perl, python and guile.
-
-
- In case this is not convincing as a teaser to read more, let me give you a pragmatic example.
-When i work with pf, i have usually a terminal running a pf session with some
-things loaded. I want do try something. Mostly this is just a couple of commands.
-But i will need them again later, so i make a new composite word. Then i try again,
-etc. When i got something workin, i paste it to an editor. Or, i can work the other
-way around, and send a line of commands to the interpreter when i'm working on
-a forth program in the editor (emacs). This just works. The fact that it's forth,
-doesn't matter that much, only that it leads to the smallest red tape overhead. Most
-things are just one word. One symbol per abstract action.
-
-
-
-Commands and Command Composition
-
-
-Forth is commands. Each command does something with the current things.
-The current things are kept on a stack. The stack can be printed using
-the command .S, which starts with a
-. like most words that send
-something to the current output stream. The command consisting of
-a single . prints the top atom
-on the stack and discards it. Try this at the console:
-
-
-
-> 1
-> .S
-<1> 1
->
-
-
-
-The first command will load the integer number 1
-Now, let's get some more fuel.
-
-
-
-> 2 3
-> .S
-<3> 1 2 3
->
-
-
-
-
-We now have 3 items in our bag. The hottest one is 3. It is on the top of
-the stack. If a command is executed that consumes just one item, it will
-be the 3. But we're not going to do that. We're going to try something
-more exiting, which is to execute the command +:
-
-
-
-> +
-> .S
-<2> 1 5
->
-
-
-
-It seems the 2 and 3 magically disappeared from the stack and were
-replaced by a 5! Luckily, the 1 is still there, not touched by the evil
-fivifier. Actually, + is not really a fivifier.
-And besides, Packet Forth
-does not come with fivifiers (tsss). So why don't we just extend it?
-
-
-
-Before we start the chapter on how to add a fivifier to Packet Forth,
-we first make sure there is an item worth of fivification in the ready
-position, meaning the top of the data stack. We do this using the command
-'swap'.
-
-
-
-> swap
-> .S
-<2> 5 1
->
-
-
-
-Now, the most important thing about forth in general is the ability to
-extend the language with fivifiers, but also any other function or
-operation you can think of that is a combination of known operations. A
-new operation can be defined using the combo :
- and ;. The first word
-following the semicolon will be the name of the composite command, all the
-other symbols until a semicolon will be part of the command definition.
-
-
-
-Let's define a fivifier. Admit it. The thing you've been waiting for.
-Just type this at the '>' prompt and brace for horror.
-
-
-
-: vijver drop 1 1 + 1 + 1 + 1 + ;
-
-
-
-Now, this really is an evil fivifier. In adition to being pretty
-rude as a fivifier, by discarding the first item instead of treating it
-with proper respect, it also goes against the holy doctrine of the Church of
-Chuck, which says thou shall factor!
-Anyway. Lets check if we're really dealing with a fivifier.
-
-
-
-
-> vijver
-> .S
-<2> 5 5
-
-
-
-The top 1 is gone, and a five is put there instead. The fivifier seems
-to be operational.
-Now, let's clean this fivifier up a little. The recurrent pattern that
-catches the eye above is '1 +'. This is actually way to verbose for an
-operation with such small effect. Let's define this operation, 'to add one
-to the item on the top of the stack', to be hitheron know as 'x':
-
-
-
-: x 1 + ;
-
-
-
-This means we can redefine the fivifier using the word 'x' we just
-created. You may call me mad, but this is what is called compression of
-ideomatic sequences.
-
-
-
-: vijver drop 1 x x x x ;
-
-
-
-Ok, enough sillyness. This however does illustrate the key concepts.
-Forth is about words and stacks and this enables very easy factoring.
-Factoring (chopping the large chunks into smaller bits) is essential to
-writing understandable code in any programming language. Forth makes it
-easy and almost a requirement, so why not:
-
-
-
-: y x x ;
-: z y y ;
-: vijver drop 1 z ;
-
-
-
-If you can read that, you can read any forth program with a bit of
-practice. Of course, giving words short names like this can get pretty
-confusing. The entire program from scratch, but with more
-descriptive names:
-
-
-
-: increment 1 + ;
-: add-2 increment increment ;
-: add-4 add-2 add-2 ;
-: vijver drop 1 add-4 ;
-
-
-
-
-Implicit vs. Explicit
-
-
-The advantage of using a stack is that intermediates are not named.
-They are implicit, so
-they don't get in the way when you are trying out things. What i mean with
-intermediates is the values that are passed from one function to another.
-This is also a disadvantage, because it is less redundant: there's more
-information in your head.
-
-
-
-I was thinking about the big difference between forth and languages
-that do have named parameters and local variabled, because that's what
-it's all about in the end. If you look at this from a data-flow pov,
-symbols allow 'random access linking', which effectively introduces a
-complex data flow. In forth, the data flow is a very simple fifo one,
-which enables very short simple functions, but which makes writing longer
-functions harder. For lanugages that name local symbols and function
-arguments, it is the other way around: it is harder to write small
-functions, because the overhead of the names themselves becomes larger,
-but it's easier to write longer functions, because the symbols enable you
-to randomly connect to the caller's namespace. The same goes for data
-flow languages like Pure Data. It's easy to create a mess, and factoring
-requires a lot if [inlet] and [outlet] objects, which effectively increase
-the object count. Which one is best is really a matter of taste. Forth is
-less verbose and serves very well in its role as command language. Forth's
-syntax is optimized for lots of small functions. It allows to write
-extremely modular code, because it force you to 'linearize' your code and
-this makes it trivial to factor.
-
-
-
-
-
-
-
-
-The Gory Details
-
-
-The language is characterized by it's imperative nature. Everything is
-a succession of commands. Because that's basicly all there is, it
-serves good purpose to know how a forth works.
-
-
-
-Packet Forth's interpreter translates human readable code and data
-(text messages) to an internal data representation (data atoms like
-ints, floats, packets, lists, ...). If it concerns a symbol, the symbol is
-looked up in the dictionary of commands. Then, depending on wheter we are
-in interprete or compile mode, the command is executed or compiled.
-
-
-
-Forth is actually 2 interpreters. The inner interpreter executes the forth
-code residing in the dictionary. Forth code consists of lists of execution
-tokens. An execution token points to some machine code (which can come
-from a c program) and some data (which can be forth code). Now, that's
-a mounthful, and everything will become clear later.
-The outer interpreter translates symbolic, indirect commands to direct
-commands (xt) by looking them up in the dictionary. In packet forth, the
-parser is another element that translates a stream of text input to a
-stream of forth atoms.
-
-
-
-Compiled code is referenced by an execution token (xt). Compiling code is
-done by converting a sequence of symbols and data items to a sequence of
-xts and data items. This is a very important concept.
-The most important thing to remember is that a command or instruction for
-the inner interpreter is an execution token (xt). It represents a direct
-link to an action the forth can perform.
-Ignoring the difference between outer interpreter and the parser, the
-important thing to remember is that there are 2 levels 'code'. One is
-human readable (as a string or a list of atoms), the other one is
-compiled. When i say 'x is interpreted' later, it means the outer
-interpreter.
-
-
-
-
-
-
rmfile ./doc/old/pf.xml
rmdir ./doc/old
}