This application shows how to build Akka application with Spray API. In this tutorial, I am going to use Spray's spray-can
, spray-httpx
, spray-json
artefacts with the Akka artefacts to build an application that receives HTTP requests with JSON payloads, unmarshals the JSON into instances of our own classes (case class
es, to be exact). It then sends these instances to the appropriate Actor
s for processing. When the actors reply, it marshals the responses into JSON, and uses that to construct the HTTP responses.
I shall also explore the Cake pattern, which enable us to separate out parts of the system so that I can "assemble" the parts of the cake into the components that I ultimately run or test.
Let me begin by showing the overall structure of the application we are building.
In this template tutorial, you will learn how to construct Akka-based applications; how to test them (using TestKit and Specs2; and how to provide RESTful HTTP API using Spray.
I begin by constructing the core of our system. It contains the top-level MessengerActor
and RegistrationActor
. The MessengerActor
contains two child actors, the EmailActor
and the SMSActor
.
The top-level actors live in the CoreActors
trait. This trait's self-type annotation defines that instances that mix in this trait must also mix in some subtype of the Core
trait.
This is a rather long description of the first two lines of the CoreActors
trait.
trait CoreActors {
this: Core =>
}
Because of the self-type declaration, I have access to all members of the Core
trait in the CoreActors
trait. Our Core
trait defines only one member, namely implicit def system: ActorSystem
; and I use the system
to create the top-level actors.
The CoreActor
in its entirety is therefore
trait CoreActors {
this: Core =>
val registration = system.actorOf(Props[RegistrationActor])
val messenger = system.actorOf(Props[MessengerActor])
}
I also provide the implementation of the Core
trait that actually constructs the ActorSystem
. I call this trait BootedCore
. It instantiates the ActorSystem
and registers the JVM termination hook to shutdown the ActorSystem
on JVM exit.
trait BootedCore extends Core {
implicit val system = ActorSystem("akka-spray")
sys.addShutdownHook(system.shutdown())
}
As you can see, the BootedCore
is a straight-forward implementation of the Core
trait. If I now wanted, I could write a simple application that starts our actors by mixing in the traits.
object Cli extends App with BootedCore with CoreActors
I must be mindful of the initialization order, though. It would be an error to write object Cli extends App with CoreActors with BootedCore
It is because the BootedCore
's implementation of the system
method is implicit val system = ActorSystem("akka-spray")
and if I write object Cli extends App with CoreActors with BootedCore
, the code in CoreActors
runs before the code in BootedCore
--meaning that when the code in CoreActors
runs, the value of the system
val
is still null
.
Having to worry about the order in which I mix in the traits is wholly unsatisfactory. I need to find a way in which a val
can be evaluated immediately when its value is required, but once it is evaluated, it behaves like an ordinary val
. Rephrasing, I want a member whose value will be computed and remembered on first access, and subsequent accesses will return the remembered value.
To do this in Scala, I mark the val
as _lazy_
. Thus, our BootedCore
's system
becomes
trait BootedCore extends Core {
implicit lazy val system = ActorSystem("akka-spray")
sys.addShutdownHook(system.shutdown())
}
Notice the lazy
keyword--now I am free to mix in the required traits in any order.
Let's now explore why I did so much code gymnastics. I could have just as easily defined the CoreActors
trait to contain all the code in Core
and BootedCore
.
The motivation was testing. When I am using Akka's TestKit, we construct a test-only ActorSystem
. This testing ActorSystem
allows us to test the actors as if the messages sent and received were method calls. In other words, the ActorSystem
in our tests uses the CallingThreadDispatcher
, making the message delivery synchronous.
As it happens, the TestKit
contains a member called system: ActorSystem
; and it matches the Core
trait. Therefore, it is easy to make our specification implement the Core
trait. This in turn means that our test satisfies the self-type annotation of the CoreActors
trait.
And thus, I can easily write a test for our entire application's structure.
class RegistrationActorSpec extends TestKit(ActorSystem()) with SpecificationLike with CoreActors with Core {
...
}
I extend the TestKit
class, which gives us access to all the underlying Akka's test mechanisms; I also mix in Specs2's SpecificationLike
, which gives us the convenient DSL for writing our test scenarios and assertions. Finally, because I am writing code to test my actors, I mix in the CoreActors
and Core
traits. I do not need to do any more work, because the member system: ActorSystem
fully implements the Core
trait. However, I need to implement the Core
trait to satisfy the self-type declaration of the CoreActors
.
I could have defined Core
to be structural type, in which case, I would not have to worry about implementing Core
here. If you want to try it out, remove the trait Core { ... }
and replace it with
package object core {
type Core = { def system: ActorSystem }
}
Here, the Core
type is a structural type, which says that Core
is anything which contains the system: ActorSystem
member.
The implementation of the actors is not particularly interesting. I will explore the common patterns of naming and structuring that I believe are useful; the implementation of the actors I leave to the readers.
I begin with the RegistrationActor
. Its purpose is to register the users in our system. The actor's companion object holds all the messages that the actor deals with. In code, the structure is
object RegistrationActor {
case class Register(user: User)
case object Registered
case object NotRegistered
}
class RegistrationActor extends Actor {
import RegistrationActor._
def receive: Receive = ???
}
This structure allows me to tidy up the messages and perhaps some utility functions in the future from the actor itself.
Onwards to the actor's implementation, then. As I said, it will be rather trivial, mainly demonstrating approaches & patterns. When it receives the Register
message, it performs the required processing and then replies to the sender with the outcome of the registration process.
class RegistrationActor extends Actor{
import RegistrationActor._
def receive: Receive = {
case Register(user) if user.email.isEmpty => sender ! Left(NotRegistered)
case Register(user) => sender ! Right(Registered)
}
}
I warned you, it is not very clever at all ).
RegistrationActor
As simple as the RegistrationActor
is, I can (and should) still test it. I can either test the actor in isolation, writing a unit test, or I can test our entire application, but focusing on the RegistrationActor
--an integration test.
I will show the integration test approach here.
To allow us to examine what happens in our actors, I need to use special--crippled-- ActorSystem
that processes the messages synchronously. To the code, then. We extend the TestKit
class and mix in the required traits to construct the test.
class RegistrationActorSpec extends TestKit(ActorSystem()) with SpecificationLike with CoreActors with Core {
sequential
private def mkUser(email: String): User = User(UUID.randomUUID(), "A", "B", email)
"Registration should" >> {
"reject invalid email" in {
registration ! Register(mkUser(""))
expectMsg(Left(NotRegistered))
success
}
"accept valid user to be registered" in {
registration ! Register(mkUser("jan@eigengo.com"))
expectMsg(Right(Registered))
success
}
}
}
This is the entire body of our test. I instantiate the actors in CoreActors
, satisfying the Core
self-type annotation by having the RegistrationActorSpec
implement the Core
trait. (Remember, I can do that just by writing with Core
, because TestKit
already contains the member system: ActorSystem
, which is all that is needed to fully implement Core
.)
Onwards. If you run the test, it will fail. It will complain about failing timeouts, namely
assertion failed: timeout (3 seconds) during expectMsgClass waiting for class core.RegistrationActor$NotRegistered$
And yet, if you place a breakpoint in the RegistrationActor
's receive
, you will see that it is indeed executing; replying to the sender
with the appropriate message.
The only conclusion is that the sender
itself is somehow broken. Indeed. Going back to our test, I write registration ! Register(mkUser(""))
. If you explore the !
function, you will see that it is a curried function, whose first parameter list is the message to be sent, and its second parameter list is the ActorRef
which represents the sender. It is marked as implicit
, but it also contains a default value. So, if no ActorRef
instance is available implicitly, the default value will be used instead. Unfortunately for me here, the default value is Actor.noSender
.
To fix the problem, all I need to do is have an implicit ActorRef
value. However, this ActorRef
should also somehow interact with the rest of the code in TestKit. Furtunately for the lazy, TestKit provides the ImplicitSender
trait, which makes the testActor
implicitly available; and the testActor
interacts with all the expect...
functions in TestKit.
class RegistrationActorSpec extends TestKit(ActorSystem())
with SpecificationLike with CoreActors with Core with ImplicitSender {
...
}
I mix in the ImplicitSender
and all is good
I am going to use most of the Spray components, namely
spray-io
for the low-level, asynchronous I/O,spray-http
for the HTTP protocol implementation on top of spray-io
,spray-routing
, which provides convenient DSL for mapping HTTP requests to functions,spray-httpx
for the unmarshalling and marshalling of the HTTP requests and responses,spray-json
for JSON marshallers and unmarshallersThis feels like quite a handful, but you will see that the code is rather succinct and, of course, type safe. Even more importantly, the Spray code does not interfere with the core of our system. The core can remain completely oblivious of the way in which it is exposed.
I continue to strictly separate the layers of (even if so trivial) application; therefore, I will separate the REST API from the code that starts the HTTP server hosting the API. In keeping with the rest of the system, I will split the layers into traits, giving me the Api
and Web
traits. As you can guess, the Api
trait contains just the REST API, and the Web
trait exposes the APIs in a real HTTP server.
To make the Api
trait work with the rest of the system, I will use the self-type annotation and require that the Api
trait is mixed in with CoreActors
and Core
. The Web
trait will need to be mixed in with Api
.
trait Api {
this: CoreActors with Core =>
...
}
And
trait Web {
this: Api with CoreActors with Core =>
...
}
All of this to enable me to write tests that exercise just the REST API, without the need to start the HTTP server and deal with the added complexity of real HTTP requests; and to allow me to write a subtype of App
that combines all the components and starts a real HTTP server; server, which hosts the API, which in turn uses the core actors to do the heavy processing. In code, the entire application is just one line
object Rest extends App with BootedCore with CoreActors with Api with Web
Amazing
Let's explore the Api
trait, which defines the REST endpoints. In keeping with the structure from the diagram, I have kept each endpoint in its own class. The Api
trait constructs the classes for these endpoints and then concatenates the routes they each expose. The RoutedHttpService
then routes the incoming HTTP requests accordingly.
trait Api extends RouteConcatenation {
this: CoreActors with Core =>
private implicit val _ = system.dispatcher
val routes =
new RegistrationService(registration).route ~
new MessengerService(messenger).route
val rootService = system.actorOf(Props(new RoutedHttpService(routes)))
}
I instantiate the RegistrationService
and the MessengerService
, giving each reference to the approprite ActorRef
from the CoreActors
. (I can do this, because the Api
trait declares the CoreActors
as its self-type.)
I will show the code and structure of the RegistrationService
, which is ever so slightly more complex than the code in MessengerService
. The motivation for the RegistrationService
is to have REST API that receives JSON payloads in that can be mapped to instances of the Register
case class.
{ "user": {
"id": "122fa630-92fd-11e2-9e96-0800200c9a66",
"firstName":"Jan",
"lastName":"Machacek",
<EMAIL_ADDRESS>} }
I expect replies to match the responses (Either[NotRegistered, Registered]
); the value on the left projection should result in HTTP status bad request; the value on the right projection should be HTTP OK. In our application, the value Left(NotRegistered)
should be represented as HTTP status 400
with JSON payload
{ "value": "NotRegistered" }
The Right(Registered)
should be represented as HTTP status 200
with JSON payload
{ "value": "Registered" }
Before I begin to worry about the marshalling and unmarshalling, let's deal with the actual HTTP requests. Spray-can deals with the low-level I/O of asynchronous HTTP (and SPDY) server; it then turns the HTTP requests and responses into HttpRequest
messages; the response sent to the sender is the HttpResponse
, containing the response entity, headers, etc.
Spray-http deals with convenient routing so that I don't have to implement actors that receive HttpRequest
s and reply to the sender with the raw HttpResponse
s; spray-httpx adds the marshalling and unmarshalling support.
Let's start working on the RegistrationService
. I will begin by using the routes.
class RegistrationService(registration: ActorRef)
(implicit executionContext: ExecutionContext)
extends Directives {
val route =
path("register") {
post {
complete {
"OK"
}
}
}
}
This is a good start. It clearly demonstrates the ease of Spray's routing. I say that on path register
, on HTTP method POST, I complete the request with body "OK"
. Unfortunately, the string "OK"
doesn't quite meet our requirement. To do so, I need to interpret the request as instance of Register
and turn our Either[NotRegistered.type, Registered.type]
into the response.
All of this requires some marshalling jiggery pokery. Firstly, I need to be able to turn the HTTP requests into instances of our types and then I need to be able to do the reverse. Spray provides pluggable marshalling mechanism to do that. The instances of the typeclasses Marshaller[A]
and Unmarshaller[A]
are responsible for performing the request entity -> our instance and our instance -> response entity transformations.
I will not get into a complex discussion of typeclasses; I will just say that typeclass defines behaviour for a certain type and a typeclass instance is the implementation of such behaviour. Spray includes the spray-json
library, which, together with the SprayJsonSupport
trait allows me to wire in spray-json
marshallers and unmarshallers and use them in my Spray code.
Without further delay, let me show you how it's done in code and then explore the details.
class RegistrationService(registration: ActorRef)(implicit executionContext: ExecutionContext)
extends Directives with DefaultJsonFormats {
import akka.pattern.ask
import scala.concurrent.duration._
implicit val timeout = Timeout(2.seconds)
implicit val userFormat = jsonFormat4(User)
implicit val registerFormat = jsonFormat1(Register)
implicit val registeredFormat = jsonObjectFormat[Registered.type]
implicit val notRegisteredFormat = jsonObjectFormat[NotRegistered.type]
implicit object EitherErrorSelector extends
ErrorSelector[NotRegistered.type] {
def apply(v: NotRegistered.type): StatusCode = StatusCodes.BadRequest
}
val route =
path("register") {
post {
handleWith { ru: Register =>
(registration ? ru).mapTo[Either[NotRegistered.type, Registered.type]]
}
}
}
}
Looking at the route
definition, the only difference is that I changed complete
to handleWith
; and then wired in the call to our RegistrationActor
.
Reading the code intuitively, I say that to handle requests to register on HTTP method post, I turn the request into Register
and then handleWith a function that returns a Future[Either[...]]
, which we turn into a response.
Intuition did not fail us. All I have to do is to implement the behaviour of turning the requests into our types and our types into responses. So, instances of typeclasses Those are the mysterious lines
implicit val userFormat = jsonFormat4(User)
implicit val registerFormat = jsonFormat1(Register)
implicit val registeredFormat = jsonObjectFormat[Registered.type]
implicit val notRegisteredFormat = jsonObjectFormat[NotRegistered.type]
You see, their types are RootJsonFormat[A]
, where A
is User
, Register
, and so on. RootJsonFormat[A]
contains functions that read JSON and write JSON; SprayJsonSupport
then contains further typeclass instances that implement Marshaller[A]
given JsonWriter[A]
, and Unmarshaller[A]
given JsonReader[A]
. Moving on, I can create other interesting marshalling typeclasses.
For example, if I know how to marshal some type A
, I also know how to marshal Seq[A]
, Future[A]
; if I know how to marshal some A
and B
, I can marshal Either[A, B]
, and so on. I am now ready to write a marshaller that marshals Either[A, B]
and, for the left values, it also indicates the corret HTTP status code. Its signature is rather scary
type ErrorSelector[A] = A => StatusCode
implicit def errorSelectingEitherMarshaller[A, B]
(implicit ma: Marshaller[A], mb: Marshaller[B], esa: ErrorSelector[A]):
Marshaller[Either[A, B]] =
Marshaller[Either[A, B]] { (value, ctx) =>
value match {
case Left(a) =>
val mc = new CollectingMarshallingContext()
ma(a, mc)
ctx.handleError(ErrorResponseException(esa(a), mc.entity))
case Right(b) =>
mb(b, ctx)
}
}
And breathe Now, I have a function errorSelectingEitherMarshaller[A, B]
that returns Marshalle[Either[A, B]]
. To be able to do that, it must know how to marshal A
and B
; and if I want to be able to indicate the status code, I must also be able to turn A
s into StatusCode
. That's what the three implicit parameters do I am asking the compiler to implicitly find an instance of Marshaller[A]
, Marshaller[B]
and ErrorSelector[A]
; in other words, instances of the Marshaller
and ErrorSelector
typeclasses for instances A
and B
.
To use, I must give the typeclass instance for ErrorSelector[A]
, where A
is NotRegistered.type
; I do so by defining a singleton
implicit object EitherErrorSelector extends ErrorSelector[NotRegistered.type] {
def apply(v: NotRegistered.type): StatusCode = StatusCodes.BadRequest
}
So, any NotRegistered
value is StatusCodes.BadRequest
.
To complete the picture, I must implement the Web
trait, which takes the rootService
in the Api
trait and hosts it in the spray-can
HTTP server. The good news is that the code gets simpler
trait Web {
this: Api with CoreActors with Core =>
IO(Http)(system) ! Http.Bind(rootService, "<IP_ADDRESS>", port = 8080)
}
I create the Http
extension, pass it to Akka's IO
machinery; and finally send it the Http.Bind
message to bind the rootService
to all interfaces, on port 8080
.
I am excited to present the final application that combines all our components in an HTTP server. It is
object Rest extends App with BootedCore with CoreActors with Api with Web
That's all there is to it. I have created an App
, mixed in all required traits and we're good to go.
Let's not stop here, though. Today's users expect good client applications, too. Note that, as usual, the Akka code does nothing special with the uploaded files; it simply demonstrates that we can acccept multipart/form-data
-encoded POST.
This is our AngularJS application in the browser. We press the Add files... button to add (images) that will be uploaded. When the users click the Start upload button, we start the uploads in parallel, but each POST contains one file. The Cancel upload button clears the form.
The requests are going to register/image
, so we need to add the appropriate handler to the RegistrationService
to handle POST to that path, to unmarshal the request as MultipartFormData
. We then complete
the request with the appropriate response.
class RegistrationService(registration: ActorRef)(implicit executionContext: ExecutionContext)
extends Directives with DefaultJsonFormats {
import akka.pattern.ask
import scala.concurrent.duration._
implicit val timeout = Timeout(2.seconds)
implicit val userFormat = jsonFormat4(User)
implicit val registerFormat = jsonFormat1(Register)
implicit val registeredFormat = jsonObjectFormat[Registered.type]
implicit val notRegisteredFormat = jsonObjectFormat[NotRegistered.type]
implicit object EitherErrorSelector extends ErrorSelector[NotRegistered.type] {
def apply(v: NotRegistered.type): StatusCode = StatusCodes.BadRequest
}
val route =
path("register") {
post {
handleWith { ru: Register =>
(registration ? ru).mapTo[
Either[NotRegistered.type, Registered.type]]
}
}
} ~
path("register" / "image") {
post {
entity(as[MultipartFormData]) { data =>
complete {
data.fields.get("files[]") match {
case Some(imageEntity) =>
val size = imageEntity.entity.buffer.length
println(s"Uploaded $size")
"OK"
case None =>
println("No files")
"Not OK"
}
}
}
}
}
}
This is the entire source code of the RegistrationService
to show you where the new code fits in. The new bit is the usage of entity(as[A]) { a => ... }
, which takes the posted HttpEntity
, finds the instance of the Unmarshaller
typeclass for the type A
. When the unmarshalling succeeds, it applies the given function { a => ... }
to complete the request. In our case, we have
path("register" / "image") {
post {
entity(as[MultipartFormData]) { data =>
complete {
data.fields.get("files[]") match {
case Some(imageEntity) =>
val size = imageEntity.entity.buffer.length
println(s"Uploaded $size")
"OK"
case None =>
println("No files")
"Not OK"
}
}
}
}
}
This means that on POST to register/image
, we unmarshal the entity as MultipartFormData
and apply the function
{ data =>
complete {
data.fields.get("files[]") match {
case Some(imageEntity) =>
val size = imageEntity.entity.buffer.length
println(s"Uploaded $size")
s"""{"size":$size}"""
case None =>
println("No files")
"""{"size":0}"""
}
}
}
To the successfully unmarshalled value. In that function, we complete
the request by--ultimately--returning either s"""{"size":$size}"""
or """{"size":0}"""
.
Hand-constructing JSON, XML, ..., anyting really, is a terrible idea. Let's get rid of those s"""{"size":$size}"""
and """{"size":0}"""
strings and replace them with a convenient case class.
case class ImageUploaded(size: Int)
We can easily define the JsonWriter
typeclass instance for the ImageUploaded
type by adding an implicit value of type JsonWriter[ImageUploaded]
; and this is exactly what the jsonFormat
functions do.
implicit val imageUploadedFormat = jsonFormat1(ImageUploaded)
So, we add the case class and the JsonWriter[ImageUpload]
typeclass instance, which allows us to get rid of the String
s in the complete
function.
class RegistrationService(registration: ActorRef)(implicit executionContext: ExecutionContext)
extends Directives with DefaultJsonFormats {
case class ImageUploaded(size: Int)
implicit val imageUploadedFormat = jsonFormat1(ImageUploaded)
...
val route =
...
path("register" / "image") {
post {
entity(as[MultipartFormData]) { data =>
complete {
data.fields.get("files[]") match {
case Some(imageEntity) =>
val size = imageEntity.entity.buffer.length
println(s"Uploaded $size")
ImageUploaded(size)
case None =>
println("No files")
ImageUploaded(0)
}
}
}
}
}
}
Now, this is better there are no String
s and we handle the file uploads quite nicely. Unfortunately, there are still too many notes. Dissecting the post
handler, we have
entity(as[MultipartFormData]) { data =>
complete {
ImageUploaded(...)
}
}
The entity(as[A]) { a: A => complete { ... } }
can be replaced with handleWith
the same code we use in the register
posts. And so, the final code is simply
path("register" / "image") {
post {
handleWith { data: MultipartFormData =>
data.fields.get("files[]") match {
case Some(imageEntity) =>
val size = imageEntity.entity.buffer.length
println(s"Uploaded $size")
ImageUploaded(size)
case None =>
println("No files")
ImageUploaded(0)
}
}
}
}
Now that we have the Spray application sorted out, let's tackle the JavaScript app. Its source is in src/main/angular
. The main components are index.html
and js/app.js
. One cannot just open the index.html
file in the browser. The other resources (JavaScripts, stylesheets) will not load properly, but even if they did, the browser would refuse to call our Spray server, because the locations do not match. Our Spray server runs on http://localhost:8080
, but the AngularJS application's location would be file:///.../index.html
.
To allow us to test it, we need to (easily) serve the AngularJS application as well as our Spray application on the same location. In this post, I will only tackle the development setup, leaving me space to post about the proper AWS setup in the future.
Let's use Apache to serve the AngularJS application at http://localhost/~USER/angular
and let's host the Spray application (or, in fact, anything that listens on port 8080
) at http://localhost/~USER/app
.
To make this happen, we'll enable Apache's per-user home pages and we'll drop in ProxyPass
and ProxyPassReverse
directives. On my machine, the configuration for $USER
lives in /etc/apache2/users/$USER.conf
.
Options Indexes Multiviews +FollowSymLinks
AllowOverride AuthConfig Limit
Order allow,deny
Allow from all
ProxyPass /~$USER/app/ http://localhost:8080/
ProxyPassReverse /~$USER/app/ http://localhost:8080/
Of course, you cannot use $USER
, you must replace it with your real username I don't really want to copy the src/main/angular
directory to the ~/Sites
directory, so I've added the +FollowSymLinks
directive and created a symbolic link in ~/Sites
to point to wherever I have src/main/angular
. In my case, the listing of ~/Sites
is
~/Sites$ ls -la
total 16
lrwxr-xr-x ... angular -> /.../akka-spray/src/main/angular
-rw-r--r-- ... index.html
Now, after adding this file and starting (or restarting) Apache sudo apachectl start
(or sudo apachectl restart
), you are ready to see the app by going to http://localhost/~USER/angular
.
So, you are now ready to go opening http://localhost/~USER/angular
shows the AngularJS application, where you can add as many files as you like, and clicking the Start upload button sends the files to the Spray application. The Spray application unceremoniously prints the file size I shall leave some interesting processing logic as exercise for the readers.
As usual, the source code is at https//github.com/eigengo/activator-akka-spray; feel free to report issues, or to send your contributions


