[an error occurred while processing this directive]
A guide to downloading, installing and running the tools can be found in our Getting started with the Eden tools document.
The tools need to find various support files at their start up
time. On UNIX, writing the appropriate wrapper script is left as an
exercise for the user. On Windows, the .exe
files need
to be left in the same directory as the library files, as they were
when the .zip
file was extracted. Previously, a
run.bat
file was configured with information about the
location of the various support files, and then this was invoked to
start tkeden.exe
. The batch file (and the required
initial manual configuration) has now been removed, and replaced with
a hack that attempts to determine the support file locations using the
current working directory. Windows appears to set the current working
directory to the location of the executable when it is run in most
(but not all) circumstances. The proper solution to this problem is
to build an installation program which modifies the registry to record
the location of the support files, but this would take some time and
the current hack may be sufficient for the time being.
Many of the model scripts use the Eden procedural command
include(...)
to read in other scripts. For this to work,
the current working directory needs to be set to the correct location.
Historically, this was never a problem on UNIX as users tended to
cd
into the directory containing the model scripts before
starting the tool (which was usually located somewhere on their
$PATH
). The current working directory is, however, a
less obvious concept in a GUI environment. The tools currently have a
hack to attempt to help with this problem: whenever a script is
included (which could be via the File menu, or via an
include(...)
statement), the current working directory is
set to the containing directory of that script file.
The tools can be run from a DOS prompt, giving a UNIX-like style to
locating and running models. The Windows tools have the same command
line arguments as the UNIX version. If this appeals, we might suggest
that you download cygwin, which
provides a bash
shell for Windows and many other
utilities. We expect most users, however, to use the tools via their
interface. In tkeden.exe
you can load and start using a
model by using options in the File menu. In ttyeden.exe
,
the Eden include(...)
function can be used to read in an
Eden script.
It is possible to put a shortcut onto your desktop to ease starting
the tools: right-click on the .exe
file, choose Create
Shortcut and then drag the resulting shortcut to the desktop.
One possible way to avoid having to repeatedly navigate to the
model files via the File menu is to add the tools to the "Send To"
menu. To do this, create shortcuts as above, then place the shortcuts
in the directory c:\windows\send to
. Model file(s) can
then be selected and "sent to" the tool.
Yes, but over-use of triggered actions can quickly lead to a model which executes rather like the proverbial spaghetti, and is then particularly prone to execution ordering issues which can be affected by subtle factors such as the ordering of items within the script. The primary emphasis of the tools is intended to be the definitive facilities, which are more robust to change. Triggered actions are provided mainly to allow a display (with a conventional procedural interface or API) to be kept in synchrony with a definitive model.
No, although we'll forgive you if you do. Modelling is intended to
be a fairly intensive process involving much interaction between
modeller and model and a large amount of experimentation. The intent
is not for modellers to write large amounts of script "code" in a text
editor, and then keep reinvoking the tool on that file and making
small adjustments until the model "compiles". The interaction
envisaged is more along the lines of the modeller introducing a new
definition or redefinition a few at a time through the Input window,
observing their effect and then repeating, gradually growing a model.
Admittedly, the tkeden
interface offers some rather poor
support to this mode of interaction.
ttyeden
?No, ttyeden
uses the GNU readline
library
as of version 1.4. This uses emacs
-style key bindings by
default, but it can be configured to use vi
-like key
bindings if you love vi
. Note that you can edit input in
the usual way using cursor left / right and backspace, you can move
backwards and forwards through history using the cursor keys (or
control-p, control-n), activate a search through history using
control-r and then typing some of what you would like to find and so
on. readline
can be configured by writing a
.inputrc
file - see the readline(3)
man
page for full details of key bindings and
configuration information.
It is possible to do a kind of "translation" between these two
forms: a is b+c;
might be considered similar to
proc calca : b, c { a = b+c; }
for example. However, the
two concepts are intended to be used for quite different modelling
purposes, and the scheduling of the action version may not be as
correct as the definitive version, since the definition maintainer
lacks knowledge of the left-hand-side of the effective definition
stated by the action. (More detail in this answer would be
appreciated if you'd like to write it!)
proc
and func
in Eden?Currently, the implementation behaviour for both proc
and func
is the same. However, in the future,
func
may be changed, adding dependency on internally
referenced global state, as noted at the end of the Eden handbook.
Modelling a process with continuous retriggering, like a clock,
requires the use of the todo(...)
procedure (which delays
the evaluation of the provided string until after the current run
queue has completed) if the tkeden
interface is to be
kept alive. The code snippet below (taken from the Eden Quick
Reference guide, available from the Help menu in tkeden
)
provides a clock implementation:
proc clocking : clock { /* a clocking process */ todo("clock++;"); /* increment clock after current evaluation finishes */ } proc device1 : clock { /* action synchronised by the clock */ ... /* action body */ } proc device2 : clock { ... /* action body */ }
autocalc
lines added at the start and
end of my files?The ordering of items within a definitive script is, in theory,
unimportant, as the value of a definition will not be calculated until
the information is available. In practice, however, some Eden
operators do not cope gracefully with undefined values (@), and cause
errors, so the ordering of the file becomes important (eg functions
should be defined before their first use). The autocalc
variable allows evaluation to be temporarily suspended, and if placed
at the start and end of a file allows all relevant information to be
loaded (in any order) before evaluation begins. tkeden
's
save facility adds autocalc
lines automatically when
saving if the "save as reusable definitions" option is checked.
tkeden
crashed and (lost my model) / (before I saw
the error message)!Apologies. However, all may not be lost - the history of your
interaction with tkeden
is saved in the files
.tkeden-history*
, located in your $HOME
directory. There is one file per session with tkeden
-
older files are moved to names with a number appended, in case you
restart tkeden
before realising you've lost your work.
Currently, your last four sessions are saved.
The crash may be "normal" (as in "frequent") as the tools unfortunately still have many bugs. However, a fatal error is a nasty type of bug (as it causes annoyance and possibly lost work). If the tool crashes, if you can, fix the problem in the Eden source code. If you can't, please report it as a bug using the database at the SourceForge Eden project page. Please take the time to check if your crash is repeatable and write a small "test-case" (a script with only a few lines) to show the problem - your problem will be easier to solve and hence more likely to be fixed if you put a small amount of effort in.
Strings are not equivalent to lists in some ways. Please submit some more detail for this answer!
Eden's list implementation is not perfect, especially when they are
used definitively (eg l is [a, b, c+2, 42];
):
l[4] =
43;
above would cause the values in l
to then
become the current values of a
, b
,
c+2
and 43
, and they would not be updated in
the future if a
, b
or c
changed).
l[n]
) is really
just sugared syntax for a function-based definition (eg
selectElement(l, n)
). As a result, if a definition
references l[n]
, it will be reevaluated if any other part
of l
(perhaps l[x]
) is modified. This
unnecessary evaluation should not cause trouble with a correctly
written definitive script, but it makes model evaluation slower than
necessary. This problem also means that it is not possible to create
dependency within a list, eg l is [a, l[1]];
as this is
considered a cyclic reference.
There are many ways to approach this problem, and each comes with disadvantages.
graph
facility. This is OK but
limited to line drawing.
for
loop and the include()
procedure to read in a file multiple times, and use the virtual agency
feature to read in the file in a different "context" each time,
creating definitions with agent names prepended to their names,
remembering to use the ~
character to specify the root
context for references to non-context-specific variables. This can
lead to problems which are very difficult to debug and lots of small
files whose function is unclear.
for
loop and the execute()
procedure to repeatedly give the interpreter dynamically created
redefinitions, usually constructed using much string concatenation.
The code that does this is usually fairly hard to read, but easier to
debug than the virtual agent based solution.
for
loop and a macro substitution
procedure to repeatedly substitute parameters into a redefinition
"template" which is then given to the interpreter. The substitution
procedure could be hand-coded, or the system function
sprintf()
could be used, or the library Eden function
macro()
(which is used by DoNaLD) could be used. This
may be the cleanest way yet devised to solve the problem, but requires
some learning about the macro substitution procedure before it can be
used.
Here is an example of technique number 4, kindly contributed by Chris Roe. The following procedure instantiates a set of num parallel DoNaLD lines.
proc p { para num; auto i; for (i=1; i<=num; i++) { execute("%donald point p"//str(i)//" p"//str(i)//" = {10+"//str(i*10)//",10} line l"//str(i)//" l"//str(i)//" = [p"//str(i)//",p"//str(i)//"+{0,500}] "); } }
Note that the line breaks in this solution are essential. The attributeexplorerRoe2000 project contains more examples of this technique.
Some examples for solutions 3 and 5 are given in the Matters Arising section of the Not So Quick Guide to dtkeden.
All of the above "solutions" are in some sense equivalent at the machine level, where individual symbols are created in storage for each instantiated symbol. The duplication uses more system resources and also is not recorded as duplication in the machine, making it difficult to remove instances, for example. So a better solution to this problem probably involves some work in the machine, below the notational level. However if you have any ideas, please contribute!
forget()
procedure work?Yes, it does. But it silently fails (although it gives a different return code) if a definition somewhere in the system references the symbol that you are trying to remove. Check the return code from forget() and use the query statement to help you remove obstinate symbols:
1:> a = 42; 2:> r is a; 3:> writeln(forget("a")); 2 4:> ?a; a=42 a ~> [r]; /* a last changed by input */ 5:> writeln(forget("r")); 0 6:> writeln(forget("a")); 0 7:> ?a; a=@ a ~> []; /* a last changed by input */
This means that Eden was interrupted whilst executing a procedure,
and aborted the procedure, throwing away the return result, any
parameters and auto
variables (which are all stored on
the stack). It is probably safe to carry on without needing to
restart the tool.
Recent update: as of version 1.19, this message has been removed as it means more to the tool developer than it does to the modeller.
"How can I rewrite
if (f(a) == 1) { x = 1; } else { x = 0; }
such that it starts x is ...
? For this, you need to
use the ternary operator (so-called because it unusually has three
parameters). For this example, you would need
x is (f(a) == 1) ? 1 : 0;
Note that the dependency between x
, f
and
a
is correctly set up when using a ternary operator
(check with the query ?
statement).
Back-ticks can be used to change a string into a reference (in a similar manner to their use in UNIX shells to denote execution of a command, the value of the expression being the output of the command). For example:
1:> a = 42; 2:> r = "a"; 3:> writeln(`r`); 42
Back-ticks used in definitions can be problematic. Using them on the left hand side of a definition is safe:
4:> `r` = 43; 5:> ?a; a=43 a ~> []; /* a last changed by input */
But back-ticks on the right hand side of a definition results in missing dependency:
6:> c is `r` + 5; 7:> writeln(c); 48 8:> a = 0; 9:> writeln(c); 48 10:> ?a; a=0 a ~> []; /* a last changed by input */
a
should be triggering c
, at least for as
long as r
remains set to "a"
. This dynamic
dependency is not implemented by Eden (a partial hack solution was
present, but was removed recently as it was incomplete). It is
possible to add missing dependency by using the "dependency link"
~>
statement manually and perhaps wrapping this in an
agent action, but a general solution is difficult and there is
currently no easy way of removing dependencies added in this way.
Yes - currently
proc p : l# { writeln("length of list l changed"); }
results in a parse error. However, it should be possible to write
an action triggered by l
, and examine the length of
l
within the action to see if it has changed (the old
length of the list would need to be recorded as global state).
If you are at the University of Warwick, the USENET group
uwarwick.dcs.emprojects
is a useful public forum, where
others can also benefit from your question and any potential answers.
There are also mailing lists for the Empirical Modelling group: check
the EM web pages for details.
Here are a couple of tricks that might be useful:
_tkeden_showxoutput
to 1. The code sent
Tcl (which is used to implement the DoNaLD and Scout output) will then
be dumped to your terminal when redefinitions are made.
top
. If there appears to be a memory leak, it
is possible to link a version of tkeden
with a library
that checks memory accesses - dmalloc
is a good one: see
the --with-dmalloc-include=DIR
and
--with-dmalloc-lib=DIR
configure
options and
http://dmalloc.com. This can of
course make the tool run very slowly. After you have compiled the
tool with the dmalloc library and set up your shell with the
dmalloc
function / alias, dmalloc -l ~/dmalloc.out
-i 100 low
could be an initial setup line to turn on debugging
and log statistics to the given file on exit.
tkeden
runs: on Solaris, try running truss -f
tkeden
to see them (or use strace
on Linux)
gdb
, or ddd
if
you prefer a windowing version, or dbx
if tkeden was
compiled with cc instead of gcc). If you can reproduce the bug within
the debugger, use the bt
(backtrace) command to print out
the stack trace - this may help to locate the problem. If you can't
get the debugger to work (there might be problems if you don't have
access to the source code, perhaps), then try generating a
core
file (look at the command limit
(in csh
derivates), or ulimit
(sh derivates, including bash)).
Then give the core
file to someone with the source code
and the knowledge that can have a look.
a=@
; causes a Segmentation fault" is better than
"my 5000 line model sometimes crashes".
Use the backslash symbol \
at the end of a line to
continue it onto the next, much as is required in many UNIX shells.
Commas can be used to separate attribute declarations within Scout window definitions, but they are not required, and in fact cause a parse error if they are used after the last attribute. This makes copying and pasting blocks of attributes rather difficult, so we'd recommend that you don't use commas:
window ash = { type: TEXT string: "Ash" };
From \ To | Eden | DoNaLD | SCOUT |
---|---|---|---|
Eden | direct | prepend an underscore _ |
direct |
DoNaLD | append exclamation ! (before any argument list for a
function: eg eq!(a,b) ). You may need to surround with
trunc() or float() to force the type. |
direct | append exclamation ! (before any argument list for a
function: eg eq!(a,b) ). You may need to surround with
trunc() or float() to force the type. |
SCOUT | direct | prepend an underscore _ |
direct |
Don't forget to declare variable types in notations other than Eden.
The Scout Y coordinate system is the opposite way up to Donald. (Or is it? Can you provide more detail?).
Remember that you can redefine a large amount of the standard
library that is included in tkeden
at runtime. If you
need information that a library function uses, then write a patch file
which you include at runtime that redefines that function, extending
it in a way that you would like. If this solves a general problem in
a nice way, your patch should then be merged into the main source code
permanently.
~
character do in Eden?In DoNaLD, the ~
character denotes a "root context".
In Eden, it means something similar: it denotes a reference to a
variable in the root virtual agent context. Virtual agents are
documented in the Quick Guide to dtkeden. They bring many problems
along with their potential power, however - please read the note at
the head of that document carefully before using them.
sscanf()
?This example might help - it reads a string input from the user,
then attempts to convert this to an integer value. See the
sscanf(3C)
man page.
$ ttyeden 1:> input=gets(); 42 2:> i=0; /* must initialise to an integer */ 3:> sscanf(input, "%d", &i); 4:> writeln(i); 42
Scout is designed primarily for window layout, so probably won't
give you much help here! You can write a function in Eden, however,
and show the result of that in Scout. A function to format a number
to this specification is given below - see the
sprintf(3C)
man page or any good book on the C language
for an explanation.
%eden func snf { /* Must initialise it to a string of appropriate length */ ret=substr("", 1, 10); sprintf(ret, "%.4e", $1); return ret; }
sprintf
is used by Donald: see the rtos
function in donald.init.e
(or just View Eden
definitions).
Colour values can specified to Tk (and hence, tkeden
)
in two ways. (The following is taken from "Practical Programming in
Tcl and Tk", Welch). Colour values are specified in two ways:
symbolically (eg red
) or by hexadecimal numbers (eg
#ff0000
). The leading #
distinguishes the
hexadecimal representation from the symbolic one... There is a large
collection of symbolic colour names like "red", "blue", "green",
"thistle", "medium sea green", "yellow4". These names originate from
X... run the xcolors
program that comes with the standard
X distribution.
We'd recommend that you use hexadecimal colour values if you are
not using one of the trivial colour names (for portability). A
function to convert integer red, green, blue values (eg 1, 30, 255)
into a hexadecimal colour reference which can be used throughout
tkeden (the corresponding result being #011eff
) is given
below.
%eden func colourref { para r, g, b; s = substr("", 1, 8); /* must initialise to appropriate length first */ sprintf(s, "#%02x%02x%02x", r, g, b); return s; }
eval()
(or
back-ticks...)List indexing doesn't appear to be implemented in either the back-tick operator or the eval function currently:
$ ttyeden 1:> d = ["a", "b", "c"]; 2:> writeln(eval("d[2]")); d[2] 3:> writeln(`"d[2]"`); @
Eval
in particular, though, has procedural overtones:
it evaluates the given expression to provide a value, but when? At
the time of execution of the eval
statement - perhaps
something we should be trying to get away from. Can you re-think?
-------- file server.e: -------- %eden /* dtkeden -s -c 12 server.e & */ %lsd agent ash oracle tn, _clock_t, a %eden tn = 0; _clock_t is tn / 60; a is tn / 60; -------- file client.e: -------- %eden /* dtkeden -a -c 12 -h gem client.e */ proc p : _clock_t { writeln("_clock_t = ", _clock_t); } --------
One thing that appears to come out of this experiment: in some
cases, specifying an observable means that every change to it
will be observed by the client. In other cases (eg this
derivate case), specifying the observable means that it can
be observed by the client. In this case, doing
renewObs("a");
on the client causes the current
definition of a
(which is a derivate) to turn up at the
client. There are numerous issues here: derivates probably shouldn't
be treated differently wrt propagation; perhaps a peer-to-peer-based
structure to dtkeden
would be more sensible and general
than a client / server architecture; the ontology being invoked by the
dtkeden
implementation is undocumented and hence probably
not well implemented, etc etc...
sensitive: MOTION
?"I would like to be able to drag a 2D drawing (using a reference point) across a Donald window. The catch is that I want to be able to redraw the object so it appears on the screen as I move it..."
If you specify sensitive
as MOTION
, the
definition name_mousePos
will follow the position of the
mouse. name
should be substituted with the name of the
widget in the same manner as the _mouse
and
_key
definitions. Here is some example code:
%scout point soundLevelButNW, soundLevelButSE; soundLevelButNW = {400, 420}; soundLevelButSE = {410, 490}; window soundLevelBut = { type: DONALD pict: "SOUNDLEVELBUTTON" box: [soundLevelButNW, soundLevelButSE] xmin: -5 ymin: -5 xmax: 5 ymax: 105 border: 1 sensitive: ON + MOTION }; screen = <soundLevelBut>; %eden proc p : soundLevelBut_mouse { writeln("p : ", soundLevelBut_mouse); } proc q : soundLevelBut_mousePos { writeln("q : ", soundLevelBut_mousePos); }
p
is triggered when the mouse is clicked (since
ON
also specified for sensitive), and q
is
triggered when the mouse is moved inside the button. Check the
History window and watch for redefinitions there when moving the
mouse.
Note that it should now be possible to specify a variable instead
of the constant MOTION
for sensitive
, which
would mean that you could turn this feature on and off (as the number
of redefinitions caused by every mouse movement can cause things to
slow down a bit).
This doesn't work:
for (i=1; i<= delList#; i++) { delete master, delList[i]; };
(delList
is, for example, [18, 36, 54] and
master
is [1, 2, 3, 4, ...]).
It looks like there were two problems for anyone who comes across
this in the future: a) An eager()
is needed some time
after the delete. b) When you delete x
, y
becomes element y-1
if y
is after
x
: you need to add a fudge factor...
dtkeden
(like
-c
) which allows specification of agent name
automatically?No, not at the moment - sorry:
$ dtkeden -u Usage: /dcs/emp/empublic/solaris-sparc/bin/dtkeden-1.17 [-s|-a] -c<channel number> -h<hostname> {-l<lib directory>} {-v|-u} {-e <code>}|{<filename>} {-e <code>}|{<filename>}... -s invoke as the server ("superagent") -a invoke as a client ("agent") -c channel number: 0,1,2,3, ..., 99 -h hostname of the machine running the dtkeden server (only required if running as a client [-a]) -l name of the directory containing the library files -v output version information and exit -u output this usage information and exit -e execute 'code' if file is '-', standard input will be read See http://www.dcs.warwick.ac.uk/modelling/ for more information
This feature might be added at some point in the future: keep an
eye on the ChangeLog file (accessible using Help->ChangeLog) and the
usage message given by the -u
argument.
The &=
Scout operator was implemented to allow adding,
instead of having to use an execute()
, so (eg)
screen &=
should add to the
screen
variable.
As a first step, you can redefine the screen
variable
so that the particular window does not show. You might like to know
that you can reflect on the current state of symbols using the Eden
functions such as symboldetail()
, the results from which
it is possible to modify and then use to make a redefinition, using an
execute()
. (Documentation of a second step would be
appreciated if you want to submit it!).
"Eg, in DoNaLD, line1 = [{5,10},{15,20}]
, then in Eden
find out the values of the x
and y
variables
of the points".
Try accessing it as _shape_linename
(e.g. _thingy_line1
if you call your shape
thingy
). This seems to represent, as a list:
[L,[C,1,1],[C,100,1]]
so _thingy_line1[2][2]
is the first coordinate of the first point,
_thingy_line1[2][3]
is the second coordinate of the first
point and so on.
There appears to be a variable CLIENT_LIST
which
contains a list of connected clients.
symboltable()
function...Presumably you have quite a large model. Probably the targets and
sources parts of the list that is being built to be returned to you
are too large. The function symboltext(symbol)
should be
useful in this circumstance: it gives the same result as
symboldetail(symbol)[3]
(the text that was used to
originally define the symbol) but this function is less likely to fall
over due to lack of heap space.
Remember to state which platform you are using in problem descriptions as things may well work differently on different platforms.
If you are using Windows, try re-enabling the "mouse follows focus"
function in edenio.tcl
.
You aren't running it on an XDM terminal, are you? (Ie an X-terminal or old SparcStation set up to run almost everything remotely across the network).
Environment variables might be possible, as Tcl and Eden run in the same process...
/* parameter is string of TCL variable to copy e.g. $eshost */ /* RETURNS : Contents of Tcl Var in EDEN */ proc tclBridge { para toGet; auto result; tcl("set env(TCL_TO_EDEN_LINK) "// toGet); result = getenv("TCL_TO_EDEN_LINK"); return result; }
Update: this may be unnecessary as the Eden tcl()
function seems to return the result of the Tcl command. So the above
function could possibly be replaced by this (untested) version:
proc tclBridge { return tcl("set "//$1); }
propagateType
is a system variable that controls
automatic sending of observables to clients (within
dtkeden
). There are 3 possible values: -1
,
0
and 1
. It works in conjunction with
everyOneAllowed
which controls the activation of LSD, if
present. everyoneAllowed
is documented in the Quick
Guide to dtkeden. This table shows the actions taken by
dtkeden
for each value combination.
propagateType \ everyOneAllowed | 1 | 0 |
---|---|---|
-1 | No Propagation | No Propagation |
0 | Propagate all observables | Follow LSD definition |
1 | Propagate all observables | Propagate all observables |
The value of propagateType
can be changed during a
modelling session. Any new observables will behave as the new
value. The behaviour of the old ones is more uncertain. In general it
will keep its previous method: e.g. observable a
is
created while propagateType == -1
. Observable
a
will not be sent to any dtkeden
clients.
However, under some circumstances the observable
(e.g. a
) will switch behaviours after
propagateType
is changed: i.e. it may now be
automatically sent out to all the clients. The exact circumstances
that this occurs under are not clear, but it may be related to the
observable being redefined.
If the value 0
is used then LSD permissions are
respected. It is important to note that LSD works for virtual agents
as well as normal ones and once a definition is created for an
observable, every agent requiring access must be
stated. This includes any virtual agents created by
procedures.
This is a rough outline. Edward Yun Wai Yung's third year project
became his MSc by research, which he submitted in September 1989.
This was Eden. Edward's younger brother, Simon Yun Pui Yung (sy)
became interested in this and, following the completion of his PhD in
October 1992, spent two years as an EPSRC-funded research fellow
integrating the pipeline-based tools into the initial
tkeden
. Richard Cartwright and Amanda Wright later fixed
bugs, ported the system to Solaris 2 from SunOS 4 (Solaris 1) and
worked on the initial PC port. For his PhD (completed in July 1999),
Pi-Hwa (Patrick) Sun added distributed features to the work, producing
dtkeden
. Ashley Ward started to clean up the code in
1999, merging the dtkeden
and tkeden
sources
back together and replacing the old Imake
-based build
system with an autoconf
based solution. Ben Carter
developed the code on Windows for his third year project in 1999/2000,
working on the port and adding the Sasami notation. Since then,
Ashley Ward has ported the Sasami notation back to UNIX, given the
software the GPL license, uploaded it to SourceForge and worked on
many bug fixes and interface improvements.
exp2
, exp10
and
log2
gone?These functions have been missing from Eden since around 1999 as they seem to have disappeared from the C library. Hopefully you can work around this using other functions - ask if you need them implemented again.
screen=<thing/thing2>;
and
screen=thing&thing2;
in Scout?The /
operator in Scout is for both numeric division and
for concatenating windows into a window list, the last item
in the list being furthest away in Z. A window list (which might only
have one item) is made into an expression of type display by
surrounding it with chevrons, thus:
<window1/window2>
or perhaps just
<window1>
. The variable screen
is of
type display
, and so this syntax can be used to form an
expression which may then be assigned to screen
.
The &
Scout operator is used to concatenate items of
type frame
(used for laying out text across multiple
windows as in desktop publishing - although this doesn't work too well
at present) or display
, with the last item mentioned
again being furthest away in Z. Thus multiple displays can be
assigned to screen
using the &
operator:
screen = display1 & display2;
, or displays and windows
can be mixed, using the chevron syntax described in the paragraph
above: screen = display1 & <window1>;
.
tkeden
seems to keep freezing for two seconds each time
there is an error...Yup, this seems to be a bug in the Tk "raise" function (which pulls
a window to the front) - tkeden
does this each time an
error occurs, and when you open the History window etc etc. This
seems to have been reported already as bug #25020 in KDE (which is 73
days old today) and bug #220260 in Tk, which states the bug is with
Enlightenment and can be fixed by upgrading to version 0.16.4 (which
doesn't seem to help here).
A work-around is to use Tcl to redefine the raise function. Start tkeden like this:
tkeden -e 'tcl("proc raise {win} {}");'
No, but you can copy a proc and then overwrite the old definition. This can be useful when debugging. For example:
execute("proc scout_show_canvas_original " // symboltext("scout_show_canvas") // ";"); proc scout_show_canvas { writeln("scout_show_canvas ", $); apply(scout_show_canvas_original, $); };
tkeden
seems to have hung...First, try pressing the Interrupt button. If that fails, try
pressing Control-C once in the terminal window from where you
started running it. (Or find the process number and do a kill
-INT <process number>
). This will clear both the current
and the todo run queues, hopefully unwinding the tight loop that
tkeden
may be in.
tkeden
- why doesn't it work in
ttyeden
?tkeden
comes loaded with a lot of state from the
library files (specified with the -l
argument).
ttyeden
does not read any library files and so has fairly
minimal state at startup: there is no definition for TRUE
and so on, for example.
-n
and -i
command line
options do?These options effectively control the state of the
eden_prompt
variable, determining whether the
ttyeden
prompt is displayed. This is typically used to
suppress the prompt when piping input into the tool via a translator.
The options are only available in ttyeden
, and the
eden_prompt
variable (which is correctly triggered by a
change propagated from the command line options) is only available in
version 1.19 and later (so the prompt may only be controlled from the
command line). The options may be given multiple times and the
ordering is significant: -n one.e -i two.e -n three.e
causes a prompt to appear during execution of two.e
only,
for example.
dtkeden
communicate on?dtkeden
uses sockets to implement client / server
communication. The port number it uses is set by the -c
option, which ranges from 0 ... 99. The actual port number currently
used is this number + 9000. This port range is not officially
assigned and so may need changing in the future.
Use the -u
(usage) option to find out.
Use the -v
option.
Trigger pointers on variables tell Eden to propagate change
elsewhere when the value of that variable is changed. The current
status of the trigger pointers is shown in the output from the
?
query operator:
1:> a is b+c; 2:> ?b; b=@ b ~> [a]; /* b last changed by input */
(When a change is made to b
, this will automatically
cause a
to be re-evaluated). The list of trigger
pointers may be added to using the ~>
"dependency
link" syntax:
3:> b ~> [q]; 4:> ?b; b=@ b ~> [a, q]; /* b last changed by input */
It is not easily possible to remove trigger pointers in the current (1.19) version of Eden, although it would be possible to hack a solution by using execute to redefine symbols, resetting the trigger pointers.
----
line at the top of the View menu?Some of the menus in tkeden
can be "torn off" - click
on the menu, then click on the ----
line at the top to
turn the menu into a "torn-off" window that persists until you close
it. This might be useful if you are repeatedly opening and closing
windows.
Define your function in Eden, then use func!(args)
in
Donald to call it. (Note that the !
in the syntax must
go between the name of the function and the argument list).
include("~/...")
statement doesn't work~/
and ~username/
are syntax for home
directory location in some UNIX shells. The syntax is not implemented
in Eden: you might try using getenv("HOME")
instead.
Eden provides C-style multi-line /* */ comment syntax. C pre-processors do not implement nesting of comments, and so commenting out chunks of code can be difficult if comments already exist within the code (the first */ ends the comment block). In Eden, /* */ comments can be nested and so chunks of code can be reliably commented out.
tkeden
notations?Eden previously implemented only the C-style multi-line /* */
comment syntax. Some other notations do not implement this syntax,
and so getting the correct syntax to use for a comment can be
frustrating when writing a script which uses multiple notations. Due
to this problem, a one-line '##' comment syntax was introduced into
Eden in version 1.19. '#' is a valid comment in the other
tkeden
notations, and so
## this is a comment in all tkeden notations (phew)
Historically, UNIX does not use file extensions, preferring to look
at the start of the file contents to determine the type (see the
file(1) command for example). As a result, most existing models use a
somewhat rough file extension scheme. The tools now exist on more
than one platform, however, and Windows in particular still uses
information from the filename to determine the file type. As of
version 1.16, we would suggest the use of the file extensions
.eden
, .donald
, .scout
,
.sasami
and .script
. The single character
file-types were inadequate in many ways (we now have >1 notation as a
candidate for .s
, .s
is also used for
assembler files on some platforms and so on). .script
is
intended to be used for the circumstance where a text file contains a
script which uses mixed notations: Eden and Donald, for instance.
Hopefully this won't cause problems with Windows 8.3 filename
limitations.
This FAQ will only be useful if it contains genuinely useful
frequently asked questions and answers, and it will only grow into
this through contribution. Please email any questions (and hopefully
answers!) you have to modelweb@dcs.warwick.ac.uk
for
inclusion here. Thanks in advance :).
Note that the []
list indexing operator takes
precedence over the *
pointer dereference operator.
Brackets are therefore required if you use pointers to lists:
var = &my_list; x = (*var)[i]; writeln(x);
Yes. Instead of building your entire interface in one Scout
window, you can create more than one window in your platform's
windowing environment and use multiple Scout screen
s.
You need to call the OpenDisplay
procedure and introduce
an agent to call DisplayScreen
when your new Scout
screen
list is changed. An example with an additional
text window to show how the second screen can be used is below:
%eden OpenDisplay("screen2", 500, 500); proc display_screen2 : screen2 { DisplayScreen(&screen2, "screen2"); } %scout window label = { type : TEXT frame: ([{20, 20}, {400, 30}]) string: "This is Scout screen2" }; display screen2 = <label>;
There is a commonly used idiom for appending to lists which causes problems in Eden. The code below will cause a stack overflow error after only 1023 items have been appended:
%eden l = []; for (i = 0; i <= 9999; i++) { l = l // [i]; /* don't use this idiom */ }
The problem occurs as the //
concatenation operator
uses the stack as temporary space to form its result. The expression
on the right hand side of l = l // [1]
causes Eden to
make a copy of l
, add the extra item 1
to
its end and then finally assign this result back to the symbol
l
. The following reformulation is much more efficient
and does not result in a stack overflow error as it appends to the
list in place:
%eden l = []; for (i = 0; i <= 9999; i++) { append l, i; }
So, in general, in all cases, when appending to the end of a list,
the procedural append
command should be used in
preference to the more list-processing concatenation //
equivalent. l = l // [x]
should be replaced with
append l, x
(note that the concatenation operator
requires two lists, whereas append
takes a list and any
type).
If the recommended idiom for appending to lists is used, very large lists can easily be processed by Eden: the limit is actually related to the amount of virtual memory available to the Eden process.
The above substitution should not be applied when l is a string, as
although the //
concatenation operator functions on
strings as well as lists, the append
command does
not.
23rd Feb 2002: the above substitution is now automatically
implemented in Eden (versions >= 1.38), so the problem described above
should no longer occur, and there should be no need to change any Eden
scripts. Note however that the less common case l = [x] //
l
is not optimised, and would lead to the same stack overflow
problem described. This example could be recoded using the list
insert
command.
sprintf
examples, added another one. [Ash]
uwarwick.dcs.emprojects
(particularly Chris Keen) for the questions and answers. [Ash]