marketplace-2014/marketplace/scribblings/background.scrbl

103 lines
3.4 KiB
Plaintext
Raw Normal View History

2013-05-08 11:22:34 +00:00
#lang scribble/manual
@require[racket/include]
@include{prelude.inc}
@title{Background}
@section{Network programming in the small}
Even the simplest of programs can be seen as a network. This program
sends a message containing @racket[3] and @racket[4] to @racket[+],
and awaits a reply message, which contains @racket[7]:
@interaction[(+ 3 4)]
Subroutines are network services. Here, when the message @racket[3] is
sent to @racket[add-four-to], it delegates to @racket[+]:
@interaction[(define (add-four-to n) (+ n 4))
(add-four-to 3)]
@note{In π-calculus encodings of programs, replication and state are
made explicit.} Immutable programs (of which stateless programs are a
special case) are easily able to be @emph{replicated}; programs using
mutable state, however, must be fixed in place. In fact, strictly
speaking, it is the @emph{state} that must be fixed in place, not the
program @emph{manipulating} the state. In the following program, the
mutable @racket[total] variable must not be replicated:
@interaction[(define accumulate
(let ((total 0))
(lambda (n)
(set! total (+ total n))
total)))
(accumulate 3)
(accumulate 4)
(accumulate 0)]
It would be a mistake to simply replace each occurrence of
@racket[accumulate] with its definition, since three separate
@racket[total] locations would be created. However, there is no
problem replicating the @racket[lambda] term, so long as
@racket[total] always refers to the same location:
@interaction[(define total 0)
((lambda (n) (set! total (+ total n)) total) 3)
((lambda (n) (set! total (+ total n)) total) 4)
((lambda (n) (set! total (+ total n)) total) 0)]
Programs raise exceptions to signal partial failure:
@interaction[(define accumulate
(let ((total 0))
(lambda (n)
(when (negative? n)
(error 'accumulate "n must be non-negative!"))
(set! total (+ total n))
total)))
(accumulate 3)
(accumulate -2)]
Programs can handle exceptions to @emph{contain} partial failure:
@interaction[(with-handlers ([exn:fail? (lambda (e) 'ok)])
(error 'oh-dear))]
Partial failures interact with shared, mutable state in unpredictable
ways, especially in larger programs that combine stateful subprograms.
Programmers often ignore issues of security and trust between
subprograms within a larger program. Most programming languages
entirely lack any means of securely isolating subprograms from each
other, leading to predictable failures. Even memory-safe languages
such as Racket, Java and .NET only offer weak techniques for securely
composing mutually suspicious subprograms. Techniques such as avoiding
@emph{ambient authority} and using @emph{object capabilities} to
compose subprograms
TODO ^
@section{Network programming in the large}
Programs which engage in I/O are very obviously part of a network:
@racketblock[(define username (read-line))
(printf "Hello, ~a!\n" username)]
But look closely! There is a difference here between the kind of communication
This program is more obviously composed of a number of moving pieces:
@interaction[(let ((b (box 3)))
(set-box! b (+ (unbox b) 4))
(unbox b))]
@interaction[(define (add-three-to b)
(set-box! b (+ (unbox b) 3)))
(define (add-four-to b)
(set-box! b (+ (unbox b) 4)))
(define my-box (box 0))
(add-three-to my-box)
(add-four-to my-box)
(unbox my-box)]