Commit ff6b61e3 authored by Jiri (George) Lebl's avatar Jiri (George) Lebl

Mon Jul 27 15:22:57 2009 Jiri (George) Lebl <jirka@5z.com>

	* help/C/genius.xml, help/C/gel-function-list.xml: Update
	  documentation for all the new features and improve existing
	  parts a bit especially by adding a bunch of links for some
	  functions.

	* NEWS: update
parent e1b7a0d5
Mon Jul 27 15:22:57 2009 Jiri (George) Lebl <jirka@5z.com>
* help/C/genius.xml, help/C/gel-function-list.xml: Update
documentation for all the new features and improve existing
parts a bit especially by adding a bunch of links for some
functions.
* NEWS: update
Fri Jul 24 17:23:04 2009 Jiri (George) Lebl <jirka@5z.com>
* lib/calculus/fourier.gel: fix cosine series and fix argument
......@@ -13,7 +22,7 @@ Fri Jul 24 17:23:04 2009 Jiri (George) Lebl <jirka@5z.com>
Fri Jul 24 16:32:32 2009 Jiri (George) Lebl <jirka@5z.com>
* lib/calculus/fourier.gel: add NumericalFourierCosineSeriesFunction
and NumericalFourierSineSeriesFunction and fixup some doc stringss
and NumericalFourierSineSeriesFunction and fixup some doc strings
* src/eval.c, src/dict.c: build the subst_dict on first function
evaluate. This avoids subst lists for simple functions, plus
......
Changes to 1.0.7
FIXME
* SYNTAX: Added a possibility to exactly specify which variables are copied
into a function's extra dictionary when it is being returned.
E.g. "`(x) [x0] = (x-x0)" will copy x0 from the current context. This
is a lot more efficient than the current behaviour which tries to copy
everything referenced.
* SYNTAX: Add "local" variables by specifying "local x,y,z" or "local *" as
the first statement in a function. Local variables are not visible from
higher contexts (functions called within)
* CHANGE: all system parameters are now protected and cannot be redefined
using the "parameter" keyword
* Add UserVariables, UndefineAll, ProtectAll, and add Undefine as an alias to
undefine.
* Add trigonometric Fourier series related functions:
NumericalFourierSeriesFunction, NumericalFourierSineSeriesFunction,
NumericalFourierCosineSeriesFunction, FourierSeriesFunction,
NumericalFourierSeriesCoefficients, NumericalFourierSineSeriesCoefficients,
NumericalFourierCosineSeriesCoefficients, PeriodicExtension,
EvenPeriodicExtension, OddPeriodicExtension
* Fix changing floating point precision!
* Fix uninitialied variable in graphing (Matthias Drochner)
* Improve variable substitution for returned functions to be more efficient.
Slightly changes behaviour with respect to global functions and variables
used.
* Plot windows now not treated annoingly as dialogs
* Fix compilation/decompilation of all function attributes.
* Parse/Evaluate with a syntax error at end of string no longer terminate
genius
* Updated Mersenne stuff for the newest data from mersenne.org and
fix MersennePrimeExponents
* Fix opening new files from the command line.
* Update the gel library to use the new language features.
* Various other minor fixes
* Translation updates (Philip Withnall, Jen Ockwell)
* For some of the changes the author (Jiri) was partially supported by
NSF grant DMS 0900885 and the University of Illinois at Urbana-Champaign
Changes to 1.0.6
......
This diff is collapsed.
This diff is collapsed.
......@@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY app "<application>Genius Mathematics Tool</application>">
<!ENTITY appname "Genius">
<!ENTITY appversion "1.0.6">
<!ENTITY appversion "1.0.7">
<!ENTITY manrevision "0.2.3">
<!ENTITY date "March 2009">
......@@ -1827,43 +1827,82 @@ for conditional evaluation works here as well. For example, <literal>1 or a=1</l
<sect1 id="genius-gel-variables-global">
<title>Global Variables and Scope of Variables</title>
<para>
Like most programming languages, GEL has two different types
of variables: local and global. A local variable only exists
in the context of the function where it is set and all functions
called from inside this function. A global variable
exists in all contexts. When you set a variable on the toplevel
command line, outside of any function, then it will be a global.
All functions will see it.
Like most programming languages, GEL has different types
of variables. Normally when a variable is defined in a function,
it is visible from that function and from all functions that are
called (all higher contexts). For example, suppose a function
<function>f</function> defines a variable <varname>a</varname>
and then calls function <function>g</function>. Then
function <function>g</function> can reference
<varname>a</varname>. But once <function>f</function> returns,
the variable <varname>a</varname> goes out of scope.
This is where GEL differs from a language
such as C. One could describe variables as being semi global
in a sense
For example, the following code will print out 5.
The function <function>g</function> cannot be called on the
top level (outside <function>f</function> as <varname>a</varname>
will not be defined).
<programlisting>function f() = (a:=5; g());
function g() = print(a);
f();
</programlisting>
</para>
<para>
When you set a variable inside a function, it will only be seen
inside the function, including all function calls that are made
inside this function. This is where GEL differs from a language
such as C. One could describe local variables as being semi global
in this sense. For example the following code will print out 5.
but the function <function>g</function> cannot be called on the
top level as <varname>a</varname> will not be defined.
If you define a variable inside a function it will override
any variables defined in calling functions. For example,
we modify the above code and write:
<programlisting>function f() = (a:=5; g());
function g() = print(a);
a:=10;
f();
</programlisting>
This code will still print out 5. But if you call
<function>g</function> outside of <function>f</function> then
you will get a printout of 10. Note that
setting <varname>a</varname>
to 5 inside <function>f</function> does not change
the value of <varname>a</varname> at the top (global) level,
so if you now check the value of <varname>a</varname> it will
still be 10.
</para>
<para>
Function arguments are exactly like variables defined inside
the function, except that they are initialized with the value
that was passed to the function. Other than this point, they are
treated just like all other variables defined inside the
function.
</para>
<para>
Suppose you assign a value to an identifier inside a function,
and this identifier is also used for a global variable, or a
variable set in a calling function. Then this has the effect of
creating a new local variable inside the function. For example
the following code will print out 6 and not 5.
<para>
Functions are treated exactly like variables. Hence you can
locally redefine functions. Normally (on the top level) you
cannot redefine protected variables and functions. But locally
you can do this. Consider the following session:
<screen><prompt>genius> </prompt><userinput>function f(x) = sin(x)^2</userinput>
= (`(x)=(sin(x)^2))
<prompt>genius> </prompt><userinput>function f(x) = sin(x)^2</userinput>
= (`(x)=(sin(x)^2))
<prompt>genius> </prompt><userinput>function g(x) = ((function sin(x)=x^10);f(x))</userinput>
= (`(x)=((sin:=(`(x)=(x^10)));f(x)))
<prompt>genius> </prompt><userinput>g(10)</userinput>
= 1e20
</screen>
</para>
<para>
Functions and variables defined at the top level are
considered global. They are visible from anywhere. As we
said the following function <function>f</function>
will not change the value of <varname>a</varname> to 5.
<programlisting>a=6;
function f() = (a:=5);
print(a);
f();
</programlisting>
</para>
<para>
Sometimes however it is neccessary to set
a global variable from inside a function. For this, use the
Sometimes, however, it is neccessary to set
a global variable from inside a function. When this behaviour is needed,
use the
<function>set</function> function. Passing a string or a quoted identifier to
this function sets the variable globally. For example, to set
this function sets the variable globally (on the top level).
For example, to set
<varname>a</varname> to the value 3 you could call:
<programlisting>set(`a,3)
</programlisting>
......@@ -1874,8 +1913,30 @@ or:
<para>
The <function>set</function> function always sets the toplevel
global. There is no way to set a local variable in some function
from a subroutine. For this you must use passing by reference.
from a subroutine. If this is required, must use passing by
reference.
</para>
<para>
So to recap in a more technical language: Genius operates with
different numberred contexts. The top level is the context 0
(zero). Whenever a function is entered, the context is raised,
and when the function returns the context is lowered. A function
or a variable is always visible from all higher numbered contexts.
When a variable was defined in a lower numbered context, then
setting this variable has the effect of creating a new local
variable in the current context number and this variable
will now be visible from all higher numbered contexts.
</para>
<para>
There are also true local variables which are not seen from
anywhere but the current context. Also when returning functions
by value it may reference variables not visible from higher context
and this may be a problem. See the sections
<link linkend="genius-gel-true-local-variables">True
Local Variables</link> and
<link linkend="genius-gel-returning-functions">Returning
Functions</link>.
</para>
</sect1>
<sect1 id="genius-gel-returning">
......@@ -2068,8 +2129,10 @@ else
to some parameters. The tricky bit is what variables does the
function see. The way this works in GEL is that when a function
returns another function, all identifiers referenced in the
function body are prepended a private dictionary of the returned
function. So the function will see all variables that were in scope
function body that went out of scope
are prepended a private dictionary of the returned
function. So the function will see all variables that were in
scope
when it was defined. For example we define a function which
returns a function which adds 5 to its argument.
<programlisting>function f() = (
......@@ -2087,16 +2150,17 @@ g(5)
<para>
One thing to note is that the value of <varname>k</varname>
that is used is the one that's in effect when the
<function>f</function> returns. So for example
<function>f</function> returns. For example:
<programlisting>function f() = (
k = 5;
r = `(x) = (x+k);
k = 10;
k := 5;
function r(x) = (x+k);
k := 10;
r
)
</programlisting>
will return a function that adds 10 to its argument rather than 5.
This is because the extra dictionary is created only when the context
will return a function that adds 10 to its argument rather than
5. This is because the extra dictionary is created only when
the context
in which the function was defined ends, which is when the function
<function>f</function> returns. This is consistent with how you
would expect the function <function>r</function> to work inside
......@@ -2106,9 +2170,131 @@ g(5)
no longer exists. Variables
used in the function that are in still valid contexts will work
as usual, using the current value of the variable.
The only difference is with global variables and functions.
All identifiers that referenced global variables at time of
the function definition are not added to the private dictionary.
This is to avoid much unnecessary work when returning functions
and would rarely be a problem. For example, suppose that you
delete the "k=5" from the function <function>f</function>,
and at the top level you define <varname>k</varname> to be
say 5. Then when you run <function>f</function>, the function
<function>r</function> will not put <varname>k</varname> into
the private dictionary because it was global (toplevel)
at the time of definition of <function>r</function>.
</para>
<para>
Sometimes it is better to have more control over how variables
are copied into the private dictionary. Since version 1.0.7,
you can specify which
variables are copied into the private dictionary by putting
extra square brackets after the arguments with the list of
variables to be copied separated by commas.
If you do this, then variables are
copied into the private dictionary at time of the function
definition, and the private dictionary is not touched afterwards.
For example
<programlisting>function f() = (
k := 5;
function r(x) [k] = (x+k);
k := 10;
r
)
</programlisting>
will return a function that when called will add 5 to its
argument. The local copy of <varname>k</varname> was created
when the function was defined.
</para>
<para>
When you want the function to not have any private dictionary
when put empty square brackets after the argument list. Then
no private dictionary will be created at all. Doing this is
good to increase efficiency when a private dictionary is not
needed or when you want the function to lookup all variables
as it sees them when called. For example suppose you want
the function returned from <function>f</function> to see
the value of <varname>k</varname> from the toplevel despite
there being a local variable of the same name during definition.
So the code
<programlisting>function f() = (
k := 5;
function r(x) [] = (x+k);
r
);
k := 10;
g = f();
g(10)
</programlisting>
will return 20 and not 15, which would happen if
<varname>k</varname> with a value of 5 was added to the private
dictionary.
</para>
</sect1>
<sect1 id="genius-gel-true-local-variables">
<title>True Local Variables</title>
<para>
When passing functions into other functions, the normal scoping of
variables might be undesired. For example:
<programlisting>k := 10;
function r(x) = (x+k);
function f(g,x) = (
k := 5;
g(x)
);
f(r,1)
</programlisting>
you probably want the function <function>r</function>
when passed as <function>g</function> into <function>f</function>
to see <varname>k</varname> as 10 rather than 5, so that
the code returns 11 and not 6. However, as written, the function
when executed will see the <varname>k</varname> that is
equal to 5. There are two ways to solve this. One would be
to have <function>r</function> get <varname>k</varname> in a
private dictionary using the square bracket notation section
<link linkend="genius-gel-returning-functions">Returning
Functions</link>.
</para>
<para>
But there is another solution. Since version 1.0.7 there are
true local variables. These are variables that are visible only
from the current context and not from any called functions.
We could define <varname>k</varname> as a local variable in the
function <function>f</function>. To do this add a
<command>local</command> statement as the first statement in the
function (it must always be the first statement in the function).
You can also make any arguments be local variables as well.
That is,
<programlisting>function f(g,x) = (
local g,x,k;
k := 5;
g(x)
);
</programlisting>
Then the code will work as expected and prints out 11.
Note that the <command>local</command> statement initializes
all the refereced variables (except for function arguments) to
a <constant>null</constant>.
</para>
<para>
If all variables are to be created as locals you can just pass an
asterix instead of a list of variables. In this case the variables
will not be initialized until they are actually set of course.
So the following definition of <function>f</function>
will also work:
<programlisting>function f(g,x) = (
local *;
k := 5;
g(x)
);
</programlisting>
</para>
<para>
It is good practice that all functions that take other functions
as arguments use local variables. This way the passed function
does not see implementation details and get confused.
</para>
</sect1>
<sect1 id="genius-gel-startup-procedure">
<title>GEL Startup Procedure</title>
<para>
......@@ -2807,9 +2993,12 @@ typsetting in LaTeX, MathML (XML), or in Troff.</para>
<chapter id="genius-about">
<title>About &app;</title>
<para> &app; was written by Ji&#345;&iacute; (George) Lebl (<email>jirka@5z.com</email>). The history of &app; goes back to late 1997. It was the first
calculator program for GNOME, but it then grew beyond being just a desktop calculator. To find more information about &app;, please visit the <ulink url="http://www.jirka.org/genius.html" type="http">Genius Web
page</ulink>.
<para> &app; was written by Ji&#345;&iacute; (George) Lebl
(<email>jirka@5z.com</email>). The history of &app; goes back to late
1997. It was the first calculator program for GNOME, but it then grew
beyond being just a desktop calculator. To find more information about
&app;, please visit the <ulink url="http://www.jirka.org/genius.html"
type="http">Genius Web page</ulink>.
</para>
<para>
To report a bug or make a suggestion regarding this application or
......@@ -2824,6 +3013,11 @@ calculator program for GNOME, but it then grew beyond being just a desktop calcu
<ulink url="ghelp:gpl" type="help">link</ulink>, or in the file
COPYING included with the source code of this program. </para>
<para>Ji&#345;&iacute; Lebl was during various parts of the development
partially supported for the work by NSF grant DMS 0900885 and
the University of Illinois at Urbana-Champaign. The software has
been used for both teaching and research.</para>
</chapter>
</book>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment