Here an attempt to describe my work related about frontend in Scheme. I am not aware of related work in Scheme
outside HOP which I believe its scheme incarnation is not maintained.

We could also list Scheme implementation that can run the browser?

Feel free to add it to the wiki if you find it worth it.


# frontend

Review of existing work related to building frontend using Scheme
programming language.

## server-side rendering

The idea here is to render the html that will be used by the browser
in the server.

### Scheme XML

Scheme SXML looks like the following:

```scheme
(html
  (head
    (title "Hello, scheme web"))
  (body (@ (class "index"))
    (h1 "Hello, " (b "scheme") "web!")))
```

There is variation of that sxml syntax that is based on skribe reader
syntax that allows to easily embed tags inside strings delimited by
square brackets using a comma to escape the enclosing string.  The
above would be written in skribe syntax as follow:

```scheme
(html
  (head
    (title "Hello, scheme web"))
  (body (@ (class "index"))
    (h1 [Hello, ,(b [scheme]) web!])))
```

This is really interesting when (a lot of) html is written by hand,
which is not the case of modern web.

## client-side rendering

This is the *de facto* standard approach to do frontend webdev since
the last argument against it is not relevant anymore, that is search
engines are able to index frontend rendered fully client side.  Also,
the limitation of search engines is not applicable to the majority of
webdev that happens in the walled gardens behind login pages
ie. entreprise applications. Those are not meant to be indexed by
search engines.

### forward.scm

- [website](https://hyperdev.fr/defunct-forward.scm/)
- [github](https://github.com/amirouche/defunct-forward.scm)
- [todomvc](https://github.com/amirouche/scheme-todomvc)

This is an experiment to get to understand how Elm does what it does.
The above todomvc is a direct port of Elm architecture that is purely
functional. It was described as cumbersome by its author and was later
revised what became the `forward.scm` framework. It rely on
BiwaScheme.  HTML is described by SXML syntax. snabbdom JavaScript
library is used to patch the DOM. It support browser back button.

The gist of that approach is best described by the `%create-app` procedure:

```scheme
(define (%create-app container init view)
  (let ((model (init)))  ;; init model
    ;; create a procedure that allows to create new green threads
    (letrec ((spawn (lambda (timeout proc args)
                      (set-timeout (lambda () (apply (proc model spawn) args)) timeout)))
             ;; lambda used to wrap event callback
             (make-controller (lambda (proc)
                                (js-closure
                                 (lambda args
                                   (let ((new (apply (proc model spawn) args)))
                                     (when new
                                       (set! model new)
                                       (render)))))))
             ;; rendering pipeline
             (render (lambda ()
                       (let ((sxml (view model make-controller)))
                         (set! container (patch container (sxml->h sxml)))))))

      ;; change procedure allows to sneak into the app closure
      (lambda (proc)
        (let ((new (proc model spawn)))
          (when new
            (set! model new)
```

Its website try hard to explain how to use it. Later work based on
that approach revealed a race condition that was fixed by asking
controllers to return synchronous procedures dubbed transfomers.
See [ff.js](https://github.com/amirouche/ff.js#ffjs). As of yet
that work was not adapted to Scheme.

### cons

- [website](http://scheme-lang.com/cons/)
- [github](https://github.com/amirouche/scheme-lang/tree/master/cons)

This approach rely on chibi scheme wasm build. It use ReactJS. It does
not support XHR as of yet.

Here the event loop:

```scheme
(define (create-app init view)
  (let ((model (init))
        (callbacks '()))
      (let loop ()
        (set! callbacks (render! model))
        (wait-on-event!) ;; yields control back to the browser
        (let ((event (string-eval-script "document.scheme")))
          (set! model (control model callbacks event))
          (loop)))))
```

## mixed

## others