HTML is the data format used to construct web pages. Using HTML elements, you can construct elaborate pages.
You can use CSS to add styling to your content, such as modified fonts and colors.


WITNESS LIST
State Affairs Committee
September 27, 2012 - 1:00 PM
Interim charge regarding state procurement
On:
Bishop, Ann (ERS)
Brantz, Gary (Health Care Service Corporation (Blue Cross Blue Shield of Texas))
Chaplin, Matt (TX General Land Office)
Dukes, Aundre (Texas Facilities Commission)
Guthrie, Brian (Teacher Retirement System of Texas)
James, Joe (Texas General Land Office)
Jones, Jennifer (Sunset Commission)
Keel, John (Texas State Auditor's Office)
Keel, Terry (Texas Facilities Commission)
Kukla, Robert (ERS)
Marshall, Bert (Blue Cross Blue Shield of Texas)
Pigott, Ron (Comptroller of Public Accounts, TPASS Division)
Quirk, Tom (United Healthcare)
Robinson, Karen (Dept. of Information Resources)
Zelinksky, Martin (Dept. of Information Resources)
Registering, but not testifying:
On:
Darr, Shyra (Texas Facilities Comm)
Ehlert, Richard (Texas Facilities Commission)
Green, Don (Teacher Retiruments System)
Jones, Betsey (TRS)
Jones, Paula (ERS)
Lacy, Michael (TX Facilities Commission)
Linder, Kelly (Texas State Auditor's Office)
Molina, Kay (Texas Facilities Commission)
Raff, John (Texas FAC. Commission)
Welch, Ken (Teacher Retirement System of Texas)
Young, John (State Auditor's Office)
1


Academic Manager
Student
Dashboard
Add a student
Exchange
Dashboard
Add an exchange student
Alma
Dashboard
Add an Alma
Lecturer
Dashboard
Add a Lecturer


The sutra means vertical and crosswise.
It is excellent for carrying out multiplications. It is based
on the following algebraic identity:
(ax+b)*(cx+d)=acx*x+(bc+ad)*x+bd
Using x=10 makes it immediately applicable to the decimal system that we
use.
Let us try the following:
037 (a=3, b=7)
x68 (c=6, d=8)
---
By conventional method it will be:
37
x68
----
0296
222
-----
2516
Let us see how it is with vertical and cross-wise
(1) First the vertical units place: 8*7=56
Put 6 down and carry 5 over ---6
(2) Add the carried over 5 to the cross multiplication of ad and bc i.e.
8x3+6x7+5=71
Put 1 down and carry 7 over --16
(3) Finally do the vertical for the 10s place.
Add carried over 7 to a*c i.e. 3*6+7=25
Put that down 2516
We have arrived at the solution in a "single" step!
A longer example of the same:
000345
x00789
------
003105
02760
2415
------
272205 (doing it conventionally)
By our newly learnt method:
9*5=45 (write 5 carry 4)
9*4+8*5+4=80 (write 0 carry 8)
9*3+8*4+7*5+8=102 (write 2 carry 10)
8*3+7*4+10=62 (write 2 carry 6)
7*3+6=27 (write it all since that is the last part)
One Step Answer: 272205
(ax*x+b*x+c)*(dx*x+e*x+f)=
adx^4+(ae+bd)x^3+(af+be+cd)x^2+(bf+ce)x+cf
And this can of course be extended to any number of digits trivially.


| Author | Matthew Schinkel - borntechi.com, copyright © 2011, all rights reserved. |
| Adapted-by | |
| Compiler | 2.4o |
This library reads temperature from TC77 through SPI. TC77 has a resolution of 0.0625C from -55C to +125C
TC77 temperature sensor library by Eur van Andel http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010750
This is a complete re-write of the orignal jallib TC77 library written by Eur van Andel.
No dependency found
var word _TC77_NEG25C = 0b1111001110000111
var word _TC77_POS25C = 0b0000110010000111
var word _TC77_POS125C = 0b0011111010000111
var word _TC77_NEG55C = 0b1110010010000111
tc77_read_celsius_sdword(sdword out temperature)
tc77_read_raw(word out raw)
tc77_read_celsius_sword(sword out temperature)
tc77_read_celsius_sbyte(sbyte out temperature)
tc77_celsius_sbyte'get() return sbyte
tc77_celsius_sword'get() return sword
tc77_celsius_sdword'get() return sdword
var word _TC77_NEG25C = 0b1111001110000111
No documentation found
var word _TC77_POS25C = 0b0000110010000111
constants
var word _TC77_POS125C = 0b0011111010000111
No documentation found
var word _TC77_NEG55C = 0b1110010010000111
No documentation found
tc77_read_celsius_sdword(sdword out temperature)
No documentation found
tc77_read_raw(word out raw)
Read raw data from TC77
tc77_read_celsius_sword(sword out temperature)
No documentation found
tc77_read_celsius_sbyte(sbyte out temperature)
procedures for compatibility
tc77_celsius_sbyte'get() return sbyte
Read Temperature (sbyte). Temperature x 1. Example temperature output: 26
tc77_celsius_sword'get() return sword
Read Temperature (sword). Temperature x 100. Example temperature output: 2662
tc77_celsius_sdword'get() return sdword
Read Temperature (sdword). Temperature x 10000. Example temperature output: 266875
| 16f877a | 16f877a_temperature_tc77.jal |
| 18f4525 | 18f4525_temperature_tc77.jal |
| 18f4550 | 18f4550_temperature_tc77.jal |
| 18f4620 | 18f4620_temperature_tc77.jal |
| 18f46k22 | 18f46k22_temperature_tc77.jal |


Battle of Britain Challenge
To date this year, I’ve not really signed up to do any bike challenges. About this time last year, I’d cycled from London to Loughborough, but I currently haven’t planned anything similar this year. I’d talked about doing the Devon Coast to Coast or the Way of the Roses but this has been hot air for the time being. I thought it was about time that I signed up and did something this year. My rides to date have mainly been commutes and transport, rather than recreational rides. I needed a challenge to get my teeth into.
Brompton Rides
I’d seen back in January that the Royal Air Force Benevolent fund were running a Paris to London bike ride in September. I liked the idea as it was to celebrate the 75th anniversary of the Battle of Britain and that it was all on Bromptons. However, the off putting fact was the £1000 sponsorship target, so I initially dismissed it.
However, it kept popping up in the London Brompton Club Facebook group and it also cropped up on my Twitter feed when retweeted by various companies I follow (namely Brompton themselves). And so, I looked at it in a bit more detail.
£350 entry fees that covers all my expenses for the ride. It’s sponsored, by some big names - Thales, Brompton and Strava which has kept costs down for the riders. However, there is a £1000 sponsorship requirement (riders have to raise £1000 to take part) which had initially put me off.
However, the idea of the ride refused to leave me alone - images of cycling along the French countryside in a “formation” of up to 150 other Bromptons with the RAF March Past playing in the background kept cropping up whilst I was trying to work…
The Gauntlet is laid down
So last week, I eventually looked at the challenge again. And looked at the other tours that Ride 25 offered. Looking at the prices of running my own Paris to London trip, staying at hotels and getting the Eurostar there and the ferry back, £350 suddenly looked very good value for money. And then the opportunity to take part in a memorial ride and raise money for a charity, I decided that it would be worth the cost and it would be a great opportunity.
So I signed up and now have to start training for the ride in September! Hope to get a lot of pictures along the route and aim to do some rides with the London Brompton Club to get some training in for it. The ride will be four days of riding and the longest ride I’ve done to date is a two day ride - it looks like I need to get in the habit of cycling distances day after day again. I used to do 40Km rides on both Saturday and Sunday when I was at university so I’ll be looking at doing similar in training. The distance from my house to work is about 40Km so it would be good training to cycle in once or twice a week. The benefit of having the Brompton is that I can cycle in for the morning (or home in the evening) and I only have to do a ride in a single direction as I can bike on the train without having to get an off peak train.
Sponsorship
So now comes the part where I ask if you’d care to sponsor me for this challenge and donate to a good cause.
There’s three ways you can help out:
-
Firstly, you can donate directly at Just Giving. My page can be found here. All money is sent directly to the charity.
-
Secondly, you can help raise money for me without any cost to yourself by using Easyfundraising. Basically, if you buy anything online, if you go to Easy Fundraising and click the shop link on their website, you get directed to the store website and can purchase your item as normal - however, the shop pays Easy Fundraising for each sale made through it’s store like this and this money is donated towards charity.
-
Spread the word! If you don’t want to or can’t donate, then please pass on the details of the ride and my sponsorship page to others!
I think I’ll be organising some RAF themed rides over the coming year to get the right mindset. I lost a family member who was in the RAF during the war so this can be my tribute to him.


Create custom landing pages with Omega that convert more
visitors than any website. With lots of unique blocks, you can
easily build a page without coding.
Multiple Layouts
With lots of unique blocks, you can
easily build a page without coding.
Fully Responsive
With lots of unique blocks, you can
easily build a page without coding.
Great Support
With lots of unique blocks, you can
easily build a page without coding.
Create custom landing pages with Omega that converts
more visitors than any website. With lots of unique blocks,
you can easily build a page without coding.
Create custom landing pages with Omega that converts
more visitors than any website. With lots of unique blocks,
you can easily build a page without coding.
50+ Unique Design Blocks
Multiple Layouts
Mobile First Design
Fully Responsive
Bootstrap 4 Framework
Humanly Support
Lifetime Updates
Rich Documentation
Create custom landing pages with Omega that converts
more visitors than any website. With lots of unique blocks,
you can easily build a page without coding.
Create custom landing pages with Omega that converts
more visitors than any website.
Jonathan Taylor
CEO at Creativex
Marie Stanley
Digital Marketer, Writer
Create custom landing pages with Omega that converts more visitors than any website. With lots of unique blocks, you can easily build a page without coding.


What it is:
Hierarchical database of critical system configurations
Registry is the configuration and control mechanism for the Windows Operating system
Contains system-wide and per-user settings
Useage:
During initial boot process (pre-kernel).
List of boot device drivers to load before kernel
During kernel boot process
Loads device drivers and system element configuration
During logon
Reads per-user preferences and settings
During application startup and execution
Purpose and Role of the Registry
13.1 Explain the purpose and role of Windows Registry and its major functions
HKCU - Current User
HKU - Users
HKCR - Classes Root
HKLM - Local Machine
HKCC -Current Config
Additional handles to predefined keys exist as per Predefined Keys (Windows) MSDN
The Registry has 5 Root Keys
13.2 Describe Registry hierarchy organization and primary components
HKCU – Current User, individual user settings
HKU – All accounts on machine, the root key containing the ntuser.dat hives for ALL users.
HKCR – Classes Root – file association and COM objects, backward compatibility, and file extension information
HKLM – System related information, SAM, Critical boot/kernel functions, 3rd party software, hardware, BCD.dat
HKCC – Current Config – Current hardware profile, informaiton that is gathered at runtime
Additional handles to predefined keys exist as per Predefined Keys (Windows) MSDN
The Hivelist
\REGISTRY\MACHINE\HARDWARE
Recreated every time the system starts
\REGISTRY\USER\
Specifies location of the files that store the current user profile
\REGISTRY\MACHINE\SECURITY
Specifies location of files that store the HKLM\Security key
\REGISTRY\USER\.DEFAULT
Specifies location of files that store the HKU\.DEFAULT key
\REGISTRY\MACHINE\SYSTEM
Specifies location of files that store the HKLM\SYSTEM key
\REGISTRY\MACHINE\SOFTWARE
Specifies location of files that store the HKLM\SOFTWARE key
\REGISTRY\MACHINE\SAM
Specifies location of files that store the HKLM\SAM key
13.2 Describe Registry hierarchy organization and primary components
A registry key that contains a list of mappings for the hive file mounting within the registry namespace.
When SMSS loads the Windows subsystem, it calls the configuration manager to load up the core registry hives.
After the registry is loaded via the configuration manager, SMSS records the location of the hives to CurrentControlSet. Table 1: From https://technet.microsoft.com/en-us/library/cc951686.aspx
A registry hive is a group of keys, subkeys, and values in the registry that has a set of supporting files that contain backups of its data.**Microsoft, "Windows registry information for advanced users," Microsoft, 11 Sep., 2011, Available: https://support.microsoft.com/en-us/help/256986/windows-registry-information-for-advanced-users
HIVE
13.2 Describe Registry hierarchy organization and primary components
Registry contains keys, and values.
Keys
Keys are a container object, much like a folder.
Keys contain other keys (AKA Sub-keys) and/or a collection of property/value pairs.
Values
Values store data.
Values are non-container objects, much like a file.
Data
12 data types available
Components of the Registry
13.2
GUI
Regedit.exe
Command Line:
REG.exe
WMIC CLASS StdRegProv CALL
https://goo.gl/fcmtgZ
Powershell
Get-item
Get-itemproperty
Get-childitem
Set-itemproperty
New-item
New-itemproperty
Registry Tools
14.1 Identify parts of the Registry using GUI-based tools
14.2 Use command line syntax to query, view, analyze, modify, and create Registry values
https://msdn.microsoft.com/en-us/library/aa393664(v=vs.85).aspx
Query
reg query [\\Machine\] HKLM\SOFTWARE\TEST
(PS) get-item -path "HKLM:\Software\Test"
wmic class StdRegProv call EnumValues sSubKeyName=”Software\Test”
Create
reg add HKLM\software\test /v data /d “This is the data”
(PS) new-itemproperty -path "HKLM:\Software\test" -name “data” -value “This is the data”
wmic class StdRegProv call SetStringValue sSubKeyName=”software\test” sValueName=”data” sValue=”This is the data”
Modify
reg add HKLM\SOFTWARE\TEST /v data /d “This is modified” /f
(PS) set-itemproperty -path "HKLM:\Software\test" -name “data” -value “This is modified”
wmic class StdRegProv call SetStringValue sSubKeyName=”software\test” sValueName=”data” sValue=”This is modified”
Delete
reg delete [\\Machine\]HKLM\SOFTWARE\TEST
(PS) remove-item -path "HKLM:\Software\Test"
wmic class StdRegProv call DeleteKey sSubKeyName=”software\test”
Query, Create, Modify, Delete
14.2 Use command line syntax to query, view, analyze, modify, and create Registry values
Changes to the registry often require a restart, as many programs read the registry values upon load.
Whether the entire system needs to be restarted, or just a program, depends on the program that is reading the changes.
As a general rule:
Changes to Windows System Settings require a reboot
Changes to Windows User Settings require a login
Changes to Windows Policy Settings usually don’t require a reboot
Changes to an Application require a restart
Milage may very
It is also important to note that some parts of the registry are always loaded into memory.
Registry Changes
14.3 – Explain when and how changes to the Registry are expected to take effect
HKLM\\Software\Microsoft\Windows\Current Version\Run
HKLM\\Software\Microsoft\Windows\Current Version\RunOnce
HKU\\Software\Microsoft\Windows\Current Version\Run
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tasks
HKLM\SYSTEM\CurrentControlSet\SERVICES\
HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR
HKU\\Software\Microsoft\Internet Explorer\TypedUrls
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\
Useful Registry Locations
15.1 – Identify Registry locations that contain forensically relevant information
15.2 – Identify Registry locations that can be utilized for persistence
HKLM\\Software\Microsoft\Windows\Current Version\Run
HKLM\\Software\Microsoft\Windows\Current Version\RunOnce
HKU\\Software\Microsoft\Windows\Current Version\Run
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tasks
HKLM\SYSTEM\CurrentControlSet\SERVICES\
HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR
HKU\\Software\Microsoft\Internet Explorer\TypedUrls
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\
Useful Registry Locations
15.1 – Identify Registry locations that contain forensically relevant information
15.2 – Identify Registry locations that can be utilized for persistence


The collapsible plugin has the following options:
collapsed
booleandefault: true
When false, the container is initially expanded with a minus icon in the header. To set the value for all instances of this widget, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.collapsed = false;
});
This option is also exposed as a data attribute: data-collapsed="false"
.
collapseCueText
stringdefault: " click to collapse contents"
This text is used to provide audible feedback for users with screen reader software. To set the value for all instances of this widget, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.collapseCueText = " collapse with a click";
});
contentTheme
stringdefault: null, inherited from parent
Sets the color scheme (swatch) for the collapsible content block. It accepts a single letter from a-z that maps to the swatches included in your theme. To set the value for all instances of this widget, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.contentTheme = "a";
});
This option is also exposed as a data attribute: data-content-theme="a"
.
expandCueText
stringdefault: " click to expand contents"
This text is used to provide audible feedback for users with screen reader software. To set the value for all instances of this widget, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.expandCueText = " expand with a click";
});
heading
stringdefault: "h1,h2,h3,h4,h5,h6,legend"
Within the collapsible container, the first immediate child element that matches this selector will be used as the header for the collapsible. To change the selector, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.heading = ".mycollapsibleheading";
});
iconpos
stringdefault: "left"
Positions the icon in the collapsible header. Possible values: left, right, top, bottom, none, notext.
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.iconpos = "right";
});
This option is also exposed as a data attribute: data-iconpos="right"
.
initSelector
CSS selector stringdefault: ":jqmData(role='collapsible')"
This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as collapsibles. To change which elements are initialized, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.initSelector = ".mycollapsible";
});
mini
booleandefault: false
Sets the size of the element to a more compact, mini version. If the value is false for an individual collapsible container, but that container is part of a collapsible set, then the value is inherited from the parent collapsible set. To set the value for all instances of this widget, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.mini = true;
});
This option is also exposed as a data attribute: data-mini="true"
.
theme
stringdefault: null, inherited from parent
Sets the color scheme (swatch) for the collapsible. It accepts a single letter from a-z that maps to the swatches included in your theme. To set the value for all instances of this widget, bind this option to the mobileinit event:
$( document ).bind( "mobileinit", function(){
$.mobile.collapsible.prototype.options.theme = "a";
});
This option is also exposed as a data attribute: data-theme="a"
.


