Using the version 3 dialect for PDB values
This describes a new and improved dialect of the ScriptFu language and how to port old scripts to the new dialect.
Note we say “version 3 dialect” to mean this optional dialect introduced along with GIMP version 3. Script-Fu per se is not versioned.
Pure Scheme is unaffected
The dialect only affects calls to the PDB. A script that uses the v3 dialect binds to certain PDB calls differently.
This means you can usually call most library scripts when using v3, since most library scripts are pure Scheme, that is, with no calls to the GIMP PDB.
Where to call script-fu-use-v3 in scripts
ScriptFu interprets the old version 2 dialect for PDB binding by default for compatibility reasons. The Script-Fu Console also always starts in the v2 dialect. In other words, it is optional to use the dialect.
To use it, call (script-fu-use-v3) at the beginning of the
run function. Example:
(define (script-fu-testv3 img drawables )
(script-fu-use-v3) ; <<<
(let* (
...After a call to script-fu-use-v3,
ScriptFu interprets the new dialect globally (that is: even
for other functions defined in the same script but lexically
outside the function where the dialect is set) until the
script finishes, or until the script calls (script-fu-use-v2).
More details below.
Details of the implementation
Both script-fu-use-v2 and script-fu-use-v3 always return the empty list(). But they have different side-effects on the state of the interpreter.
A call to script-fu-use-v3 sets a flag in the state of the interpreter. When the flag is set, the interpreter binds arguments to PDB calls slightly differently:
- Single return values from the PDB are not wrapped in lists.
- Boolean return values from the PDB are bound to #t and #f.
- Boolean values to the PDB can be #t and #f (this is optional).
Similarly, a call to script-fu-use-v2 clears the flag and restores the interpreter state to binding using the v2 dialect.
Plans for the future
The long-term goal is for the v3 dialect to be the only dialect of ScriptFu, since it is shorter and more natural for Scheme programmers as you will see below.
You should write any new scripts in the v3 dialect, and call script-fu-use-v3.
You should also plan on porting existing scripts to the v3 dialect, since, as said, eventually ScriptFu may obolete the v2 dialect.
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
)A call to a PDB procedure returning a single value
A call to a PDB procedure returning e.g. a single integer
(set! (width (car (gimp-drawable-get-width pic-layer))))must become
(set! (width (gimp-drawable-get-width pic-layer)))The PDB call returns a single integer, so no car is needed.
A call to a PDB procedure returning a list
(set! brushes (car (gimp-brushes-get-list)))must become:
(set! brushes (gimp-brushes-get-list))Formerly, the PDB procedure returned a list wrapped in a list, i.e. ((…)) In the v3 dialect, it returns just a list, i.e. (…) which is a single value, a single container.
A call to a PDB procedure returning a list, getting the first element
(set! first-brush (caar (gimp-brushes-get-list)))Gets the first brush in GIMP. This must become:
(set! first-brush (car (gimp-brushes-get-list)))The call to caar is consecutive calls to car, and you must eliminate the first call to car.
A call to a PDB procedure returning boolean
(if (= (gimp-image-is-rgb image) TRUE) ...must become:
(if (gimp-image-is-rgb image) ...The PDB procedure returns a boolean, which is bound to #t or #f, the usual symbols for Scheme truth.
If it is a call to a PDB procedure taking a boolean, you should (but are not required to) eliminate most uses of symbols TRUE and FALSE from a script using v3 dialect. To not repeat ourselves, see: FALSE and TRUE symbols are deprecated
Does not require changes to calls to PDB procedures returning void
You should not need to change scripts on calls to PDB procedures returning C void because a script should not be examining the result.
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 () i.e. nil in v3 dialect.