Why Smalltalk is NOT Object-Oriented, Part One: How is Smalltalk Different?


The title may seem like blasphemy to purist object-oriented developers, particularly those who work in Smalltalk, especially since the person who coined the term “object-oriented” did so specifically to describe his other major contribution to software development – the Smalltalk language. Nevertheless, brilliant as he is as a developer and conceptualist, he is a technologist with a scientific bent and not an ontologist, and object-oriented is misleading in that “object” is not a neutral term, and its use both allows languages that are not at all Smalltalk-like, to claim the description, as well as not getting at the heart of what makes Smalltalk programming a different and in many ways superior experience to other languages that are described as “object-oriented”.

My main reason for writing this is in defense of Smalltalk itself. As most who have heard of the language know, it is not a new language. It’s been around since the 1970s and was formalized, after extensive testing well beyond what most development languages undergo, in 1980. Nevertheless it remains a niche language, loved by those who use it and generally ignored by everyone else. This is unfortunate because not only is Smalltalk more enjoyable to develop software in, it is vastly more productive than more commonly used languages such as C, C++, Java, JavaScript, Ruby or Perl, for example. The other reason is that as a term that has escaped its original usage even beyond programming, its lack of precision makes, for instance, it difficult to discern what “object-oriented philosophy” might be on about. There may well be ontological and philosophical insights to be gained by understanding what makes Smalltalk different, but that has to include what makes it just as different from other “object-oriented” languages such as C++ and Java as it is from procedural languages such as C or COBOL.