Response.url
in DevTools
This tests that the DevTools utilize the Response.url
property
when using WebAssembly.instantiate
to properly show the
response-url.wasm
file in the Sources / Debugger panel. The
response-url.wasm
file should show up next to the
main.js
and response-url.html
files.
response-url.wasm
in the Sources / Debugger panel


Resize the page to see the ResponsivePanel in action. It collapses the demos' sidebar on device or browser of width less than 1200px.
Read more about ResponsivePanel in Kendo UI Docs:


Lending Club analysis
funded_amnt_inv(The total amount committed by investors for that loan)
int_rate(5.31 to 30.99)
emp_length(0-10 only)
annual_inc(annual income provided by the borrower during registration)
pymnt_plan(only 0,1)
dti( A ratio of borrower’s total monthly debt payments on the total debt obligations)
deling_2yrs
fico_range_low(660.0 to 845.0)
ing_last_6mths(The number of inquiries in past 6 months)
open_acc(The number of open credit lines in the borrower's credit file)
pub_rec(Number of derogatory public records)
revol_bal(Total credit revolving balance)
revol_util( the amount of credit the borrower is using relative to all available revolving credit.)
total_acc(total number of credit lines currently in the borrower's credit file)
initial_list_status(only 0 and 1)
total_rec_late_fee(Late fees received to date)
last_pymnt_amnt(Last total payment amount received)
last_fico_range_high(0.0 to 850.0)
last_fico_range_low(0.0 to 845.0)
collections_12_mths_ex_med(Number of collections in 12 months excluding medical collections)
policy_code(Only1)
application_type(only 0 and 1)
acc_now_dealing(The number of accounts on which the borrower is now delinquent.)
tot_coll_amt(Total collection amounts ever owed)
tot_cur_bal(Total current balance of all accounts)
total_bal_il(Total current balance of all installment accounts)
max_bal_bc( Maximum current balance owed on all revolving accounts)
TARGET(0,1)
issue_d_month(Jan=0,Feb=1,Mar=2,Apr=3,May=4,June=5,July=6,Aug=7,Sep=8,Oct=9,Nov=10,Dec=11)
earliest_cr_line_month(Jan=0,Feb=1,Mar=2,Apr=3,May=4,June=5,July=6,Aug=7,Sep=8,Oct=9,Nov=10,Dec=11)
earliest_cr_line_year(Enter last two digit of year)
last_pymnt_d_month(Jan=0,Feb=1,Mar=2,Apr=3,May=4,June=5,July=6,Aug=7,Sep=8,Oct=9,Nov=10,Dec=11)
last_credit_pull_d_month(Jan=0,Feb=1,Mar=2,Apr=3,May=4,June=5,July=6,Aug=7,Sep=8,Oct=9,Nov=10,Dec=11)
last_credit_pull_d_year(Enter last two digit of year only 2014-2018)
Calculate the loan prediction
{{ prediction_text }}


THE SOONG SISTERS (1997)
"Love is a kind of revolution, and revolution is a kind of love."
3.5 out of ****
Starring Maggie Cheung, Vivian Wu, Michelle Khan, Winston Chao, Kuo Chiu Wu Directed by Mabel Cheung Written by Alex Law Cinematography by Arthur Wong
Who were the Soong sisters? I can tell you quite a lot about them after watching Mabel Cheung's biopic. They were born around the turn of the century, in China, the daughters of Charlie Soong, a friend and ally of Dr. Sun Yat-Sen when he founded the Republic of China. Ai-Ling, the eldest, married the wealthiest man in China. Ching-Ling married Sun Yat-Sen and continued his legacy after his death. May-Ling, the youngest, married Kai-Shek Chiang, who became the leader of the Nationalist Party. They're all dead now.
Their fortunes were inextricably bound up in the colossal political and military struggles that have beset China throughout this century. I do not particularly believe in the idea of fate, but this film gave me pause, because it shows three women who seemed destined to "live in interesting times," as the proverb would have it, from the moment of their birth onward. Their story begged to be made into an epic, and an epic is what THE SOONG SISTERS is, in the best sense of the word. It's got it all: majestic cinematography, multiple stories played out against a vast backdrop, breathless narrative momentum, and great stars.
The stars include two of Hong Kong's leading women: Maggie Cheung (IRMA VEP, CHINESE BOX) plays Ching-Ling and Ai-Ling is played by Michelle Khan (aka Michelle Yeoh, of SUPERCOP and TOMORROW NEVER DIES). THE PILLOW BOOK's Vivian Wu is May-Ling. None of the performances are outstanding, but each actress brings the necessary charisma and presence to the part. They look the way famous women should look in a big-budget, glossy epic.
But who were these famous women, really? What were they like, in their everyday lives? That I can't tell you, because THE SOONG SISTERS isn't interested in that. It is interested in these women as vital figures in China's tempestuous 20th century upheavals, and as representatives of the extraordinary, frightening, operatic emotions that can occur in any country at war with itself. The film uses Ai-Ling, Ching-Ling, and May-Ling as focal points to show us over five decades of Chinese history, from the beginning of this century till after the "liberation" by the People's Army, and to give us some sense of what it might have been like to live through such times.
If any of this sounds like FAREWELL MY CONCUBINE to you, well, it does to me too. The structure and intentions of both films are remarkably similar; THE SOONG SISTERS plays, to some extent, like a Hong Kong remake of Chen Kaige's masterpiece. Both movies are visually superb, both are emotionally-charged melodramas, both use a triad of conflicting characters as the central focus of hugely ambitious narratives, and both films ran into trouble with the Chinese censors (18 minutes were cut from SISTERS for this reason).
But there are telling differences. In FAREWELL, history is the backdrop to a personal story: namely, the loyalties and conflicts that divide the two opera singers and the prostitute who marries one of them. In SISTERS, history is both the backdrop and the personal story, because the three sisters are all involved in the making of history. This difference, ultimately, is what makes SISTERS the lesser of the two movies. The personal, intimate details of their lives are sacrificed in favour of extravagant gestures; the sisters seem to interact only at moments of intense emotion: in love and in war, during death-bed scenes, angry confrontations, tearful farewells. This is immensely pleasing on the level of story and spectacle, but in the end I would have preferred less excess and more subtlety.
Ai-Ling is a pragmatist, Ching-Ling a pro-Communist idealist, and May-Ling an important player in the Nationalist Party, and these three traits essentially define each character: they become types, not individuals. I can't say I blame the filmmakers for treating the sisters in this light, because their story is so astounding, so larger-than-life, that these women, for all that they are modern, historical figures, take on the potency of myth. Besides, while each sister may be one-dimensional, when you put them together you have three dimensions--which is one more than you need to make a movie.
Some Chinese reviewers feel that the movie sacrifices the complexities of Chinese history in favour of reductive simplicities. I imagine they are right; I'm not really qualified to comment, since all I know of Chinese history is probably reductive simplicities. But to accuse THE SOONG SISTERS of trivializing Chinese history by giving it the Hollywood treatment ignores a significant distinction: in Hollywood movies, fate is usually an ally of the hero, while in most Chinese movies (certainly in this one) fate is the enemy, implacable and omnipotent. The sisters may be shown as one-dimensional romanticized types, but they're still ultimately treated no differently from many Chinese people, famous and obscure, in this century--victims of an unkind destiny they could neither choose nor avoid.
A Review by David Dalgleish (June 28/98<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


PLANET OF THE APES A film review by Steve Rhodes Copyright 2001 Steve Rhodes RATING (0 TO ****): **
There's a whole lotta gruntin' goin' on as actors in ape suits overact with a vengeance in Tim Burton's remake of PLANET OF THE APES, his BATTLEFIELD EARTH. Both films suffer from poor character development and dopey dialog. Although PLANET OF THE APES is much better made -- Burton is a great visual stylist -- if forced to sit through one of them again, I'd go for BATTLEFIELD EARTH, at least it was campy fun. PLANET OF THE APES is dreary and overwrought.
Delivering the film's only credible performance, Mark Wahlberg plays Capt. Leo Davidson, a human astronaut who accidentally lands on a planet where the apes are in command and are abusing the humans. Leo ends up teaming with a blonde bombshell named Daena (Estella Warren, DRIVEN), who dresses like Sheena, Queen of the Jungle, and acts like a zombie. Kris Kristofferson, as Daena's dad, plays one of the script's many clichéd characters. Although most of the apes look and act alike, it is Tim Roth, as General Thade, who is given the key role of the main villain. General Thade keeps scheming toward a Hitlerian final solution for eliminating the humans from the planet.
The apes run around saying things like, "How many times do I have to tell you to wear gloves when you handle humans?"
In the big battle scenes, Burton finally gets it right. These are great moments worthy of a master of the visual. But most of the movie is one silly scene after another. The original was fun, but the remake is dreary, violent and takes forever to get to the brief last act, the only successful part of the remake.
The movie does contain one comedic gem. "Be sure and get rid of them by puberty," a slave trader admonishes an ape who is in the process of purchasing a young human child.
PLANET OF THE APES runs 1:59. It is rated PG-13 for some sequences of action/violence and would be acceptable for kids around 10 or 11 and up, depending on how well they can handle violent, frightening images.
My son Jeffrey, age 12, gave it ***. He thought it was awesome, realistic and funny, but he was bothered by some of the story's logic.
The film opens nationwide in the United States today, Friday, July 27, 2001. In the Silicon Valley, it is showing at the AMC and the Century theaters.
Web: http://www.InternetReviews.com Email<EMAIL_ADDRESS>Want free reviews and weekly movie and video recommendations via Email? Just send me a letter with the word "subscribe" in the subject line.
========== X-RAMR-ID: 28998 X-Language: en X-RT-ReviewID: 240226 X-RT-TitleID: 1108704 X-RT-SourceID: 703 X-RT-AuthorID: 1271 X-RT-RatingText: 2/4
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


This is roughly the speech I gave as a keynote address at DjangoCon 2009 in Portland.
I’ve been programming Python web software for quite a while now. I considered coming here and talked about WSGI, standards, cross-framework integration, etc., but I decided I wanted to come up here and talk to you as compatriots, as fellow open source programmers.
Over the past year or so I have been thinking a lot about politics. Not electoral politics per se, or the geopolitical situation, but the question of the meaning of what we are doing. Maybe it is some sort of programmer midlife crisis: why am I doing what I’m doing, and why does it matter? And also I have been thinking a lot about open source — what this thing that we’re doing means in the larger context. Are we just engineers? Is there some sort of movement? If so, what is that movement? Especially as open source has become more popular, the sense of a movement seems to dwindle. It felt like a movement 10 years ago, but not as much today. Why should this happen? Why now, in the midst of success does open source seem less politically relevant than it did 10 years ago?
I’m also speaking somewhat to Django specifically, as I think it is one of the communities with a bit more resistance to the idea of the politics of code. The Django philosophy is more: the value of this code is the value of what you do with it. I’m not here to criticize this perspective, but to think about how we can find meaning without relying on the traditional free software ideas. To see if there’s something here that isn’t described yet.
I’d like to start with a quick history of free and open source software. My own start was in highschool where I was taking a class in which we all used Emacs. This was my first introduction to any real sort of programming environment, to Unix, to a text editor that was anything to talk about. At the time Emacs would say at startup "to learn more about the GNU project hit Control-H Control-P" — because of course you need a keyboard shortcut to get to a philosophy statement about an editor. So one day I hit Control-H Control-P. I was expecting to see some sort of About Message, or if you remember the software of the times maybe something about Shareware, or even "if you really like this software, consider giving to the Red Cross." But instead I came upon the GNU Manifesto.
GNU Manifesto
I’d like to read a couple quotes from the GNU Manifesto. There are more modern descriptions of GNU, but this is one of the first documents describing the project and its mission, written by Richard Stallman. Let me quote the section "Why I Must Write GNU":
"I consider that the golden rule requires that if I like a program I must share it with other people who like it. Software sellers want to divide the users and conquer them, making each user agree not to share with others. I refuse to break solidarity with other users in this way. [it continues...]
"So that I can continue to use computers without dishonor, I have decided to put together a sufficient body of free software so that I will be able to get along without any software that is not free."
[later it goes on...]
"The fundamental act of friendship among programmers is the sharing of programs; marketing arrangements now typically used essentially forbid programmers to treat others as friends. The purchaser of software must choose between friendship and obeying the law. Naturally, many decide that friendship is more important. But those who believe in law often do not feel at ease with either choice. They become cynical and think that programming is just a way of making money."
When I read this statement I was immediate head-over-heels in love with this concept. As a teenager, thinking about programming, thinking about the world, having a statement that was so intellectually aggressive was exciting. It didn’t ask: "how wrong is piracy really", or "why are our kids doing this", but it asked "is piracy a moral imperative" — that’s the kind of aggressive question that feels revolutionary and passionate.
Let me go over one of the lines that I think exemplifies this:
"I consider that the golden rule requires that if I like a program I must share it with other people who like it."
It wasn’t saying: what are we not allowed to do, nor did it talk about some kind of societal injustice. It didn’t talk about the meaning of actions or their long-term effects. Instead it asked: what must we do, not as a society, not in service of some end, but what are we called upon to do as an individual, right now, in service of the people we call friends. It didn’t allude to any sociological explanation, natural selection, economics; there is just the golden rule, the most basic tenant of moral thought.
Free Software vs. Open Source
When I first encountered free software, I suppose about 15 years ago, this was during one of the more difficult periods of its evolution. It was past the initial excitement, the initial optimism that the project would take only a couple years to reach parity with closed-source Unix, it was before it was clear how the project would move forward. Linux was young and seemed to be largely off the radar of Richard Stallman and other GNU advocates, and they were struggling to fill in final key pieces, things like a kernel, widgets, and they hadn’t even thought about entirely new things like browsers.
The message that came through from that period is not the message I wish came through. The message I wish came through was that message from the GNU Manifesto, that spirit of a new sense of duty and ability. When people talk about Richard Stallman and the Free Software Foundation and the GNU Project, they’ll often point to the GNU General Public License as the most important contribution — the GPL. I’m sure you all know something about it. Of course the core concept there is the idea of copyleft. Not only will the software be open, but it’s takes the implied perspective that the principles of freedom are rights — that unfortunately the world is not wise enough to see that use, distribution, and modification are rights; but the GPL still asserts that these are your rights. When you become one of us, when you participate in the freedoms this license grants you, when you use the GPL, there is encoded in the license a support for this sense of the natural right of free software. We, GNU, can’t encode that for the world, but for the software that we write these rights are inalienable.
But as I said those were difficult times. There was a great deal of pressure. People were trying to understand what open source meant. People still struggle with questions: how would an economy function, how would a programmer get a job, if this is as successful as people hoped will we all just be out of jobs? Other questions were: who will write the software that no one wants to write? How can I, embedded in a situation where I can’t actually use only free software — remember at this time there was no way to use completely free software — how can I assert a duty to do something that is not possible? How can I be useful unless I interface with all these proprietary things? If I deal with companies which aren’t comfortable with open source software, then what? After all, open source seemed only barely plausible at this time. It was not an easy argument to make.
And all this was before the term "open source" really took hold as a distinct idea. That itself is an interesting story. There was a time during this marketing period when there arose a kind of terminology divide — free software vs. open source software. The terminology divide was that the "free" in free software implied you couldn’t charge anything, that made people think about price, might even imply cheapness. Open source directly refers to programming, uses the feel-good term "open", and doesn’t sound too revolutionary. But besides that there was also a substantial philosophical difference about the value of the software itself.
So there was a difference in how things were going to be pitched, but also a difference in what people thought the general value of this project was. From GNU and Richard Stallman there was the notion that this was right because it was right; it was a moral imperative. The virtue of what we build is in its freedom; if it is also technically superior then that’s great, but it is not how we should judge our success. We were giving people self-determination: programmer self-determination, user self-determination… on the open source side the argument was that this is a good way to create software. Programmers working together can do better work. With many eyes all bugs are shallow. All working together, we’ll work faster, you get the benefit of free contributions from all sorts of people. People were clamouring to get all these proprietary companies with failing software products to open source their software; miracles will occur! What you thought was useless will regain value! You’ll reattain relevance!
The open source and free software philosophical divide: on one side practical concerns, on the other moral. And this is what I want to talk about later: can we find a moral argument for these practical concerns?
The basic free/open disagreement continues in debates over licenses: the GPL vs. the BSD and other permissive licenses. If you read the GPL it talks a great deal about philosophy; if you read the BSD license it’s really just some disclaimers and basic instructions, and the one line: "Redistribution and use in source and binary forms, with or without modification, are permitted." It doesn’t say why you’ve received this software, or any philosophy about rights and freedoms, or even encourage you to use the same license on your own software. An engineer’s license.
So these two licenses in many ways became a focus and definition of free and open source software. If you look at the Open Source Initiative, which has served to define what "open source" means, it is basically just a list of approved licenses. If you use one of those licenses, the software is open source, if not then it is closed.
I think this is disappointing, because licenses are just law, and law is not very interesting. A law tells you what you shouldn’t do, it doesn’t tell you what you should do. When both sides are talking about freedom, the licenses just define freedom as the lack of certain restrictions. Take away those restrictions and voila, you are free… as though we are all just bundles of freedom waiting to be released.
Self-Definitions
With licenses we have a negative definition of our community. Either license you choose, the license feels like a reaction against closed source software. If you can imagine a world in which there was no copyright, where our platforms were all setup to distribute source code in modifiable forms, where everything was open and everything was free, then none of these licenses would matter. No one would be compelled to create the GPL in such a world; we wouldn’t advocate for copyright just so we can secure people’s freedoms. In that kind of world all this licensing disappears. And this isn’t even so weird a world. You can pretend there’s no copyright now. Maybe you have to reverse-engineer some stuff. There’s lots of places in the world where no one really gives a damn about copyright. But those places don’t feel open source to me, they don’t feel that more free. We aren’t made unfree just by legal restrictions; freedom is something we have to actively grasp.
I don’t think what we do is predicated on copyright. Indeed, many projects are comfortable with an entirely confused copyright ownership. This causes very few problems. A focus on licensing makes us into a reaction against proprietary software, where we allow proprietary software and its makers to define what it means to be us.
This concerns me because it isn’t just about formal definitions and terminology. When I say what do I do, I say I am an open source programmer. That’s not just an attribute, like saying that my hair is brown. Open source is a way in which I see myself, a way I think about my craft, my profession, and a way I justify the work I put out to the world: that it aligns with these values. So it’s very important to me what these values are. And it’s frustrating to see open source defined in reaction to closed source software, because personally I don’t care about closed source software that much.
I never really cared much about fighting Microsoft, and I certainly don’t care now. I see myself as a builder; this is what always drew me towards programming. The desire to build new things. This is our privilege as programmers, that we always have the opportunity to build new things. If we’re asked to do something again and again and again, you always have the power to do it in a more abstract way, to generalize it away, until you can start to ignore the requests and move on to another problem. This is something unique thing to computer programming. These are the kind of unique attributes that make us different as a profession and as a craft than just about anything I can think of.
So I’m frustrated. Here we are stuck in this notion of a license as a self-definition. I want to find a new self-definition, a new idea of what makes us us.
What Makes Us Us
So… what makes us us?
I was saying about Django, the community is not particularly enthusiastic about philosophy. Or maybe I should say, Django’s philosophy is: the value of the code is the thing you do with it. These abstract discussions about architecture, reuse, big plans… instead, Django as a community encourages you to keep your head in the code, think about what you want to do, and then do it. Don’t shave yaks.
But I’m not here to tell you to get philosophical about freedom, or to berate you for a functional definition of value. I’d like to look at this community for what it is, and ask: what is the value system here? Maybe it isn’t described, but I also don’t think it is therefore absent.
So… when I say I identify as an open source programmer, what is it that I am identifying as?
I don’t believe licensing makes something truly open source. There was this clamour in the past to get companies to open source their products. This has stopped, because all the software that got open source sucked. It’s just not very interesting to have a closed source program get open sourced. It doesn’t help anyone, because the way closed source software is created in a very different way than open source software. The result is a software base that just does not engage people in a way to make it a valid piece of software for further development. At least not unless you have something peculiar going on… an economic force like you had behind Mozilla that could push things forward even in the midst of all the problems that project had. One might even ask, is Mozilla still suffering from that proprietary background, when something like KHTML or WebKit which came from a truly open source background, and has been a more successful basis for collaboration and new work.
So whatever it is that makes something open source, it’s not just licensing. Given a codebase, we can’t necessarily expect that someone going to care about it and love it and make it successful. A lot of people have described what makes a successful open source codebase; I’d like to talk some about what the communities look like.
Open source works as a fairly loose federation of people together. Everyone involved is involved as an individual. Companies seldom participate directly in open source. Companies might use open source, they might sponsor people to work on open source projects, they might ask an employee to act as a liason. But it’s not cool to submit a bug as a company. You submit it as yourself. If someone asks a question, you answer as yourself. You don’t join a mailing list under the company’s name. And even when you put a company name on a product, it’s hard to relate to the product as a project without some sense of authorship, of the underlying individual.
There’s also very little money being moved about. There’s not a lot of commercial contracts. You might get software, you might get bug fixes, you might get reputation, but there’s seldom any formal way setup to introduce commerce into the community. How many projects let you pay to escalate a bug? Even if everyone involved might like that, it’s just not there.
But I want to get back to individuals. How things are created is not that someone determines a set of priorities, lays them out, then people work on implementation based on those priorities. That of course is how things typically work at a company, as an employee. But open source software and open source projects are created because an individual looks at the world and sees an opportunity to create something they think should exist. Maybe it resolves a tension they’ve felt in their work, maybe it allows that person to respond to the priorities from above better, but the decision to implement lies primarily with the implementor. When someone makes a decision to move a product from simply private code — regardless of the license — to being a real open source project, that decision is almost always driven by the programmer.
Underneath most open source work there is a passion for the craft itself. This is what leads to a certain kind of quality that is not the norm in closed source software. It’s not necessarily less bugs or more features, but a pride in the expression itself. A sense of aesthetic that applies to even the individual lines of software, not just to the functionality produced. This kind of aesthetic defies scheduling and relies on personal motivation.
As open source programmers we are not first concerned with how a task fits into institutions, how a task can be directed by a hierarchy or an authority, or even how the task can be directed by economics. The tasks that we take on are motivated by aesthetic, by personal excitement and drive.
We are also in a profession where there is little stasis. If you can create something once, you can create it a thousand times, through iteration or abstraction. You can constantly make your own effort obsolete. A good programmer is always trying to work themselves out of a job.
Djangocon didn’t exist a couple years ago. Django didn’t exist only a few years ago. And I don’t think there’s anyone here who thinks that, having found Django, they’ve reached some terminal point. It’s hardly even a point to pause. There’s a constant churn, a constant push forward that we’re all participating in.
As a result it’s demanded of us that we have a tight feedback cycle, that education is not a formal affair but a constant process in our own work. There’s a constant churn, and a professional sense we’re kind of like fruit flies. A generation of knowledge and practice is short enough that the evolution is rapid and visible. You don’t have to be particularly old or even thoughtful to see the changes. You can look back even on your own work and on communities to see changes over the course of a couple years, to see changes and shifts and a maturing of the work and the community.
Another attribute of open source: our communities are ad hoc and temporary. We do not overvalue these communities and institutions; we regularly migrate, split, recombine, and we constantly rewrite. There is both an arrogance and a humility to this. We are arrogant to think This Time Will Be Different. But we are humble enough to know that last time wasn’t different either. There will always be a next thing, another technique, another vision.
Because of the ad hoc nature of the communities, we don’t have long collective plans. The ad hoc community may be the intersection of different personal long range plans, a time when different visions somehow coincide in a similar implementation. Or perhaps it’s just serendipity, or leadership. But we make each decision anew. I believe this protects us from being misled by sunk costs. The idea of a sunk cost is that when you make an investment, you’ve put in effort, that effort is gone. Just because you’ve put in effort doesn’t mean you’ve received value, or that the path of investment remains valid. But as humans we are highly reluctant to let go of a plan that we’ve invested in. We have a hard time recognizing sunk costs.
I believe in our developer community we approach our work with sufficient humility that we can see our work as simply a sunk cost. Our effort does not entitle us to any particular success, so we can choose new directions with more rationality than an institution. Though it can also be argued that we are too quick to dismiss past investments; there is a youthfulness even to our oldest members.
We do not have hierachies with decision makers above implementors. Some people have veto power (a BDFL), but no one has executive power. A decision only is valid paired with an implementation. You cannot decide something based on information you wish was true; you cannot decide on something then blame the implementors for getting it wrong. We are in this sense vertically integrated, decision and implementation are combined. The result may be success or failure, commitment or abandonment, but the hierarchy is flat and the feedback loop is very tight. And if an individual feels stymied, there is always another community to join or create.
Though this is only a start, it’s these attributes that I would prefer define us, not licenses.
I also would like that this could be a model for how other work should be done.
Why Us?
Why would we, as programmers, be unique or worthy of emulation? I mentioned before that we constantly work ourselves out of our job. We also create the tools we use to do the work. We define the structure of our communities. We’re consistently finding novel ways to use the internet build those communities. It’s not that we as a group are somehow uniquely wise, or some Greatest Generation, but we have become distinctly self-empowered. There is a uniqueness to us. It might be a coincidence of history, but it is there.
A question I might then ask: is there a political meaning to this? This is the form our craft takes, but does that mean anything? We work with computers, someone else might work with their hands, an artist considers color, a salesperson learns how to put on a good smile.
I haven’t quite figured this out yet, but I think there’s something in this. Over the years I’ve found myself looking at politics in a increasingly technocratic lens; more so than as a liberal, conservative, or radical. That is, instead of looking at the world and seeing what’s wrong about it, and explaining it in terms of a class struggle, a cultural conflict, in terms of advocacy or invented enemies or allies, I see a system that just works how it works. It’s more like gears than like a war. The gears turn and sometimes we don’t like what results, but it’s not malice.
But I also don’t think we are slaves to the technical functioning of the system. None of us are inevitably caught up in some statistical outcome of markets, or condemned by money in politics or advertising. At any time we can say Here Is What I Believe, and it is as powerful as any of those other things; we’re too quick to look at the people who aren’t asserting a belief, who aren’t asserting their own potential for self-empowerment and direction, and we ignore everyone who is aware and concerned and attempting self-determination. We are at danger of ignoring the great potential around us.
It is in this sense that I wonder not just how we can spread the idea of freedom through licensing, which has inspired the free culture movement, but also how we can spread this idea and practice of individual action, of combining decision and implementation, and of constant ad hoc collaboration.
I’m not just thinking of politics directly, but of professional lives as well. Right now we’re talking about healthcare. It’s a very political issue, and yet healthcare is ultimately a profession, a job, an action. How we work on that, collaboratively or not, is as political as any aspect of the system.
One anecdote that made me think about this, is a task I had that involved putting authentication in front of a mailing list. The mailing list happened to be for wound, ostomy, and continence nurses, and in the process of the job I read a bunch of their emails from the archives. As wound nurses they spent a lot of time asking about specific questions — maybe a wound that wouldn’t heal, they kept draining the puss and it discharge kept reappearing, and did anyone have ideas of the next technique to try?
Reading a few of these I could tell this was a profession where you needed a strong stomach. But the whole interaction, the way they described problems, the way people came back with answers, it felt very familiar to me. It was the same kind of discussions I could imagine having about Linux administration or debugging. And the goals were similar. No one was making money, there wasn’t really reputation on the line, it was just people who wanted to help their patients and who wanted to help each other.
So that mailing list was great, but it’s unfortunately not that common. And if nurses were open to that kind of collaboration, doctors don’t seem nearly as ready. And there’s a lot of professions where there’s not even that thoughtfulness. I believe in any profession there’s the ability to do it well or not; there’s nothing so rote or well understood that there’s no room for improvement. It doesn’t have to be fancy technology, it can just be a technique, a way of managing work; all things worth doing have some way of improving, by bringing in this same sense of collaboration and individual action and thoughtfulness, all things can be implemented better than they are now. What I’m describing isn’t a fancy new website for professionals, but about people look at their own work differently; the technology is not the hard part.
The Political
Changing how people look at their work I think is political. It involves individual empowerment. It can mean economic change. I also think it deemphasizes competition. When I think about Pylons, or Django, or TurboGears, or WSGI, there’s competition, but it’s also collegial. There’s not really that much of a sense of survival. We aren’t carving out territories, we’re just finding paths to some unknown end. If something else wins out, well, we’re all just along for the ride. In the end it is inevitable that something else other than what any of us are working on will win out over what any of us are doing. Just like everyone eventually loses their job at least to death or retirement. There’s no permanency. But if we can be individually more productive, it doesn’t have to mean we’ve put someone else out. It could mean we all, all of society, all of humanity, just do more. Why do we have to set ourselves against the Chinese, or Europe against the U.S.? Why do we have to set ourselves one economy against another?
Or consider government itself: we’re obsessed with our elected officials, but of course government is far larger than just the elected officials. The U.S. Federal Government alone has 1.8 million employees. We constantly threaten to institute accountability, meaning that we’ll poke and prod government workers from the outside and expect better outcomes. That we expect anything to come of this is absurd, but somehow accountability has become an easy alternative to constructive suggestions for improvement.
But why shouldn’t we expect that government workers want to do better? I believe in fact those people doing the work are especially well equiped to figure out how to do better. But it’s not automatic. They aren’t empowered in a system that is so exceptionally hierarchical. Lately we’ve seen lots of efforts to ask the public how to do government work better, but we’ve seen nothing asking government how to do government work better.
These are the kinds of things I’d like to see us all think about more: open source has done incredible things, has inspired new ideas, about more than just software and engineering, but I think we have yet more things to give.
Thank you for your time.
Automatically generated list of related posts:
- App Engine and Open Source This is about Google App Engine which probably everyone has...
- Git-as-sync, not source-control-as-deployment I don’t like systems that use git push for deployment...
Good stuff in there Ian, thought provoking. Thanks for sharing for future reference and forwarding it to others.
Ian have you read Clay Shirky’s essay “Institutions versus Collaboration”? Do a google search, there is a video at TED where he lays out the thesis that we’re in the early stages of a universal cultural shift regarding how we work together nearly exactly like what you describe. He compares it to the shift in Europe from 1200 AD, where political authority was based on divine right to the treaty of Aachen when the notion of secular rule was firmly established. It took 400 years for that shift to happen. He believes our current shift will take about 50-100 years.
You should check it out, it kinda flipped my lid.
Thanks, keep writing.
I think I’ve read that (the TED talk is very familiar to me, at least), though not while I was writing this. I did also think about his book Here Comes Everybody, where he talked about some of these things. For some reason Clay Shirky doesn’t talk much about open source software production. There’s perhaps something less exciting about software production than politics or art… but we’re also years and years ahead of those areas, and our output is concretely and measurably useful, whereas politics and art are hard to judge. For instance, people were excited about what happened with the Iranian election and Twitter, but it’s unclear that the internet served any constructive purpose at all (it’s possible that it helped start a nascent movement that will rise up again in Iran, or that it made Iran seem more empathetic to Americans, but the jury is still out on that stuff — there was nothing immediately positive about the outcome of that event).
True, Shirky doesn’t put an overly-fine point on it. But he does mention Linux in the talk as a “phenomenon” in the context of how Ballmer poo-poos it (as in “he obviously doesn’t get it”).
Still, there is much in the implications of what you describe in the keynote in the politics of Anarcho-Communism or even Anarcho-Syndicalism. I kind of hate using those terms because nobody seems able to use them without totally misunderstanding them; allowing their over-hyped exponential examples to define them. Emma Goldman was not very radical by today’s standards.
In an earlier conception of the talk libertarian vs. anarchism was going to be a substantial part — though it requires an introduction to anarchism; while I expect a programmer audience to understand libertarianism well, I’m afraid I can’t expect the same of anarchism. The libertarian conception of freedom (the removal of state coercion) is somewhat akin to the licensing conception of freedom. Though frankly I think traditionally both libertarian and anarchist thought are overly obsessed with the negative (i.e., coercion and oppression). Still, anarchists in practice actually pay attention to the positive pursuit of freedom; I haven’t seen a libertarian equivalent.
On the subject of anarchism, capitalism, and geek culture, I always recommend Ursila K LeGuin’s fantastic sci-fi novel “The Dispossessed.” It presents a picture of one possible anarchist society, and contrasts it with something much more like american capitalism. The subtitle is “an ambiguous dystopia” and it’s not clear which culture is supposed to be the dystopia from the title. But what’s appropriate to this discussion is that the anarchy in the book is pretty much presented as a stand-alone society, which is defined positively, not by what it stands against.
I think the experience of open source developers shows that some of the premises of LeGuin’s book aren’t totally valid, but it’s interesting how much of the contrast between the two worlds in the book is reflected in the contrast between the open source and commercial software communities.
Very nice read, thanks
Great read – thanks for posting the text.
I’m sorry I missed the presentation live, but thanks for posting it here. I found it very interesting.
“..as though we are all just bundles of freedom waiting to be released.” When did you become a poet?
You wrote, “But open source software and open source projects are created because an individual looks at the world and sees an opportunity to create something they think should exist.”
This reminded me of the mantra of Andrew Cowie, on why are we doing it: “Because it needs doing”. His post is [here](http://blogs.operationaldynamics.com/andrew/software/freedom/one-year-and-more.html).
Great post, thanks. I’ve been thinking a lot about why we are worthy of emulation and I found two more reasons:
Code is the best way to control a complex system. For an x86 server we use software code, for our government and judiciary system we use legal code, but they are really quite alike. Generalizing a bit, we are good at writing code to control complex systems. Right now, we’re all focused on complex Turing machines, but that could change, especially as those non-Turing systems will have all their data accessible by Turing machines.
Our craft is unique in that the cost of destruction is nil, so coding evolved to include refactoring as part of the development process. I don’t think there’s any other craft or profession out there where you are not ashamed of throwing away your old work, but it’s really all right if your professions is focused on knowledge.
Fantastic essay, thank you for posting!
I share your technocratic view of government, or any significantly large organization. People always overestimate how much control and power the leader(s) have, but if the leaders do a good job then they have very little (personal) power at all. All decisions are be reasoned, agreed upon, and executed, as if obeying the laws of physics. Like gears in a machine.
I view myself as an Open Source developer, a builder (or creator). I can’t remember a time when I hesitated posting the source code to my creations, mostly because I didn’t see the source code as the part that contains its value, but rather the idea it represents. I want the idea to flourish, even if someone else becomes responsible for it.
Finally, I very much enjoyed the anecdote about the nursing mailing list. I’ve heard similar impressions from nurses and their perspective on the battle between their opinion and that of the doctors. My impression is that the nursing movement is much more agile and progressive (very similar to the open source community), whereas MD’s are a proprietary corpus of R&D and reputation.
Thank you for sharing your thoughts and your code.
@shazow (a user of much of your code)
“What I’m describing isn’t a fancy new website for professionals, but about people looking at their own work differently; the technology is not the hard part.”
Yes. The open source style of organizing work, and of narrating work in a transparent way, is a key innovation that can and should spread to every profession.
I’ve been trying for a long time to use the open source model to illustrate this point — because it’s the best real-world example of it. But it’s hard because people both inside and outside the software world keep wanting to view the model through the lens of tribal warfare.
Thank you for his refreshing read! This is a jewel I will definately share with my fellow developers in Academia — who sometimes forget that sharing of knowledge is a good thing!
A relate post is “We No Longer Need Power” from Bruce Eckel and the comments there. I must say I read you post yesterday but I was not able to get the deep meaning of it. Only skimming throw the text I got the impression that you feel that a change is going to occur but don’t see the direction or how to focus people to go in some direction.
I think we should learn the value of symbols, for example what is the meaning of a coin for society. We depend very much of such concepts, imagine there were not possible way to guarantee secure economic transactions, or that legal status are not respected by people any more …
In order to change we should be able to appreciate the kernel features that are at the core of our society. Such change require a deep knowledge of the human nature, an appreciation that I think we will never get when a person is only a mascaraed to live in a tribe.
Thanks, Ian. It’s nice to hear introspectives on FOSS again. I miss those. Last year, I posted http://jjinux.blogspot.com/2008/02/hybrid-world-of-open-and-closed-source.html which is similar in nature to your post, and there wasn’t as much of a response as I expected.
I’m glad to see other people thinking deeply about these things. Recently, I posted http://jjinux.blogspot.com/2009/08/open-source-closed-source-video-games.html in which I admitted that I’m thankful for both open and closed source video games.  Part of me thinks it does, but the little Stallman who sits on my shoulder keeps calling me a sellout ;)
Nicely said. You might find “The Success of Open Source” by Steven Weber an interesting read. It’s a few years old, but touches on quite a bit of history and some of the motivations for participants in a few of the larger OSS projects. He also does some analysis of the difference in culture between BSD and GPL licensed projects.
Love the crossover between political thought and how it applies to the new evolution of open-source technology. Tremendously insightful!
I found this post just checking out what folks are saying about “yaks”. At first I thought it was just another “yak shaving” post. Somehow reading the first few paragraphs hooked me. I am not a programmer, just a simple yak rancher. Still I was fascinated by the political point of view. I ended up following most of the comments. Thanks for a great post and somehow broadening my thoughts on software and politics!
Very interesting post, which lets me focus on a difference I didn’t recognize that well between Open Source and Free Software. I liked the political aspects you mentioned, too. On my point of view, if a kind of revolution is still possible in our (over-)developed world, it will be a digital one!
Very well said, this is why I’m interested in free and open source, thanks
Things change. For exp. I live in country (Lithuania) where in XIX century we had book smugglers – That’s right, books were illegal an they were brought from abroad by smugglers. Of course they were criminals or pirates by messurements of those times. But now they are heroes and we pay tribute for them – for bringing culture to our people during those dark times. So – think the same with piracy now. people like billy gatesy call these people pirates, they are steeling their money. But from other side – people from third world, they will never get chance to same technology, same knowledge and culture as rich nations do. What if piracy can change this – lead us to better world, where every man has a right to read, use, or entertain with content that was created by mankind.


---
layout: post
title: Visual development
date: '2018-01-06T11:30:29+01:00'
categories:
- Concept Art
picture_url: https://film-Storyboards.tumblr.com/post/169389399239/visual-development
---
Concept art for a Franco Dragone aquatic show, for Da Nang Naman Resort.