Implementing such a Web client-server file viewer with a single Hop
code is almost as straightforward as
implementing it for a single computer, because HTML is built in and
execution partitioning between servers and clients is automatic. Figure 1
shows a complete Hop solution to this
problem.
Hop identifiers can contain special characters such as “<” and “?”. In
Hop, directory?, string=?, and
<SPAN> are legal identifiers. In the example, <BROWSER> is the name of a
variable bound to a function that creates an HTML div element.
HTML objects are created by
Hop functions with the same names
(<DIV>…), (<SPAN> …), among others; no HTML closure is needed because the code deals with parenthetical functional expressions instead of
texts. The full power of Scheme is used
to build DIVs and SPANs. The <dir-entry> and <file-entry> auxiliary functions are used to build fragments of the final HTML document.
The map operation in the main <directory> function is used to build
the global HTML page out of these
HTML fragments, with help from the
Hop sort function to sort the printed
output alphabetically. Figure 2 shows
how values produced by the <div-entry> function are compiled into
HTML and JavaScript.
The and constructs appearing at
line 7 of Figure 1 are the multitier pro-
gramming operators. Let us explain
how they work. Expressions prefixed
by are client-side expressions evalu-
ated by the browser; unannotated ex-
pressions are evaluated on the server.
Compiling is done on the server. A
client code is seen as a value, com-
puted or elaborated by the server and
automatically shipped to the client on
demand. The construct is used to
inject a server value within the client
code at elaboration time. For example,
~(alert $(hostname))prints the
server name on the client screen. In the
example of Figure 1, line 7 provokes
the injection of an automatically gen-
erated service named anonymous314
in the HTML excerpt of Figure 2. The
~-prefixed expression at line 7 speci-
fies the action to be executed by the cli-
ent when the user clicks on a directory.
The action invokes the anonymous
service, called by the client and run on
the server.
Figure 3. A Web file browser.
(<HTML>
(<TABLE>
(<TR>
(<TD> (<BROWSER> :class "usr" :path "/usr"))
(<TD> (<BROWSER> :class "local" :path "/usr/local")))))
Figure 1: A Web file browser.
Figure 4. Modified file browser for file size.
(define (<file-entry> path)
(<DIV> :data-hss-tag "file-entry"
(basename path)
(<SPAN> (round (file-size path) 1024)))) ;; <-- added line for size