Smalltalk was late to the open source game, in that although GNU Smalltalk has been around for a while, GNU’s dependency on the entire GNU system takes away a significant aspect of what makes a true Smalltalk variant “true”. GNU Smalltalk is not truly a “live” development environment, a development “world”, and as a result has a similar compile-build-test cycle to more traditional languages. Pharo on the other hand, or Amber (www.pharo.org and http://amber-lang.net respectively) are true Smalltalk variants that are open source. The existence of these variants, as well as the newer licensing model on variants such as VisualWorks (www.cincom.com) that only charge the user of applications written in it a nominal fee and do not charge the developer for the environment, makes Smalltalk more attractive economically for developers than it has been for most of its lifetime, where development environments had a very high initial cost, putting off developers who were unsure of the potential of Smalltalk from trying it out. A number of the quotes and examples in this article are from the free PDF book accompanying Pharo, Pharo by Example (www.pharobyexample.org), which is a fantastic introduction to programming not just for experienced developers that want to try something different, but for novices who have never written code, since it makes very few assumptions about what the reader “ought” to know prior to beginning.

To begin, I’m going to take an example of “object” use in Java. I’m using Java as a comparison language not to bash Java (I do plenty of work in Java myself) but because it is the most used language in the world (more code has been written in it than all other programming languages put together), it is generally accepted as being an object-oriented language although the syntax and semantics are not radically different from C, and it is a relatively productive language (using basic assembler as a base for comparison, function point analysis shows Java to be approximately 12x more productive. That sounds great doesn’t it, after all C, the most common language for years prior to Java, only works out to be 5x as productive as assembler.)

The example I’m going to use is a relatively common library call that a developer would make in order to output a PDF of some data of whatever kind the application is involved with. Many web applications, such as banking applications, do this kind of thing to provide the customer with a statement that is better rendered and more easily printable than the web page itself, for instance. A library is a collection of prebuilt functions or objects, depending on the language type, that allow a developer to do common tasks without reinventing the wheel. One of the more common libraries for creating PDFs from data in the Java world is known as Apache FOP.

The following code is from a Java class (a class can be thought of as a template for creating objects, which are also known as instances of that class) which takes an arbitrary Java object and renders it to PDF. The beginning of the file has a block of comments beginning with /* and ending with */, single line comments begin with //. Comments are ignored by the Java interpreter, they are only for the use of other developers. As a result the code proper begins with the keyword package followed by a name. A package in Java corresponds to a package in Smalltalk, but is often referred to in other languages as a namespace. By convention (not followed in this example) packages in Java begin with the domain of the author backwards followed by a hierarchy that specifies a more or less sensible location for the class. For instance org.apache.fop.examples.

/*

* Licensed to the Apache Software Foundation (ASF) under one or more

* contributor license agreements. See the NOTICE file distributed with

* this work for additional information regarding copyright ownership.

* The ASF licenses this file to You under the Apache License, Version 2.0

* (the “License”); you may not use this file except in compliance with

* the License. You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an “AS IS” BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/
/* $Id$ */
package embedding;
// Java

import java.io.File;

import java.io.OutputStream;

import java.io.IOException;
// JAXP

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.TransformerException;

import javax.xml.transform.Source;

import javax.xml.transform.Result;

import javax.xml.transform.stream.StreamSource;

import javax.xml.transform.sax.SAXResult;
// FOP

import org.apache.fop.apps.FOUserAgent;

import org.apache.fop.apps.Fop;

import org.apache.fop.apps.FOPException;

import org.apache.fop.apps.FopFactory;

import org.apache.fop.apps.MimeConstants;
import embedding.model.ProjectTeam;
/**

* This class demonstrates the conversion of an arbitrary object file to a

* PDF using JAXP (XSLT) and FOP (XSL:FO).

*/

public class ExampleObj2PDF {
// configure fopFactory as desired

private FopFactory fopFactory = FopFactory.newInstance();
/**

* Converts a ProjectTeam object to a PDF file.

* @param team the ProjectTeam object

* @param xslt the stylesheet file

* @param pdf the target PDF file

* @throws IOException In case of an I/O problem

* @throws FOPException In case of a FOP problem

* @throws TransformerException In case of a XSL transformation problem

*/

public void convertProjectTeam2PDF(ProjectTeam team, File xslt, File pdf)

throws IOException, FOPException, TransformerException {
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

// configure foUserAgent as desired
// Setup output

OutputStream out = new java.io.FileOutputStream(pdf);

out = new java.io.BufferedOutputStream(out);

try {

// Construct fop with desired output format

Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
// Setup XSLT

TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = factory.newTransformer(new StreamSource(xslt));
// Setup input for XSLT transformation

Source src = team.getSourceForProjectTeam();
// Resulting SAX events (the generated FO) must be piped through to FOP

Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing

transformer.transform(src, res);

} finally {

out.close();

}

}

/**

* Main method.

* @param args command-line arguments

*/

public static void main(String[] args) {

try {

System.out.println(“FOP ExampleObj2PDF\n”);

System.out.println(“Preparing…”);
// Setup directories

File baseDir = new File(“.”);

File outDir = new File(baseDir, “out”);

outDir.mkdirs();
// Setup input and output

File xsltfile = new File(baseDir, “xml/xslt/projectteam2fo.xsl”);

File pdffile = new File(outDir, “ResultObj2PDF.pdf”);
System.out.println(“Input: a ProjectTeam object”);

System.out.println(“Stylesheet: ” + xsltfile);

System.out.println(“Output: PDF (” + pdffile + “)”);

System.out.println();

System.out.println(“Transforming…”);
ExampleObj2PDF app = new ExampleObj2PDF();

app.convertProjectTeam2PDF(ExampleObj2XML.createSampleProjectTeam(), xsltfile, pdffile);
System.out.println(“Success!”);

} catch (Exception e) {

e.printStackTrace(System.err);

System.exit(-1);

}

}

}

This example usually brings up a long sigh from Smalltalk developers at the amount of code required to do what is, after all, a fairly straightforward task, particularly since the imported classes in the org.apache.fop package do most of the actual work. Non programmers, interestingly, have a similar response, although it’s more quizzical, since they don’t have the experience to understand what the code is actually accomplishing or why there needs to be so much of it. What I’d like to do is to look just at the lines that actually utilize other Java objects and how they do so. The first pair of such lines are the following:

private FopFactory fopFactory = FopFactory.newInstance();

FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

To a non-programmer, obviously, this is largely meaningless, although they might get a basic notion of what it does by the names of variables and methods. An FOPFactory class, in this case instantiated as fopFactory, is the means by which we obtain an instance of FOUserAgent. Rather than the simple means of creating an instance, or object, from a class using the new keyword, the library designers have used a specific programming pattern known as the Factory Pattern, which provides a factory class in order to instantiate objects for the library user. The usual reason for this is that to instantiate an FOUserAgent directly the library user would have to know a significant amount more than they do here about the FOUserAgent class itself and how it works. Although it seems more complex than simply typing FOUserAgent myAgent = new FOUserAgent(); in fact that likely wouldn’t work because FOUserAgent requires specific creation parameters of various types – trying to create one without giving it any information doesn’t work.

Since the library is open source, we can in fact check that assumption by looking at the source code to FOUserAgent. I’m not going to force the reader to look through all the source code to that class (although, for a Java class, it’s not actually all that long) but instead just to look at the constructor signature. The constructor is a special method called on a class to create a new instance of that class, a new object (in object languages blocks of code that do a specific task are usually organized into methods, which are similar to functions in procedural code – the function point analysis I referred to earlier doesn’t simply count methods or functions, however, since they may be merely housekeeping code, it only counts feature functions, whether those are end user features or technical features (such as an autosave function, for instance, which is very useful to the user although they don’t do anything inorder to use it). Here is the constructor signature for FOUserAgent:

FOUserAgent(final FopFactory factory, InternalResourceResolver resourceResolver)

A signature in a method tells you what the method requires (in Java these requirements are passed as parameters within the parentheses) as well as any returned object. Since this is a constructor the return value is not need as it by definition is an instance of FOUserAgent, otherwise it wouldn’t be much use as a constructor. On a regular method the return type would be stated before the method name, or the keyword void put before the method name to indicate that nothing is returned. This doesn’t indicate that void methods do nothing that the caller can know about, since object parameters are passed in as a reference to the identical object that the caller knows about, and any changes to that object by the method are therefore already changed in the caller’s reference to it, and there’s no need to pass the reference back.

The key aspect of the constructor signature in this case is that firstly, although the FOUserAgent is intended to be created by the FOFactory, it needs a reference to that factory in order to configure itself and accomplish any methods that are called on it. It also requires a third object, an instance of InternalResourceResolver. Without the factory pattern, the original call in the example would have to create an instance of an InternalResourceResolver as well as an FOFactory in order to create an FOUserAgent, so it makes more sense to have the FOFactory create both the InternalResourceResolver and the FOUserAgent in one call. Since the InternalResourceResolver itself may need other objects in its constructor, and those objects may need further objects, the comparative simplicity of the Factory Pattern becomes apparent.

Now, after getting an instance of FOUserAgent, we don’t appear to be any nearer to rendering our object as a PDF. Let’s take a look at how the FOUserAgent is used in combination with other FO objects and the object we want to render to accomplish this.

File xsltfile = new File(baseDir, “xml/xslt/projectteam2fo.xsl”);

File pdffile = new File(outDir, “ResultObj2PDF.pdf”);

ExampleObj2PDF app = new ExampleObj2PDF();

app.convertProjectTeam2PDF(ExampleObj2XML.createSampleProjectTeam(), xsltfile, pdffile);

After removing all the debugging print statements it actually looks pretty simple. Those of you who are actually paying attention, though, might have noticed an oddity here – app is an instance of the ExampleObj2PDF class, but that’s the class we are. And I haven’t included whatever convertProjectTeam2PDF() does. This sort of reflexivity, having a class create instances of itself outside a constructor is common in Java in patterns like the Singleton (where at most one instance is ever wanted but you don’t want the caller to have to know if that instance exists yet or not) and in example code such as this that contains a main() method. Usually a program only has one main method even though it may have thousands of classes, the point of a main() method is simply to be a starting point for the program. Putting such a method in the example allows it to be run from the command line wiithout configuring an entire application around it first.

But what does that method we noted do? For that we have to go back to the source code and have a look:

public void convertProjectTeam2PDF(ProjectTeam team, File xslt, File pdf)

throws IOException, FOPException, TransformerException {

OutputStream out = new java.io.FileOutputStream(pdf);

out = new java.io.BufferedOutputStream(out);

try {

// Construct fop with desired output format

Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
// Setup XSLT

TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = factory.newTransformer(new StreamSource(xslt));
// Setup input for XSLT transformation

Source src = team.getSourceForProjectTeam();
// Resulting SAX events (the generated FO) must be piped through to FOP

Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing

transformer.transform(src, res);

} finally {

out.close();

}

}

Now you’re probably thinking ‘hey, he just pasted half of the file again’, and you’re right. The method converProjectTeam2PDF() does nearly all the work that isn’t handled by the FO library itself. For those with little programming background, I’ll break down what it’s doing a little better:

OutputStream out = new java.io.FileOutputStream(pdf);

out = new java.io.BufferedOutputStream(out);

An OutputStream is an abstract class that various types of concrete output classes implement, thus in Java we can refer to out as either a BufferedOutputStream, a FileOutputStream or simply an OutputStream. In point of fact, to create a FileOutputStream all we need is string that tells Java the file name and path, which is in the pdf String object. To create a BufferedOutputStream, one of the types of object we can use is a FileOutputStream. Since both FileOutputStream and BufferedOutputStream inherit from OutputStream the programmers have saved a few characters of typing by reusing the same variable, out, first to hold the FileOutputStream and then the BufferedOutputStream. I personally find this confusing to new developers, since it appears that we no longer have the FileOutputStream (we’ve overwritten the reference) but in fact we can get that back from the BufferedOutputStream object itself, so we’ve no need of a copy of the reference to what is, after all, only one object. (Object languages run on the Leibnizian premise that any two identical objects are in fact one object, which has implications for object comparison, but that’s another topic).

That was a long description of a fairly simple operation that doesn’t actually accomplish much, perhaps the reader is getting impatient to see something actually rendered, but at least we now have a place to render it to.

Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
// Setup XSLT

TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = factory.newTransformer(new StreamSource(xslt));
// Setup input for XSLT transformation

Source src = team.getSourceForProjectTeam();
// Resulting SAX events (the generated FO) must be piped through to FOP

Result res = new SAXResult(fop.getDefaultHandler());

Alright, then, we’re nearly there. We’ve gone back to the FOPFactory again, this time asking it for a FOP. Since it’s the Apache FOP library, we can assume that a FOP is the key class that actually accomplishes what the library is supposed to do. However, prior to seeing that wonderful accomplishment, we have to mess around with something called XSLT transforms in order to get our object into a format that FOP understands. XSLT transforms essentially take information in one XML schema format and convert it to another. There are numerous ways to do that, but XSLT is relatively fast and efficient, so it’s utilized here. We also have to get the actual source XML in order to transform it for FOP. At that point we use the XML reader (SAX) to get a result, passing in the default method from FOP to handle the events that a SAX reader generates (SAX reads a line at a time and creates an event that has the information relevant to that line, rather than reading in and converting an entire document the way other XML reader classes might).

So, what do we have in the Result object res? Not a PDF, unfortunately. We have an XML file that has been prepared by FOP for transformation into a format FOP itself can deal with, once it is in fact transformed. Here is the code that does that:

transformer.transform(src, res);

Now you may be thinking ‘ok, but where does it create the pdf itself?’ Actually, it just did. FOP prepared the input XML for an XSLT transform that transforms it directly into a PDF. So at this point we’re done looking at how to create a PDF using FOP in Java.

If I look at this from a perspective that doesn’t already have the assumptions a Java developer has to have, I might think that I have to know an awful lot of details about FOP, XML, XSLT, OutputStreams in Java etc. In order to accomplish a pretty small feature, but at least most of that is hidden from the calling code,which is all contained in the main() method in the example. Still, since we consider Java an object-oriented language we should compare what’s said about the original object-oriented language, Smalltalk,with what we actually see to be the case in another language that is supposed to be based on the same principles, Java, before we look at the equivalent code in Smalltalk. In the book Pharo by Example, the authors give various ‘tips’ from experienced Smalltalk programmers (often even from the author of Smalltalk himself) to help beginning Smalltalk programmers avoid common misunderstandings about the language and how to use it. The very first such tip is as follows:

Try not to care. Beginning Smalltalk programmers often have trouble because they think they need to understand all the details of how a thing works before they can use it. This means it takes quite a while before they can master Transcript show: ‘Hello World’. One of the great leaps in OO is to be able to answer the question “How does this work?” with “I don’t care”. “ – Pharo By Example

This appears to go directly against what we’ve seen so far of OO, or object-orientedness, if Java is anything to go by. Now let’s look at PDF manipulation in Smalltalk, using the PDF4Smalltalk library.

page := PDF.Page newInBounds: (0 @ 0 corner: 400 @ 600) colorspace: DeviceRGB new render: [:renderer | anXMLDocument’].
page saveAndShowAs: ‘loadedFonts.pdf’

The other common PDF library in Smalltalk, known as SmallPDF and used primarily for web applications, simply sends the message

renderOn: pdf

to the object you wish to render as a PDF.

Now probably those of you who don’t write software are thinking ‘why doesn’t Java … hell, why doesn’t every programming language work that way?’ The answer is more complex than you might expect, and is tied in with the reason Smalltalk is not, strictly speaking, an object or object-oriented language. As you might expect, Smalltalk is rather productive. Although Java developers do fairly well at ~12x the productivity of basic assembler, Smalltalk developers are estimated to average ~31x the productivity of those working in assembler. The popular combination of HTML5 and JavaScript, as a further comparison, is only marginally more productive than assembler itself, about 1.5x the average number of function points / month / developer as compared with the baseline of writing in assembler. To paraphrase the author of the study, Capers Jones, writing code in HTML5/JavaScript is not development, it’s development malpractice.

Those of you who do write software, but are unfamiliar with Smalltalk, are probably thinking “well, he’s hidden all of the hard stuff away in another class”. The surprising thing is that if you go looking for the “hard stuff” you’ll have a difficult time finding it. To demonstrate this, the following is the entire code base for writing the PDF file itself:

saveAs: aFilename

| wst fst |

wst := Writer on: ByteString new.

self writeFile: aFilename on: wst.

fst := (aFilename withEncoding: #binary) writeStream.

[fst nextPutAll: wst contents asByteArray] ensure: [fst close]

writeFile: aFilename on: wst

| trailer refs xrefs startxref |

trailer := Trailer new.

trailer at: #Info put: self info newReference.

trailer at: #Root put: self root newReference.

refs := trailer tracedReferences.

trailer at: #Size put: refs size + 1.

self assignObjectNumbersTo: refs.

self writeHeaderOn: wst.

xrefs := self writeObjects: refs on: wst.

startxref := wst position.

wst cr.

xrefs writeOn: wst indent: 0.

trailer addFileIdentifierWithFile: aFilename andSize: wst position.

wst cr.

trailer writeOn: wst indent: 0.

self writeStartxref: startxref on: wst

writeHeaderOn: wst

wst nextPut: $%.

self version writeOn: wst indent: 0.

wst

cr;

nextPutAll: ‘%âãÏÓ’;

cr

writeObjects: someReferences on: wst

Write someReferences to the stream.

The references must have numbers assigned”

| xrefs |

xrefs := someReferences collect: [:reference |

| pos |

pos := wst position.

reference writeIndirectObjectOn: wst indent: 0.

wst cr.

UsedReference value: pos number: reference number generation: reference generation].

^CrossReferenceSection initialOn: xrefs

writeStartxref: positionInteger on: wst

wst

cr;

nextPutAll: ‘startxref’;

cr;

nextPutAll: positionInteger printString;

cr;

nextPutAll: ‘%%EOF’

Granted, that’s not quite ‘trivial’ code in the same sense as the calling code was, but I guarantee you it looks trivial in comparison with FOPs internal equivalent. What will be bugging those who write in languages such as C++ and Java is how does the caller know what to send, and how does the receiving object interpret it? Obviously, no matter how terse the Smalltalk syntax, XMLDocument anXMLDocument: renderOn: pdf cannot be a full method call. The answer is given in Pharo by Example in another ‘tip’:

… we do not “call methods”: we “send messages.”. The choice of terminology is significant. Each object has its own responsibilities. We do not tell an object what to do by applying some procedure to it. Instead, we politely ask an object to do something for us by sending it a message.” – Pharo By Example

The terminology is significant, and most significantly, this is not the sort of thing that one can ontologically expect of an “object”. Strictly speaking, there is no such thing as an object outside a scientists lab. Out in actuality we find things, people, animals. Things might be mere things, technological things, works, etc. The reason one can’t “ask” an object anything relevant is that neither you nor it can say what it is as such, insofar as it remains an object. As an example, a statue may become an object for a scientist in a lab. He can tell you all kinds of things about it, he can tell you its approximate age, approximately where it came from, what it is made of, etc etc ad nauseum. What he can’t tell you is that it is as a statue of the Buddha, not unless he drops scientific objectivity, i.e. drops the notion that he is facing an object, and returns to life as a human being addressing a thing, a thing that is at the same time a work. Even in this case, though, he might be able to tell you what it is, but he can’t ask it anything, because as complex as a work is, it is not a Self. In Aristotle’s old term a Smalltalk “thing” is an entelechy, something “at work remaining its Self”.

In part two I will discuss the sense in which “being an entelechy” rather than an object applies to Smalltalk things, but not to otherwise equivalent things in languages such as Java, even though Java objects can reference themselves with the this keyword. While strictly speaking this in Java may be equivalent to self in Smalltalk, Java objects do not implement the style of behaviour expected in a Smalltalk “object”, the style of behaviour of an entelechy.

What distinguishes objects from things of experience, whether they are selves, mere things, or even hypothetical things, such as the things of mathematics, is that they are determined by manipulability and as such always already subsumed in a Gestell, or framework.  As such objects can only be ascertained at all by a gestellen, or apparatus.  It’s not accidental that the reality of a quantum physicist such as Karen Barad is made up of intra-actions between objects and apparatuses which are only distinguishable by a specific agential cut in a phenomenon.  It’s no more accidental that C++ and Java contain innumerable frameworks for accomplishing just about anything you need to accomplish.  While there are a few frameworks in Smalltalk, such as Glorp for mapping things to relational data stores, and Seaside for mapping Smalltalk entities to web application features, they are not nearly as prevalent as in C++ and Java, where the object-nature of the programmatic entities demands framework and extensive programmatic apparatus in order to facilitate manipulation.  A Smalltalk thing can be expected to know a significant amount about itself, or be able to dynamically ascertain such, and for that reason a simple message is enough.  Precisely how it does what it does with the message is not the sender’s business but the receiver’s.  Objects on the other hand, in object or object-oriented languages such as Java, are passive, allowing themselves to be totally manipulated by method calls that therefore have to know just about everything about the object, since it makes no attempt to interpret.

Which comes to the last pair of quote from Pharo by Example, and the end of part one of this article.

“(A) message is not a piece of code: it is nothing but a name and a list of arguments. The receiver then decides how to respond by selecting its own method for doing what was asked. Since different objects may have different methods for responding to the same message, the method must be chosen dynamically, when the message is received.”

As Java and C++ programmers would have likely guessed, the message is not simply another name for a method call, but a request that the receiver do something.  What method actually gets called and what information that method requires is determined by the receiver.

“… pretty much everything does truly happen by sending messages. In particular, since there are no “public fields” in Smalltalk, the only way to update an instance variable of another object is to send it a message asking that it update its own field. Of course, providing setter and getter methods for all the instance variables of an object is not good object-oriented style. Joseph Pelrine also states this very nicely: ‘Don’t let anyone else play with your data.”

That a class with nothing but private instance variables and getters and setters for the same is so ubiquitous in Java that it is known as a POJO (Plain Old Java Object) says plenty about the disparity between languages such as Java and a language such as Smalltalk.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s