From ff1ad6d60541ff4ec7892871bc7e1e68a9c3eb7a Mon Sep 17 00:00:00 2001 From: lloyd konneker Date: Sun, 13 Oct 2024 14:03:08 -0400 Subject: [PATCH] ScriptFu: update devel docs re version 3 changes --- .../script-fu-author-guide.md | 504 +++++++++--------- plug-ins/script-fu/docs/using-v3-binding.md | 110 +++- 2 files changed, 355 insertions(+), 259 deletions(-) diff --git a/devel-docs/GIMP3-plug-in-porting-guide/script-fu-author-guide.md b/devel-docs/GIMP3-plug-in-porting-guide/script-fu-author-guide.md index 6a73a16edc..3570b77f31 100644 --- a/devel-docs/GIMP3-plug-in-porting-guide/script-fu-author-guide.md +++ b/devel-docs/GIMP3-plug-in-porting-guide/script-fu-author-guide.md @@ -1,14 +1,62 @@ # Guide to changes to ScriptFu v3 for script authors -*Draft, until GIMP 3 is final. FIXME: rearrange and rename the cited documents* - ## About The audience is authors of Scriptfu plugins. This discusses how to edit v2 scripts so they will run in GIMP 3. +It also discusses enhancements to ScriptFu and its language. -This is only about changes to ScriptFu proper. -The GIMP PDB, which you can call in scripts, has also changed. +## Quickstart + +A lucky few existing scripts may work in GIMP v3 without change. + +### Required changes + +Some changes are *required* in existing plugins: + + - many PDB procedures are obsolete or renamed, or their signature changed + - the symbol SF-VALUE is obolete + +Once you edit a script for these changes, the script won't work in GIMP v2. + +Most scripts will require edits due to changed PDB API. + +### Optional changes + +Other changes to scripts are *optional*. +Such changes use improved features of ScriptFu. + +In approximate order of importance: + + - you can install scripts like plugins in other languages + - you can use new, specific registration functions instead of the generic script-fu-register + - scripts can use the new mult-layer selection feature of GIMP + - scripts can use a v3 dialect having more natural binding of return values from PDB calls + - the symbolic constants TRUE and FALSE are deprecated, except for SF-TOGGLE + - a script can *quit* with an error code + - a script can call *display* to print to the terminal + +Enhancements to ScriptFu might not affect an existing plugin. +You need only understand those enhancements when you want to use them. + +### Why these changes now? + +GIMP 3 is a major version change with new features. +A major version allows breaking API, +meaning old plugins and scripts might not work. + +The GIMP developers understand these changes may be onerous. +Script developers might need to maintain two different versions of their scripts. +Some users will stick with GIMP 2 for a while and some will switch to GIMP 3. + +A major version is necessary to move forward. +The situation is similar to the disruption caused by the move from Python 2 to 3. + +## Changed PDB API + +*You must edit your scripts to conform to version 3 of the PDB API.* + +The GIMP PDB (Programmers Data Base), that you can call in scripts, has changed in GIMP version 3. That also may require you to edit scripts. - For changes in signatures of PDB procedures, @@ -16,40 +64,13 @@ That also may require you to edit scripts. - For added, removed, and replaced PDB procedures, see devel-docs/GIMP3-plug-in-porting-guide/removed_functions.md -## Quickstart +Some of the changes are for the multi-layer select feature of GIMP 3. +Many PDB procedures now take a container (a Scheme vector) of drawables +instead of a single drawable. -A lucky few existing scripts may work in GIMP v3. +## SF-VALUE type of argument is obsolete -Some changes are most likely to break an existing plugin.: - - - many PDB procedures are obsolete or renamed, or their signature changed - -Once you edit a script for these changes, the script won't work in GIMP v2. - -Other changes: - - - you can use new, specific registration functions instead of the generic script-fu-register - - you can install scripts like plugins in other languages - - scripts can use the new mult-layer selection feature of GIMP - - a script can abort with an error message - - a script's settings are more fully saved - -Those changes might not affect an existing plugin. -You need only understand those changes when you want to use new features of GIMP. - -A word of explanation: the GIMP developers understand these changes may be onerous. -Script developers might need to maintain two different versions of their scripts. -Some users will stick with GIMP 2 for a while and some will switch to GIMP 3. -But GIMP 3 is a major version change with new features. -A clean break is necessary to move forward with improvements. -The situation is similar to the disruption caused by the move from Python 2 to 3. - -## Deprecated ScriptFu constants - -### SF-VALUE kind of argument is deprecated - -The symbol SF-VALUE is deprecated. -You can edit v2 scripts and replace that symbol. +*You must edit v2 scripts and replace the symbol SF-VALUE.* In v2, SF-VALUE declared a formal argument that is an unquoted, arbitrary string. Usually, SF-VALUE was used for an integer valued argument. @@ -60,9 +81,9 @@ but the widget let you enter any text into the string. You usually will replace it with an SF-ADJUSTMENT kind of formal argument, where the "digits" field of the SF-ADJUSTMENT is 0, meaning no decimal places, i.e. integer valued. -You must also add the other fields, e.g. the lower and upper limits. +You must also provide other fields, e.g. the lower and upper limits. -A script that has been edited to replace SF-VALUE with SF-ADJUSTMENT +A script that has SF-VALUE replaced with SF-ADJUSTMENT will remain compatible with GIMP 2. Example: @@ -83,7 +104,7 @@ used SF-VALUE to declare a formal argument that is float valued: Here, the 1 denotes: show 1 decimal place, for example "45.0", in the dialog widget. -#### Use SF-STRING for some use cases +### Use SF-STRING for some use cases In v2, a SF-VALUE argument let a user enter executable Scheme code, say "'(1 g 1)", which is a list literal, @@ -92,7 +113,7 @@ That use is no longer possible. If you must do that, use SF_STRING to get a string, and then your plugin can eval the string. -#### Arbitrary precision floats +### Arbitrary precision floats In v2, a SF-VALUE argument let a user enter a float with arbitrary precision, e.g. "0.00000001" @@ -114,204 +135,33 @@ If you actually need arbitrary precision, use SF_STRING to get a string, and then your plugin can eval the string to get a Scheme numeric of the maximum precision that Scheme supports. -#### Rationale +### Rationale Formerly, a SF-VALUE argument let a user enter garbage for an argument, which caused an error in the script. -SF-ADJUSTMENT is more user-friendly. - -### FALSE and TRUE symbols deprecated - -FALSE and TRUE symbols are deprecated in the ScriptFu language. -They never were in the Scheme language. -Instead, you can use the Scheme language symbols #f and #t. - -In ScriptFu v2, FALSE was equivalent to 0 -and TRUE was equivalent to 1. -But FALSE was not equivalent to #f. - -Formerly, you could use the = operator to compare to FALSE and TRUE. -The = operator in Scheme is a numeric operator, not a logical operator. -Now you can use the eq? or eqv? operators. - -In Scheme, all values are truthy except for #f. -The empty list is truthy. -The numeric 0 is truthy. -Only #f is not truthy. - -A PDB procedure returning a single Boolean (a predicate) -returns a list containing one element, for example (#f) or (#t). - -#### Rationale - -The ScriptFu language is simpler and smaller; TRUE and FALSE duplicated concepts already in the Scheme language. - -#### Example changes - -Declaring a script: - - SF-TOGGLE "Gradient reverse" FALSE - => - SF-TOGGLE "Gradient reverse" #f - -Calling a PDB procedure taking a boolean: - - (gimp-context-set-feather TRUE) - => - (gimp-context-set-feather #t) - -Logically examining a variable for truth: - - (if (= shadow TRUE) ... - => - (if shadow ... - - -## v3 binding of PDB return values - -TODO this needs rewrite. When first written, we anticipated -a breaking change to the binding. -Now the binding version is a choice, -settable at runtime. -Scripts can opt to use the new binding. - -### In scripts, calls to PDB procedures that return boolean yield (#t) or (#f) - -In ScriptFu v2, PDB procedures returning a boolean returned 1 or 0 to a script, -that is, numeric values. -Those were equal to the old TRUE and FALSE values. - -Remember that a call to the PDB returns a list to the script. -So in ScriptFu v3, -a PDB procedure that returns a single boolean (a predicate function) -returns (#t) or (#f), a list containing one boolean element. - -#### Rationale - -#t and #f are more precise representations of boolean values. -0 and 1 are binary, but not strictly boolean. - -The ScriptFu language is smaller if concepts of truth are not duplicated. - -#### Example changes - -Calling a PDB procedure that is a predicate function: - - (if (= FALSE (car (gimp-selection-is-empty theImage))) ... - => - (if (car (gimp-selection-is-empty theImage)) ... - -Here, the call to the PDB returns a list of one element. -The "car" function returns that element. -The "if" function evaluates that element for truthy. - -Note that to evaluate the result of a PDB call for truth, -you should just use as above, and not use "eq?" or "eqv?". -Such a result is always a list, and a list is truthy, -but not equivalent to #t. -In the ScriptFu console: - - >(eq? #t '()) - #f - >(eqv? #t '()) - #f - -## Use script-fu-script-abort to throw an error - -The function "script-fu-script-abort" is new to ScriptFu v3. - -It causes the interpreter to stop evaluating a script -and yield an error of type GimpPDBStatus. -That is, it immediately returns an error to the caller. -It is similar to the "return" statement in other languages, -but the Scheme language has no "return" statement. - -The function takes an error message string. - -When the caller is the GIMP app, -the GIMP app will show an error dialog -having the message string. - -When the caller is another PDB procedure (a plugin or script) -the caller must check the result of a call to the PDB -and propagate the error. -ScriptFu itself always checks the result of a call to the PDB -and propagates the error, -concatenating error message strings. - -The function can be used anywhere in a script, -like you would a "return" statement in other languages. - -Alternatively, a script can yield #f to yield a PDB error. -See below. - -#### Rationale - -Formerly, scripts usually called gimp-message on errors, -without yielding an error to the caller. -It was easy for a user to overlook the error message. -An abort shows an error message that a user must acknowledge -by choosing an OK button. - -#### Example - -This script defines a PDB procedure that aborts: - - (define (script-fu-abort) - (script-fu-script-abort "Too many drawables.") - (gimp-message "this never evaluated") - ) - ... - -## A script can yield #f to throw an error - -Here we use the word "yield" instead of the word "return". -Neither "yield" nor "return" are reserved words in the Scheme language. - -A Scheme text evaluates to, or yields, the value of its last expression. -Any value other than #f, even the empty list or the list containing #f, -is truthy. - -A ScriptFu plugin -(the PDB procedure that a script defines in its run func) -whose last evaluated expression is #f -will yield an error of type GimpPDBStatus. - -If you don't want a ScriptFu plugin to yield an error, -it must not evaluate to #f. -Most existing plugins won't, since their last evaluated expression -is usually a call to the PDB yielding a list, which is not equivalent to #f. - -*Remember that ScriptFu does not yet let you declare PDB procedures -that return values to the caller. -That is, you can only declare a void procedure, having only side effects. -So to yield #f does not mean to return a boolean to the caller.* - -*Also, you can define Scheme functions internal to a script -that yield #f but that do not signify errors. -It is only the "run func" that defines a PDB procedure that, -yielding #f, yields a PDB error to the caller.* - - -#### Examples - - (define (script-fu-always-fail) - (begin - ; this will be evaluated and show a message in GIMP status bar - (gimp-message "Failing") - ; since last expression, is the result, and will mean error - #f - ) - ) +SF-ADJUSTMENT or SF-STRING is more user-friendly. ## You can optionally install scripts like plugins in other languages -In v3 you can install ScriptFu scripts to a /plug-ins directory. +*We recommend this for new plugins.* + +In v3 you can install ScriptFu scripts to a /plug-ins directory, +like plugins in other languages. +This helps isolate plugins. + You must edit the script to include a shebang in the first line: #!/usr/bin/env gimp-script-fu-interpreter-3.0 + ;!# Close comment started on first line. -In v2 all ScriptFu scripts were usually installed in a /scripts directory. +If the script has translatable strings, it should also have a second line +as above, to accomodate parsing by gettext. +(Note that ScriptFu doesn't actually support multi-line comments using #!, +and this is a trick to fool gettext, which parses a script as if +it did support multi-line comments.) + + +In v2 all ScriptFu scripts were installed in a /scripts directory. In v3 you may install ScriptFu scripts with a shebang in a subdirectory of a /plug-ins directory. @@ -325,37 +175,43 @@ A script file must: An example path to a script: - ~/.config/GIMP/2.99/plug-ins/myScript/myScript.scm + ~/.config/GIMP/2.99/plug-ins/script-fu-my/script-fu-my.scm -Such a script will execute in its own process. +The advantage of installing a script in the /plug-ins directory is that +such a script will execute in its own process. If it crashes, it doesn't affect GIMP or other scripts. -In v2, all scripts in the /scripts directory are executed by the long-lived -process "extension-script-fu." + +Conversely, in v2, all scripts in the /scripts directory +are executed by the long-lived process "extension-script-fu." If one of those scripts crash, menu items implemented by ScriptFu dissappear from the GIMP app, and you should restart GIMP. -## Changes in registration functions +It is only a convention to name scripts starting with "script-fu-". -ScriptFu defines "registration" functions, letting you declare a plugin PDB procedure. +## Using new registration functions -ScriptFu v2 has only *script-fu-register*. -It was a generic function used to declare procedures that are either: +*We recommend this.* -* generic procedures (operating without an image.) -* filters/renderers (operating on an image) +New registration functions let a plugin dialog have a new look-and-feel +and improved settings. +ScriptFu "registration" functions let you declare a plugin PDB procedure, +and how it's dialog will look. -The new registration functions are: +ScriptFu v3 has two new registration functions: * *script-fu-register-procedure* * *script-fu-register-filter* -The new registration functions let a plugin have a new look-and-feel -and improved settings. - Terminology: you *declare* a plugin's attributes and signature using a registration function. You *define* a run func with a similar signature. ScriptFu *registers* the plugin in the PDB. +ScriptFu v2 has only *script-fu-register*. +It is a generic function used to declare procedures that are either: + +* generic procedures (operating without an image.) +* filters/renderers (operating on an image) + ### Registration function *script-fu-register* is now deprecated. **You should not use script-fu-register in new ScriptFu scripts.** @@ -604,4 +460,166 @@ That is a programming error in the calling procedure. A well-written called plugin that is passed more drawables than declared should return an error instead of processing any of the drawables. -Similarly for fewer than declared. \ No newline at end of file +Similarly for fewer than declared. + +## Using the v3 dialect for PDB return values + +*We recommend this for new scripts.* + +ScriptFu in GIMP version 3 will optionally interpret a v3 dialect. +The dialect is more natural to the Scheme language. +The dialect affects the binding of return values from calls to the PDB. + +A script opts into the v3 dialect at runtime by calling script-fu-use-v3 +at the beginning of the run func.. + +The advantage of the v3 dialect is that scripts are smaller, +with fewer calls to car. +Also, you can more naturally examine boolean values. + +For more information, see the document in the GIMP source /plugins/script-fu/docs/using-v3-binding.md + +## FALSE and TRUE symbols are deprecated + +*We recommend not using TRUE and FALSE in new scripts, except for an SF-TOGGLE argument.* + +FALSE and TRUE symbols are deprecated in the ScriptFu language. +They never were in the Scheme language. + +Instead, you should use the v3 dialect +and use the Scheme language symbols #f and #t. + +In ScriptFu, FALSE is 0 +and TRUE is 1. +But FALSE is not equivalent to #f. + +You must use the = operator to compare to FALSE and TRUE. +FALSE and TRUE are numeric. +The = operator in Scheme is a numeric operator, not a logical operator. + +In Scheme, all values are truthy except for #f. +The empty list is truthy. +The numeric 0 is truthy. +Only #f is not truthy. + +In the v3 dialect, a PDB procedure returning a single Boolean (a predicate) +returns one element, for example #f or #t. + +In the v2 dialect, it still returns (0) or (1), +that is, numeric 0 or 1 wrapped in a list. + +*You still need to compare boolean SF_TOGGLE arguments to a script with TRUE and FALSE. +They are not #t and #f*. + +#### Rationale + +The ScriptFu language is simpler and smaller; TRUE and FALSE duplicated concepts already in the Scheme language. + +#### Example changes + +Declaring a script's SF_TOGGLE arguments can still use TRUE and FALSE. + + SF-TOGGLE "Gradient reverse" FALSE + +Comparing a boolean argument to a script *must* remain as in v2 dialect: + + (if (= should-invert TRUE) + ; do invert ) + +Calling a PDB procedure taking a boolean: + + (gimp-context-set-feather TRUE) + => + (gimp-context-set-feather #t) + +Logically examining a variable for truth: + + (if (= shadow TRUE) ... + => + (if shadow ... + +## Using the quit function to abort a script + +*We recommend using quit to declare errors* along with gimp-message. + +The function "quit" is in Scheme. +It causes a script to exit i.e. return to the system. +The function can be used anywhere in a script, +like you would a "return" statement in other languages. + +In ScriptFu v3 it causes the interpreter to stop interpreting a script +and yield an error of type GimpPDBStatus. +That is, it immediately returns an error to the GIMP app or other caller. +The GIMP app will show an error message including the phrase +"script quit with error code x." + +When the caller is another PDB procedure (a plugin or script) +the caller should check the result of a call to the script +and propagate the error. +ScriptFu itself always checks the result of a call to the PDB +and propagates the error, +concatenating error message strings. + +In ScriptFu v2, a call such as (quit -1) did abort the script, +but did not return an error to the caller +(usually the GIMP app) +and did not return the error code. + +### A script doesn't return a value + +In ScriptFu, a script returns void. +It is not possible to define a plugin script that returns useful values. +Note that script registration functions do not declare return values. +Scripts only have side effects. + +The last expression in a script plugin is *not* the value of the plugin, +as it is in Scheme. + +As a PDB procedure, a script can succeed or fail. +But success does not depend on the value of the last evaluated expression. +To make a script return failure, you should call the quit function. + +#### Rationale + +Formerly, scripts usually called gimp-message on errors, +without yielding an error to the caller. +It was easy for a user to overlook the error message. + +You should still call gimp-message just before calling quit, +with an informative error message. +The numeric code that quit prints is not informative to users, +only to the script author. + +#### Example + +This script quits early: + + (define (script-fu-my-plugin) + ... + (gimp-message "Too many drawables.") + (quit -1) + (display "this never evaluated") + ) + ... + +## Using the display function to write to the terminal + +*We recommend using the display function to help debug a script or to log, +but not to prompt for user input.* + +Display is a Scheme function, in the R5RS standard. +It should write a string to any open terminal (e.g stdout on Linux.) + +In ScriptFu v3, it does. +You will see the output in any terminal in which the GIMP app was started +(which is optional, and not usually done on a graphical desktop.) + +In ScriptFu v2, it did not write to a terminal. +Display wrote to a stream which was returned to the GIMP app, and usually discarded (unless an error occurred, and then the stream +was the prefix of the error message.) + +Example: + + (display "The script is here") (newline) + +Note that displayln is not in ScriptFu. \ No newline at end of file diff --git a/plug-ins/script-fu/docs/using-v3-binding.md b/plug-ins/script-fu/docs/using-v3-binding.md index 6ee08336ff..dcb0f91d3b 100644 --- a/plug-ins/script-fu/docs/using-v3-binding.md +++ b/plug-ins/script-fu/docs/using-v3-binding.md @@ -1,11 +1,13 @@ -# The version 3 dialect of the ScriptFu language +# Version 3 of the ScriptFu language ## About -This describes a new dialect of ScriptFu, -used when a script calls: (script-fu-use-v3). +This describes a new dialect of the ScriptFu language. +ScriptFu interprets the dialect after a script calls: (script-fu-use-v3). The new dialect is more like Scheme and makes scripts shorter. The dialect only affects calls to the PDB. +ScriptFu inteprets the old version 2 by default, +unless a script calls script-fu-use-v3. The audience is script authors and other developers. @@ -14,13 +16,20 @@ This describes the new dialect and how to port old scripts to the new dialect. ## Quick Start +ScriptFu inteprets the old version 2 by default, +unless a script calls script-fu-use-v3. +After a call to script-fu-use-v3, +ScriptFu interprets the new dialect until the script finishes, +or until the script calls script-fu-use-v2. +A script can switch back and forth between dialects at runtime. + A script that calls: ``` (script-fu-use-v3) ``` binds to certain PDB calls differently: -1. PDB procedures that return single values return just that single value, +1. PDB procedures that return single values (atoms) return just that single value, *not wrapped in a list.* Formerly, every PDB call returned a list (possibly nesting more lists.) @@ -39,12 +48,13 @@ until you call *script-fu-use-v2.* ## Where to call *script-fu-use-v3* in scripts -Call *script-fu-use-v3* early. -This sets the dialect version for the remaining interpretation of the script. Call *script-fu-use-v3* at the beginning of the run function. +This sets the dialect version for the remaining interpretation +of the script. !!! Do not call *script-fu-use-v3* at the top level of a script. -This has no effect, since it is only executed in the query phase. +This has no effect, since it is only executed in the query phase +of a plugin. The interpreter starts at the run function during the run phase. *The interpreter always starts interpreting each script in the v2 dialect. @@ -60,24 +70,26 @@ Example: (let* ( ... ``` -### Technically speaking +### Scope The dialect version has "execution scope" versus "lexical scope." Setting the dialect version is effective even for other functions defined in the same script but lexically outside the function where the dialect is set. +You only need to call script-fu-use-v3 once, +not in every defined function. ## Don't call v2 scripts from v3 scripts When using the v3 dialect, -you can't call plugin scripts or other library scripts that depend on the v2 dialect. +you cannot call plugin Scheme scripts or other library scripts that are in the v2 dialect. And vice versa. -(When a script calls a PDB procedure that is a script, +(When a script calls a PDB procedure that is a Scheme script, a new interpreter process is *NOT* started.) For example, a new plugin script should not call the PDB procedure -script-fu-add-bevel because it is implemented in ScriptFu Scheme +script-fu-add-bevel because it is a Scheme script in v2 dialect and for example has: ``` @@ -121,6 +133,30 @@ In the ScriptFu Console: TRUE and FALSE symbols may become obsolete in the future. +## An argument of type SF-TOGGLE is FALSE or TRUE, not #f or #t + +The v3 dialect does not affect the binding of arguments to a script. +So the value of an argument of type SF-TOGGLE is zero or one, +not #f or #t. + +You must continue to check boolean arguments to a script like this: + +``` +(define script-fu-my-plugin (should-invert) + (if (= should-invert TRUE) + ( + ; do invert + ))) + +(script-fu-register-procedure "script-fu-my-plugin" + "My plugin..." + ... + SF-TOGGLE "Invert?" FALSE +) +``` +This may change when in the future we obsolete v2 dialect +and the symbols TRUE and FALSE. + ## Plans for the future This dialect is shorter and more natural for Scheme programmers. @@ -133,9 +169,51 @@ You should write any new scripts in the v3 dialect, and call *script-fu-use-v3*. You should plan on porting existing scripts to the v3 dialect, -since eventually ScriptFu might not support v2 dialect. +since eventually ScriptFu may obolete the v2 dialect. + +## Example conversions from v2 to v3 dialects + +### An example script using v3 dialect + +``` +; !!! Usually not call (script-fu-use-v3) here in global scope + +(define script-fu-my-plugin (should-invert) + ; the body switches to the v3 dialect + (script-fu-use-v3) + + (let* ( + ; don't need a car, unlike v2 + (angle gimp-context-get-brush-angle))) + + ; call PDB returning boolean + ; don't need (= (car (gimp-context-get-feather)) TRUE) + (if (gimp-context-get-feather) + ; do feather + ) + + ; boolean arg to script is still C notion of truth + (if (= should-invert TRUE) + ( + ; do invert + )) + + ; calling a v2 plugin, temporarily switch to v2 dialect + (script-fu-use-v2) + (script-fu-add-bevel ...) + + ; rest of script in v3 dialect + (script-fu-use-v3) + ... +) + +(script-fu-register-procedure "script-fu-my-plugin" + "My plugin..." + ... + SF-TOGGLE "Invert?" FALSE +) +``` -## Example conversions from v2 to v3 ### A call to a PDB procedure returning a single value @@ -211,7 +289,7 @@ and you must eliminate the first call to *car*. ## Knowing what constructs need conversion You *should* (but are not required to) -eliminate all uses of symbols TRUE and FALSE from a script +eliminate most uses of symbols TRUE and FALSE from a script using v3 dialect. You should eliminate many, *but not all*, uses of the *car* function wrapping a call to the PDB, @@ -234,7 +312,7 @@ Return Values Additional Information ``` This also returns a single value. -The single value is a list i.e. container. +But the single value is a list i.e. container, of strings. In the v2 dialect, this returned a list wrapped in a list, for example (("foo" "bar")). @@ -247,7 +325,7 @@ You should not need to change scripts on calls to PDB procedures returning C voi Some scripts might examine the result of a call to a void PDB procedure, thinking that (#t) is the success of the call, but that is a misconception and should be fixed. -Calls to PDB procedures that return C void return (#t) in v2 and the empty list (), sometimes called nil, in v3 dialect. +Calls to PDB procedures that return C void return (#t) in v2 and the empty list () i.e. nil in v3 dialect. ## Details of the implementation