Update of /project/rdnzl/cvsroot/RDNZL/doc In directory common-lisp.net:/tmp/cvs-serv26247/doc
Modified Files: index.html Log Message: delegate fixes (Dominic Robinson), version 0.8.0
Date: Fri Jan 13 08:06:34 2006 Author: eweitz
Index: RDNZL/doc/index.html diff -u RDNZL/doc/index.html:1.3 RDNZL/doc/index.html:1.4 --- RDNZL/doc/index.html:1.3 Mon Nov 21 15:03:43 2005 +++ RDNZL/doc/index.html Fri Jan 13 08:06:34 2006 @@ -104,7 +104,7 @@ <li><a href="#delivery">Saving images and application delivery</a> <ol> <li><a href="#shutdown-rdnzl"><code>shutdown-rdnzl</code></a> - <li><a href="#init-rdnzl"><code>shutdown-rdnzl</code></a> + <li><a href="#init-rdnzl"><code>init-rdnzl</code></a> </ol> </ol> <li><a href="#details">Implementation details and things to watch out for</a> @@ -307,7 +307,7 @@ </pre>
and evaluate <code>(RUN-APROPOS-FORM)</code>. If you want to try this -several times start the function in its own thread. In AllegroCL or LispWorks +several times, start the function in its own thread. In AllegroCL or LispWorks that'd be:
<pre> @@ -373,7 +373,7 @@ <br> <br><h3><a class=none name="download">Download and installation</a></h3>
RDNZL together with this documentation can be downloaded from -<a href="http://weitz.de/files/RDNZL.tar.gz">http://weitz.de/files/RDNZL.tar.gz</a>, the current version is 0.7.1. It +<a href="http://weitz.de/files/RDNZL.tar.gz">http://weitz.de/files/RDNZL.tar.gz</a>, the current version is 0.8.0. It doesn't depend on any other Lisp libraries. The C++ source for the shared library <code>RDNZL.dll</code> can be downloaded separately from <a href="http://weitz.de/files/RDNZL_cpp.tar.gz">http://weitz.de/files/RDNZL_cpp.tar.gz</a> but you don't need this archive @@ -399,7 +399,7 @@ For questions, bug reports, feature requests, improvements, or patches please use the <a href="http://common-lisp.net/mailman/listinfo/rdnzl-devel">rdnzl-devel -mailing list</a>. If you want to be notified about future releases +mailing list</a>. If you want to be notified about future releases, subscribe to the <a href="http://common-lisp.net/mailman/listinfo/rdnzl-announce">rdnzl-announce mailing list</a>. These mailing lists and the CVS repository were made available thanks to @@ -416,7 +416,7 @@ The current status for the main Win32 Common Lisp implementations is as follows: <ul> -<li><a href="http://www.cormanlisp.com/">Corman Common Lisp</a>: Corman Lisp is fully supported thanks to help of Roger Corman. +<li><a href="http://www.cormanlisp.com/">Corman Common Lisp</a>: Corman Lisp is fully supported thanks to the help of Roger Corman.
<li><a href="http://ecls.sourceforge.net/">ECL</a>: I'm not familiar enough with ECL to port RDNZL myself. Please send patches if you know how to do it. @@ -431,7 +431,7 @@ </ul> All implementation-specific parts of RDNZL are located in files called <code>port-acl.lisp</code>, <code>port-ccl.lisp</code>, <code>port-lw.lisp</code>, and so on. If you want to port RDNZL to -another Lisp it should suffice to just create the corresponding +another Lisp, it should suffice to just create the corresponding <code>port-xx.lisp</code> file for your implementation.
@@ -461,9 +461,9 @@ for the first argument of <a href="#invoke"><code>INVOKE</code></a>, <a href="#property"><code>PROPERTY</code></a>, and <a href="#field"><code>FIELD</code></a>) you can also provide the corresponding "native" Lisp objects as long as they can be converted to .NET objects by the function <a href="#box"><code>BOX</code></a>. On the other hand, if -a RDNZL function returns a .NET object it will be automatically +a RDNZL function returns a .NET object, it will be automatically translated to a Lisp object by <a href="#unbox"><code>UNBOX</code></a> if possible. If a RDNZL function -call doesn't return a result (i.e. if its return type is <code>System.Void</code>) +call doesn't return a result (i.e. if its return type is <code>System.Void</code>), then the keyword <code>:VOID</code> is returned. If a <code>NULL</code> object is returned, RDNZL returns <code>NIL</code> and <code>T</code> as a second return value because otherwise there'd be no difference from returning a false boolean value. @@ -528,7 +528,7 @@ constructor based on the signature determined by <code><i>args</i></code>. <code><i>type</i></code> can either be a container representing a .NET type or a string naming the type. <p> -If <code><i>type</i></code> is a delegate type then there should be exactly one more +If <code><i>type</i></code> is a delegate type, then there should be exactly one more argument to <code>NEW</code> and it must be a Lisp closure with a corresponding signature. This is how callbacks from .NET into Lisp are implemented. (See the <a href="#apropos">second example</a> above and look for <code>KeyPressEventHandler</code>.) </blockquote> @@ -560,8 +560,8 @@
<blockquote><br> Invokes the public .NET method named by the string <code><i>method-name</i></code>. If -<code><i>object</i></code> is a container an instance method is invoked. If <code><i>object</i></code> is a -string the static method of the type named by this string is invoked. +<code><i>object</i></code> is a container, an instance method is invoked. If <code><i>object</i></code> is a +string, the static method of the type named by this string is invoked. </blockquote>
<p><br>[Accessor] @@ -570,8 +570,8 @@
<blockquote><br> Gets or sets the public .NET property named by the string -<code><i>property-name</i></code>. If <code><i>object</i></code> is a container an instance property is -accessed. If <code><i>object</i></code> is a string the static property of the type named +<code><i>property-name</i></code>. If <code><i>object</i></code> is a container, an instance property is +accessed. If <code><i>object</i></code> is a string, the static property of the type named by this string is accessed. </blockquote>
@@ -581,8 +581,8 @@
<blockquote><br> Gets or sets the public .NET field named by the string <code><i>field-name</i></code>. If -<code><i>object</i></code> is a container an instance field is accessed. If <code><i>object</i></code> is a -string the static field of the type named by this string is accessed. +<code><i>object</i></code> is a container, an instance field is accessed. If <code><i>object</i></code> is a +string, the static field of the type named by this string is accessed. </blockquote>
<p><br>[Function] @@ -592,7 +592,7 @@
Makes a <em>pass-by-reference</em> type out of <code><i>object</i></code> and returns <code><i>object</i></code>. If -<code><i>object</i></code> is not a <a href="#objects">container</a> +<code><i>object</i></code> is not a <a href="#objects">container</a>, it'll be <a href="#box">boxed</a> first. This function makes only sense if <code><i>object</i></code> is used as an argument to <a href="#invoke"><code>INVOKE</code></a>! (And after <a href="#invoke"><code>INVOKE</code></a> has been @@ -707,7 +707,7 @@ <br><a class=none name="rdnzl-error-exception"><b>rdnzl-error-exception</b> <i> condition </i> => <i> exception</i></a>
<blockquote><br> -If <code><i>condition</i></code> is an error of type <a href="#rdnzl-error"><code>RDNZL-ERROR</code></a> then this function will +If <code><i>condition</i></code> is an error of type <a href="#rdnzl-error"><code>RDNZL-ERROR</code></a>, then this function will return the .NET exception object that was actually raised. </blockquote>
@@ -735,13 +735,13 @@ This is boring and error-prone, so RDNZL provides two ways to make it easier for you: You can <a href="#import-type"><em>import types</em></a> and you can <a href="#use-namespace"><em>use namespaces</em></a>. <p> -If you import a type RDNZL internally remembers its assembly-qualified +If you import a type, RDNZL internally remembers its assembly-qualified name and you can now use its <em>full name</em> (like <code>"System.Windows.Forms.Button"</code>) instead. <p> -If this is still too long for you you can <em>use</em> namespaces to further +If this is still too long for you, you can <em>use</em> namespaces to further abbreviate type names. So, if you are using the namespace -<code>"System.Windows.Forms"</code> you can just call the type <code>"Button"</code>. Note that +<code>"System.Windows.Forms"</code>, you can just call the type <code>"Button"</code>. Note that this'll only work for imported types, though.
<p><br>[Function] @@ -751,13 +751,13 @@ Imports the .NET type <code><i>type</i></code>, i.e. registers its name as one that can be abbreviated (see <a href="#use-namespace"><code>USE-NAMESPACE</code></a>) and creates a mapping from its short name to its assembly-qualified name (if necessary). If <code><i>type</i></code> is a -string and <code><i>assembly</i></code> is <code>NIL</code> then the function will try to create the +string and <code><i>assembly</i></code> is <code>NIL</code>, then the function will try to create the type from the string with the static .NET method <code>System.Type::GetType</code>. If <code><i>type</i></code> is a string and <code><i>assembly</i></code> is a container representing an -assembly then instead the .NET instance method +assembly, then instead the .NET instance method <code>System.Reflection.Assembly::GetType</code> will be used. If <code><i>type</i></code> is already -a .NET object (i.e. a <a href="#objects">container</a>) then the function will just register -its name. If <code><i>assembly</i></code> is a <em>true</em> value then the name will also be +a .NET object (i.e. a <a href="#objects">container</a>), then the function will just register +its name. If <code><i>assembly</i></code> is a <em>true</em> value, then the name will also be mapped to its assembly-qualified name. In all cases the type itself (as a container) will be returned. </blockquote> @@ -778,7 +778,7 @@
<blockquote><br> Imports all public types of the assembly <code><i>assembly</i></code> (a string or a -container). If <code><i>assembly</i></code> is a string then the assembly is first loaded +container). If <code><i>assembly</i></code> is a string, then the assembly is first loaded with <a href="#load-assembly"><code>LOAD-ASSEMBLY</code></a>. Returns <code><i>assembly</i></code> as a container. </blockquote>
@@ -844,7 +844,7 @@ <pre> (<a class=noborder href="#invoke">invoke</a> type "IsSubclassOf" other-type) </pre> -If the symbol starts with a percent or dollar sign then it is removed +If the symbol starts with a percent or dollar, sign then it is removed and the result is a call to <a href="#property"><code>PROPERTY</code></a> or <a href="#field"><code>FIELD</code></a> respectively:
<pre> @@ -852,7 +852,7 @@ [$textBox control] => (<a class=noborder href="#field">field</a> control "textBox") </pre>
-If the symbol contains a dot then in all three cases this'll result in +If the symbol contains a dot, then in all three cases this'll result in a static invocation where the part before the (last) dot is used as the name of the type:
@@ -862,7 +862,7 @@ [$OpCodes.Switch] => (<a class=noborder href="#field">field</a> "Opcodes" "Switch") </pre>
-If the symbol starts with a plus or minus sign then this sign is replaced +If the symbol starts with a plus or minus sign, then this sign is replaced with <code>"add_"</code> or <code>"remove_"</code> respectively. This is the convention used to add or remove event handlers:
@@ -939,10 +939,10 @@ <br><a class=none name="define-rdnzl-call"><b>define-rdnzl-call</b> <i> lisp-name (<tt>&key</tt> member-kind dotnet-name type-name doc-string) args</i> => <i> lisp-name </i></a>
<blockquote><br> -Defines a Lisp function named by the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_name">function name</a> <code><i>lisp-name</i></code> which invokes the .NET member named by the string <code><i>dotnet-name</i></code>. <code><i>member-kind</i></code> must be one of the keywords <code>:METHOD</code>, <code>:PROPERTY</code>, or <code>:FIELD</code> and obviously determines whether a method, a property, or a field is to be invoked - the default is <code>:METHOD</code>. If <code><i>type-name</i></code> is <code>NIL</code> (which is the default) an instance member is invoked, otherwise <code><i>type-name</i></code> should be a string naming a .NET type and a static member of this type is invoked instead. <code><i>doc-string</i></code>, if provided, should be a string, namely the documentation string for the Lisp function which is created. If <code><i>doc-string</i></code> is <code>NIL</code> (which is the default) a generic documentation string will be created. +Defines a Lisp function named by the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_name">function name</a> <code><i>lisp-name</i></code> which invokes the .NET member named by the string <code><i>dotnet-name</i></code>. <code><i>member-kind</i></code> must be one of the keywords <code>:METHOD</code>, <code>:PROPERTY</code>, or <code>:FIELD</code> and obviously determines whether a method, a property, or a field is to be invoked - the default is <code>:METHOD</code>. If <code><i>type-name</i></code> is <code>NIL</code> (which is the default), an instance member is invoked, otherwise <code><i>type-name</i></code> should be a string naming a .NET type and a static member of this type is invoked instead. <code><i>doc-string</i></code>, if provided, should be a string, namely the documentation string for the Lisp function which is created. If <code><i>doc-string</i></code> is <code>NIL</code> (which is the default), a generic documentation string will be created. <p> -If <code><i>dotnet-name</i></code> is <code>NIL</code> (which is the default) then the name of the .NET member will be created from <code><i>lisp-name</i></code> be the following rules: -Take the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_2.htm">symbol name</a> of <code><i>lisp-name</i></code> and if it does <em>not</em> consist solely of hyphens and single-case letters just return it. Otherwise remove the hyphens and downcase all letters except for the first one and those that follow a hyphen - these are upcased. If lisp-name is a list <code>(SETF <i>symbol</i>)</code> then we use <code><i>symbol</i></code> instead of <code><i>lisp-name</i></code>. Here are some examples (note that the package doesn't matter): +If <code><i>dotnet-name</i></code> is <code>NIL</code> (which is the default), then the name of the .NET member will be created from <code><i>lisp-name</i></code> be the following rules: +Take the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_2.htm">symbol name</a> of <code><i>lisp-name</i></code> and if it does <em>not</em> consist solely of hyphens and single-case letters, just return it. Otherwise remove the hyphens and downcase all letters except for the first one and those that follow a hyphen - these are upcased. If lisp-name is a list <code>(SETF <i>symbol</i>)</code>, then we use <code><i>symbol</i></code> instead of <code><i>lisp-name</i></code>. Here are some examples (note that the package doesn't matter): <p> <table border=1 cellspacing=1 cellpadding=3> <tr><th><code><i>lisp-name</i></code> </th><th> <code><i>dotnet-name</i></code></th></tr> @@ -980,7 +980,7 @@ sure that no references to .NET objects remain in the image and finally call <a href="#shutdown-rdnzl"><code>SHUTDOWN-RDNZL</code></a> prior to saving or delivering. <p> -If you restart the image or start the executable make sure to call +If you restart the image or start the executable, make sure to call <a href="#init-rdnzl"><code>INIT-RDNZL</code></a> before accessing any RDNZL functionality. That should do the trick. <p> @@ -993,7 +993,7 @@ <blockquote><br> Prepares RDNZL for delivery or image saving. After calling this function RDNZL can't be used anymore unless <a href="#init-rdnzl"><code>INIT-RDNZL</code></a> is called -again. If <code><i>no-gc</i></code> is <code>NIL</code> (the default) a full garbage collection is +again. If <code><i>no-gc</i></code> is <code>NIL</code> (the default), a full garbage collection is also performed. </blockquote>
@@ -1013,10 +1013,10 @@ the <a href="http://www.cliki.net/AMOP">MOP</a> to map .NET types to CLOS classes. I have removed this code in favor of a simpler approach because using the MOP results in a lot of overhead at runtime and doesn't work well with application -delivery. In fact, a lot of design decisions in RDNZL are based on the +delivery. In fact, a lot of the design decisions in RDNZL are based on the fact that I want to be able to easily deliver small executables. If it were just for speed and/or convenience, RDNZL would look differently. <p> -If you're concerned about speed keep in mind that calls into .NET are +If you're concerned about speed, keep in mind that calls into .NET are expensive because a lot of marshalling of arguments is happening behind the scenes and the system deploys the .NET reflection API at runtime. It is advisable to keep interaction between .NET and Lisp out @@ -1024,7 +1024,7 @@ fully in .NET. <p> If you want to know more about the way methods are -looked up in RDNZL read <a href="http://www.rivendell.ws/dot-scheme/scheme-workshop-2003-paper.pdf">Pedro Pinto's paper</a> +looked up in RDNZL, read <a href="http://www.rivendell.ws/dot-scheme/scheme-workshop-2003-paper.pdf">Pedro Pinto's paper</a> about the implementation of <a href="http://www.rivendell.ws/dot-scheme/">Dot-Scheme</a> the basics of which apply to RDNZL as well. <p> @@ -1046,10 +1046,21 @@ used. Currently, the only way to avoid these problems with cyclic references is: "So don't do that!" <p> +If .NET calls back into Lisp from a "foreign" thread (one that wasn't +created by Lisp), this'll not work in some implementations. +Specifically, <a +href="http://common-lisp.net/pipermail/rdnzl-devel/2006-January/000048.html%22%3Ea... +Dominic Robinson has pointed out</a>, there might be GC issues in this +case. +See <a href="http://weitz.de/lw-callbacks/">here</a> +and <a +href="http://common-lisp.net/pipermail/rdnzl-devel/2005-December/000044.html%22%3E...</a> +for possible workarounds for LispWorks. +<p> About the name: It was pretty clear to me from the beginning that the name of the library should be "<a href="http://globalia.net/donlope/fz/songs/RDNZL.html">RDNZL</a>." -However, I'm not sure what this acronym exactly stands for. Surely "L" is +However, I'm not sure what this acronym exactly stands for. Surely, "L" is for "Lisp" and "DN" is for "DotNet". The rest? You'll figure it out... :)
<br> <br><h3><a class=none name="ack">Acknowledgements</a></h3> @@ -1063,7 +1074,7 @@ <p> Thanks to Charles A. Cox for the port of RDNZL to AllegroCL. Thanks to Vasilis Margioulas for the CLISP port. Thanks to Roger Corman for his help with the CCL port. Thanks to Franz Inc. (and particularly Jans Aasman) for supporting the development of RDNZL. <p> -$Header: /project/rdnzl/cvsroot/RDNZL/doc/index.html,v 1.3 2005/11/21 14:03:43 eweitz Exp $ +$Header: /project/rdnzl/cvsroot/RDNZL/doc/index.html,v 1.4 2006/01/13 07:06:34 eweitz Exp $ <p><a href="http://weitz.de/index.html">BACK TO MY HOMEPAGE</a>
</body>