[plt-dev] ANN: formlet*

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Fri May 28 16:14:09 EDT 2010

I've just pushed an update to formlets to make them a lot more useful,
IMHO. Here's a quote from the new documentation:

----

6.2 Static Syntactic Shorthand

Most users will want to use the syntactic shorthand for creating formlets.

(formlet rendering-xexpr yields-expr)

Constructs a formlet with the specified rendering-xexpr and the
processing result is the evaluation of the yields-expr expression. The
rendering-xexpr form is a quasiquoted syntactic X-expression, with
three special caveats:

,{=> formlet-expr name} embeds the formlet given by formlet-expr; the
result of processing this formlet is available in the yields-expr as
name.

,{=> formlet-expr (values name ...)} embeds the formlet given by
formlet-expr; the results of processing this formlet is available in
the yields-expr as name ....

(#%# xexpr ...) renders an X-expression forest.

These forms may not appear nested inside unquote or unquote-splicing.
For example, this is illegal:

  (formlet (div ,@(for/list ([i (in-range 10)])
                    `(p ,(text-input . => . name))))
           name)

6.3 Dynamic Syntactic Shorthand

The formlet syntax is too restrictive for some applications because it
forces the rendering to be syntactically an X-expression. You may
discover you want to use a more "dynamic" shorthand.

(formlet* rendering-expr yields-expr)

Constructs a formlet where rendering-expr is evaluated (with caveats)
to construct the rendering and the processing result is the evaluation
of the the yields-expr expression. The rendering-expr should evaluate
to an "X-expression" that may embed the results of the following forms
that only have meaning within formlet*:

{=>* formlet-expr name} embeds the formlet given by formlet-expr; the
result of processing this formlet is available in the yields-expr as
name.

{=>* formlet-expr (values name ...)} embeds the formlet given by
formlet-expr; the results of processing this formlet is available in
the yields-expr as name ....

(#%# xexpr-expr ...) renders an X-expression forest.

Each of these forms evaluates to an opaque value that rendering-expr
may not manipulate in any way, but if it is returned to formlet* as
part of an "X-expression" it will be rendered and the formlets
processing stages will be executed, etc.

Because these forms may appear anywhere in rendering-expr, they may be
duplicated. Therefore, the formlet may render (and be processed)
multiple times. Thus, in yields-expr the formlet result names are
bound to lists of results rather than single results as in formlet.
The result list is ordered according to the order of the formlets in
the result of rendering-expr. For example, in

  (formlet* `(div ,@(for/list ([i (in-range 1 10)])
                      `(p ,(number->string i)
                          ,(text-input . =>* . name))))
            name)

name is bound to a list of strings, not a single string, where the
first element is the string that was inputted next to the string 1 on
the Web page.

In this example, it is clear that this is the desired behavior.
However, sometimes the value of a formlet’s result may be surprising.
For example, in

  (formlet* `(div (p ,(text-input . =>* . name)))
            name)

name is bound to a list of strings, because formlet* cannot
syntactically determine if the formlet whose result is bound to name
is used many times.

-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://teammccarthy.org/jay

"The glory of God is Intelligence" - D&C 93


Posted on the dev mailing list.