Guilhermesilveira's Blog

as random as it gets

Posts Tagged ‘java

RESTEasy: Where did the hypermedia go to?

with 15 comments

Some friends have asked what are the major differences between Restfulie and RESTEasy client frameworks.

Strong coupling and hypermedia awareless

As of today, Resteasy requires you to create an interface mapping every resource operation to a specific method, using @VerbName and @Path annotations to specify the desired target URI.

RESTEasy is ignoring the power of hypermedia content on the client side, thus being level 2 according to Leonard Richardson, and not matching Roy Fielding’s description.

RESTEasy is not Roy’s REST

According to Roy Fielding:

But hypertext as the engine of hypermedia state is also about late binding of application alternatives that guide the client through whatever it is that we are trying to provide as a service.

And any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type

Guess what? Java interfaces with @VerbName + @Path annotations means early binding, means an effort trying to describe which methods to use on which URI’s: tighter coupling, less space to evolve your server systems.

Going further:

It is fundamental to the goal of removing all coupling aside from the standardized data formats and the initial bookmark URI.

Restfulie provides a way to access only the initial bookmark URI, everything else is derived from navigating through your resources and its states.

Roy’s dissertation puts his believe quite clear in hypermedia being an important point of the web in chapter 5, his first paragraph: “Representational State Transfer (REST) architectural style for distributed hypermedia systems”.

RESTEasy got it right when it allows the user to access multiple URIs and the http protocol as the application protocol. But it still helps creating strongly coupled systems. Those who use JAXB (JAX-RS required) and fixed xml schemas do not allow server to evolve without prior notice to their clients. Ian Robinson has written about links in his blog and – another option – contract based systems in ThoughtWorks Anthology.

Back in 2007, there was a nice discussion on SOA allowing the users to create strongly coupled systems, where Mark Baker cleared it: SOA is constraintless, therefore one can create strongly and loosely coupled systems.

RESTEasy not supporting hypermedia content by default matches Roy’s definition of unrestful:

In other words, not RESTful at all. REST without the hypertext constraint is like pipe-and-filter without the pipes: completely useless because it no longer induces any interesting properties.

Although RESTEasy supports atom feeds, which is a good point, if the client wants a real hypemedia aware resource, he has to work on the deserialization process on his own.

RESTEasy does not provide the class generation mechanism that Restfulie (both Java and Ruby) provides so end users are able to transverse your resource’s tree and states without prior knowledge of every other URI.

According to Roy, one of the key benefits of the REST archicture style is its visibility through out the entire layered system:

REST is an architectural style that, when followed, allows components to carry out their functions in a way that maximizes the most important architectural properties of a multi-organizational, network-based information system. In particular, it maximizes the growth of identified information within that system, which increases the utility of the system as a whole.

By fixing all URI’s on the client side, along with not supporting hypermedia content by default, RESTEasy provides less information to layers contained between the server and the client: thus less visibility.

Server side

The same issues arrive when talking about the server side: RESTEasy does not provide any default interface for hypermedia content, but JAX-RS default support to JAXB: plain xml. It is up to (good) programmers to know how to make use of hypermedia systems in order to create a loosely coupled system.

Languages

Another key point on Restfulie’s approach is that it is Java-INdependent. Every month we see a larger number of integration software being developed in other languages: Restfulie can already help Java and Ruby developers.

Advertisements

Written by guilhermesilveira

December 3, 2009 at 6:05 am

Posted in java, restful, ruby

Tagged with , , , , , , , , ,

Restfulie Java: quit pretending, start using the web for real

with 5 comments

Its time to release Restfulie Java, offering the same power encountered in its ruby release, through the use of dynamic bytecode generation and request interception using VRaptor.

Serialization framework

Restfulie adopts XStream by default. Its simple usage and configuration gets even easier due to vraptor’s serialization extension built upon XStream – but it allows the usage of other serializers.

The following code will serialize the order object including its children items (much similar to rails to_xml only option):

serializer.from(order).include("items").serialize();

Connected: Hypermedia content creation

In order to guide the client from one application state to another, the server needs to create and dispatch links that can be interpreted by the client machine, thus the need for generating hypermedia aware serialization tools and consumer apis.

Its the basic usage of the web in a software-to-software communication level.

Pretty much like Restfulie’s ruby implementation, by implementing the getFollowingTransitions method, restfulie will serialize your
resource, generating its representation with hypermedia links:

public List getFollowingTransitions(Restfulie control) {
  if (status.equals("unpaid")) {
    control.transition(OrderingController.class).cancel(this);
    control.transition(OrderingController.class).pay(this,null);
  }
  if(status.equals("paid")) {
    control.transition(OrderingController.class).retrieve(this);
  }
  return control.getTransitions();
}

Controller interception

Restfulie for Java goes further, intercepting transition invocations and checking for its status. The following example will only be executed if order is in a valid state for paying:

@Post @Path("/order/{order.id}/pay")
@Consumes("application/xml")
@Transition
public void pay(Order order, Payment payment) {
	order = database.getOrder(order.getId());
	order.pay(payment);
	result.use(xml()).from(order.getReceipt()).serialize();
}

Why?

Restfulie does not provide a bloated solution with huge api’s, trying to solve every other problem in the world. According to Richardson Maturity Model, systems are called RESTFul when they support this kind of state flow transition through hypermedia content contained within resources representations:

<order>
 <product>basic rails course</product>
 <product>RESTful training</product>
 <atom:link rel="refresh" href="http://www.caelum.com.br/orders/1" xmlns:atom="http://www.w3.org/2005/Atom"/>
 <atom:link rel="pay" href="http://www.caelum.com.br/orders/1/pay" xmlns:atom="http://www.w3.org/2005/Atom"/>
 <atom:link rel="cancel" href="http://www.caelum.com.br/orders/1" xmlns:atom="http://www.w3.org/2005/Atom"/>
</order>

Stateless state

In order to profit even more from the web infrastructure, Restfulie for Java provides a (client state) stateless api.

Addressability

VRaptor’s controller api allows you to specify custom URI’s (and http verbs) to identify resources (and transitions) in your system.

Addressability + client cache stateless state server allows one to achieve REST’s idea on cache usage and its related layered systems advantages by allowing other layers to be added between the client and the server.

Unknown usage of my resources

Addressability + hypermedia content allows clients to use your resources pretty much in a way that was not tought of at first. Addresses (in our case, URI’s) can be passed around from one application to another, to and from a client’s internal database (as simple as a browser favorites, or google gears).

Building your system upon such basis, it become unaware of its resources usage (resource representation’s interpretation) patterns, allowing clients to create such previously unknown systems.

Less and simpler code, more results

Both on the server and client side, restfulie tries to achieve results based on conventions, therefore one can easily access its entry api to insert a resource in a system, i.e.:

  Movie solino = new Movie();
  resource("http://www.caelum.com.br/movies").include("metadata").post(solino);

And after creating a resource, one can actually navigate through your resource’s connections:

  Movie solino = resource("http://www.caelum.com.br/movies/solino").get();
  Comments comments = resource(solino).getTransition("comments").executeAndRetrieve();
  // print all comments

And navigate through your resource’s states:

  Comments comments = resource(solino).getTransition("comments").executeAndRetrieve();

  Comment comment = new Comment("nice movie on generations of immigrants and the hard times that they face when moving to a new place");
  resource(comments).getTransition("add").execute(comment);

A lot of good practices should be put into place in order to avoid creating Leonard Richardson’s defined REST-RPC alike systems.

Those good practices involve simple steps as avoiding anemic models on the client side . Restfulie+Vraptor already tries to avoid this on the server side andwe will discuss about such practices in following posts.

Download and example applications

Beginners could start by downloading restfulie’s client and server example application, ready to run in a eclipse wtp enviroment or pure eclipse installation.

Users are encouraged to use either the java or ruby mailing lists.

Since Restfulie was born in Ruby…

Since we released restfulie for ruby (on rails), which can be found at its github page, it was commented by Jim Webbers both on his blog and in person during QCon in San Francisco, where both him and Ian Robinson held a tutorial on restful systems and the web and will hold another round, more hands-on, at QCon London 2010.

Meanwhile, Restfulie was commented at ruby5’s podcast, commented here, at infoq, and in portuguese by Juliana and by Anderson Leite – a fellow Caelum developer.

As some comments were out about restfulie’s ruby implementation, restfulie: it’s more than easy.

Written by guilhermesilveira

November 25, 2009 at 11:13 am

Using the web infrastructure

leave a comment »

Some recent posts here and at our company’s blog were dealing on how to use the web as an infrastructure for distributing an algorithm, but this post is related to how to supply a service or resource based system using some of the web infrastructure.

Last year, at Falando em Java 2009, Jim Webberr spoke about HATEOAS, Microformats and how hipermedia content could add to a servicing system.

Based on his upcoming book and some of the ideas presented on his blog, I have created a small project with the help of Adriano Almeida and Lucas Cavalcanti at Caelum to help others explore some of those topics in a easy way.

Two simple projects show off what hypermedia content can do to simple resource/service based applications.

The server application is responsible for a small and simple ordering system where one:

1. sends an order (post)
2. requests it’s status (get)
3. sends an update (post)
4. cancel it (delete)
5. pay it (post)

Actions 3-5 are made available through action 2: by getting the resource representation, one can parse it and find its available actions – leaving it to a human-programmed software to request the next step in its flow or, for those who see flow automation as a good thing, for an automatic generic client to decide whats the next step.

The client application is responsible for being a “generic client”. But a generic client can be something harmful too so its one designed for those users who want to test their servers and learn how those resources work.

In order to try out the applications, you can use the google app engine infrastructure and follow the steps below:

Entry Point

Every resource/service based application has a single or set of entry points. From the point of view that such integrated systems should be programmed by humans (and not entirely automated), the consumer application should be aware of the entry point and its http verb, therefore:

Access http://restful-client.appspot.com/ and try to post an order to:
a) entry point: http://restful-server.appspot.com/order
b) method: POST
c) name: content
d) content: any order content (it will not be validated)

This is a well-known entry point and both client and server application are aware and agreed on that. By following that mindset, one will have a set of those entry points that are aware for both sides.

Those who look for fully automated services or systems will probably create a single starting point containing a GET request which results in the set of former entry points.

Running the consumer application

PAY ATTENTION: you might need to run it twice when you first run it. google app engine has a slow startup time that
might run a timeout prior to succeeding.

After posting the order, you will receive a 201 response with your order location.

You can then view (GET) this order to see its representation. By parsing the representation, one can discover what you can do with your order:

– pay (request a payment POST)
– cancel (request an order DELETE)
– update (request an order UPDATE)
– view (request an order GET)

Anytime you can check your order status by getting it. After payment your status will change to PREPARING and after one minute it will be DONE. If you cancel your order, it will be CANCELED.

While the client application is mostly a javascript+html view of what is being consumed, it still contains some vraptor serving our requests. This way we were forced to visualize for the first time how can we generalize a little bit the idea so we create a somehow generic consumer library in Java.

At the same time, a ruby version of the server side library supporting services-aware-resources will be released here soon. The java version is also being built around vraptor already. The next step is to build a ruby library – due to its dynamic nature, one can create really nice resource representations on the client side of what we just received from the server.

Those interested in helping us are welcome to mail me.
Although its a simple server application, it is a good way to show how to use the web as an infrastructure in a little bit more than the (rest-non-ful) CRUD examples found on the web.

Written by guilhermesilveira

October 27, 2009 at 6:18 pm

Posted in restful, Uncategorized

Tagged with , , , ,

Fractals in cloud computing with Google App Engine

While studying math methods as a minor in my applied math course, I had a mentor, Eduardo Colli, who helped me teaching the math requirements to implement a desktop based discrete dynamical systems software, Pulga. In the dynamical systems area – usually non-linears – people started talking about caothic behaviour of particles and one of the most famous systems is the Lorenz attractor.

atrator de Lorenz

As most of those algorithms can be run concurrently, we have decided to send it to Google App Engine in order to test it in a highly demanded way, enjoying the benefits of running in a cloud enviroment to generate results quicklier, as in a cluster, but using the http and internet infrastructure as a cluster: Google App Engine would help not only with scalability and availability but also improving performance. The basic algorithm iterates a billion+ times through some mathematical functions. In the traditional, desktop, approach, this is run in a single thread, in a code which resembles:


for(int time = 0; time < 60*60; time++) {
  for(int initial=0;initial < 1000; initial++) {
    x0, x1 = intiialCondition[initial];
    for(int iteration = 0; iteration <= 100000; iteration++) {
      x0, x1 = calculate(x0, x1);
    }
  }
}

The code above is much simples than the original source, but illustrates how slow the software can be. A simple execution would be finding an attractor’s basin of attraction, a task which would take between 2 to 5 minutes to draw the Henon map.

In our machines, Henon’s bifurcations diagram, as the above image from wikipedia, would take 5 minutes:

diagrama de bifurcação do mapa de henon

At first sight, those results seem to be achieved in a short period of time, but once Henon’s map relies on two parameters, if we wish to create a movie by scanning one of those parameter’s domain (considering it the time), a one minute video would take about 3 hours of computer time. In real situations, with different strange attractors, some movies would take more than 7 hours to be created.

In order to run it in a parallel way, the new application has 3 parts: a client which sends a single request, a server written in ruby which receives this request and dispatches hundreds of requests to the cloud, using the well known http protocol, returning parts of the graphic.

The client will request the server for colors to paint the image through ajax/jsonp. The server app sends all requisitions using non blocking io and could be somehow enhanced through the use of ruby 1.9 fibers. This NIO api from ruby is similar to Java’s NIO.
Once the requests get to the Google App Engine, it will basically run a code quite similar to the original desktop client core. After each execution, those numbers are returned to the ruby server, which concatenates data and generates the final result.

Initial tests have shown response times 51 faster than running on a single client by using 100 parallel http requests to Google App Engine:

100 random points iterations per request

Requests Total time (seconds) Iteration time (miliseconds)
local 6 16.6
1 3 33
10 6.4 156.25
50 14 357
100 17 588
200 23.55 849

Using memcached, Google App Engine’s cache api, we achieved even faster results:


CacheFactory cacheFactory = 
       CacheManager.getInstance().getCacheFactory();
cache = cacheFactory.createCache(Collections.emptyMap());
String result = (String) cache.get(script);
if (result != null) { ... }

This simple modification helped us achieving 93 times faster response running in ~100 machines!
Of course, some machines did not answer properly and the server could deal with that by just using standar http protocol and further requests.

We could improve it even more by using the HTTP/internet provided infrastructure: proxies. By correctly configuring our proxies, many of those requisitions achieved the same task, resulting in absolutely amazing responses. That is why RESTFul webservice’s gurus consider Squid a great choice over a giant ESB system.

hiperboloide

For those who are interested, here are some examples of 2d dynamical system maps which can be easily implemented.

Batch processes and reports are tasks which usually take some long time to run and many of those could be breaken in many parallel processes.We, developers, will soon be running all our code in those cloud systems: not only in order to achieve higher and higher scalability and availability goals, but because this elastic infrastructure allows hosting companies to have less costs. Knowing how to profit from those systems is the role of a developer. Non-relational databases and languages with different approaches to concurrent programming than the traditional java/pthread one, are showing to be excelent ideas to chase.

Written by guilhermesilveira

September 4, 2009 at 5:27 am

Posted in java, mathematics, ruby

Tagged with , , ,

Dev in rio 2009

leave a comment »

Some good friends from globo.com (Guilherme) and myfreecomm (Henrique) have invited two speakers from the Caelum team to talk about Java at this year’s Dev in Rio.

Guilherme and Henrique will start the event monday morning and after that me and Nico Steppat will talk about how new modern languages (either dynamic, functional, more or less expressive or anything alike) are influencing the market around the world and how we can enjoy the benefits of those languages within the scope of a polyglot-programming team. Java shows its signs of age, so how can we face those changes in the world and profit from every positive aspects of those languages, while still benefiting something from the Java technology?

Ryan Ozimek will start talking about Joomla! and how it has been changing the and improving technology.

Fabio Akita from Locaweb will talk about Rails, we can expect some introduction to the rails enviroment and what has been developed so far by the community in order to make software development an easier task.

Jacob Kaplan-Moss will talk about Django, a well-known Python software that makes it easy to develop database-based websites.

And summing up, Vinicius Teles will gather all speakers and participants to talk about… software development.

It is a really nice chance to meet new people, learn and share ideas with some big names from the open source development community.

Written by guilhermesilveira

August 28, 2009 at 8:00 am

To break or not to break? Java 7?

with one comment

There is a short slide show to illustrate some thoughts. There will be better ones in the near future.

When is the right timing to break compatibility of a public api regarding its previous versions?

Well, in the open source communites there is a common sense that a library is allowed to cause some migration if there is a minor change (i.e. 1.1.5 to 1.2.0).

Whenever has a major change (i.e. 1.2.0 to 2.0.0) it might be completely rewritten in such a way that even allows its users to adopt both versions at the same time.

Some projects use the version number as a marketing technique in order to keep themselves up-to-date with their competitors.

Some products are famous for, whenever a new release appears, breaking compatibility with code written so far, requiring all programmers to rewrite part of their code. If you check Visual Basic’s life, every one-to-two years there was a major release with (usually) incompatibility.

VB programmers were used to that issue and kept coding the old projects using the previous release until the project was finished. Companies just got used to it and learned how to live on.

If your code is well tested through the use of automated tests, updating a library or a compiler/language version is an easier task because all incompatibility issues will be found prior to packing a new release of your product to your clients. testing++!

If you do not write code for your tests, as soon as you update a library/compiler/language, well….. have fun as it will probably be an unique adventure.

The java developers

Unfortunately, there is still a big part of the java community who do not write automated tests. Aside with the java legacy code that exists lacking any lines of automated tests in the world, sticking to compatibility between java releases can be seen as a good thing for the world, in general.

But for those who already write their tests, all that care with compatibility might be seen as a overestimated issue: due to the tests, we are ready to change and embrance those changes.

The java 7 crew is aware that there is a lot more that we can add to the language, but afraid because it will not preserve high levels of compatibility and usability.

What happens if the language has to worry so much about compatibility? It will evolve so slow that other languages have the chance to overcome it. This is the danger that the language itself faces. Java might not lose its position but one can find a lot more people arguing about language changes that could be done to the language – but are not… because preserving compatibility has been a main issue.

At the same time, some of the changes proposed might create huge incompatibility issues for those users who still do not write tests or that software who was not written using TDD practices. There is also another document on the same issue on the internet.

This proposes that methods defining a void return type should be considered as returning this. This way one can easily use it with Builder-patterned apis:


final JFrame jFrame = new JFrame()
.setBounds(100, 100, 100, 100)
.setVisible(true);

There are a few issues with that proposal that do not match the “let’s keep it backwards compatible” saying.

The first thing is that, nowadays, builder (or construction pattern) apis are already created returning something specific instead of void, as we can see from Hibernate‘s API, and the new date and time api.

The second point is that builders are used nowadays to create Domain Specific Languages and their implementation in Java do not use a single object because it would create a huge (and nasty) class. DSL’s are usually built in Java by using different types, i.e. the criteria API from Hibernate.

Even the given example is actually no builder api… JFrame configuration methods and real-time-usage methods are all within… itself! There is no JFrameBuilder which would build a JFrame, i.e.:


Builder b = new Builder();
b.setTitle("Title").addButtonPanel().add(cancelButton()).add(okButton());
JFrame frame = b.build();

Notice that in the simple example above, it would be a good idea to have two different types (Builder and PanelBuilder) thus the language modification do not achieve what we want our code to look like (or be used like). Instead, it will only allow us to remove the variable name from appearing 10 times in our code, making it easier for programmers to write lines of code like this:


// ugly line which has too much information at once
JFrame frame = new JFrame().setA("a").setB(2,3).setC("c").setD("d").andOn().andOn().andOn();

But why does it go against Java’s saying ‘we should not break compatibility’? Because it creates a even higher degree of coupling between my code and the api i am using.

Well, imagine that I used the swing api as mentioned above. In a future release of Swing, some of those methods might have their signature changed and therefore break my existing code. Why would an api change their method return type? Well, because if the return type was defined as void so far, no one was using it… so I can change it.

It creates the same type of coupling found while using class-inheritance in Java while using APIs. Parent methods being invoked might change their signature

Well, it was true until today. If this functionality is approved for the Java API, it will make a simple task of changing a “void” return type to something useful a hard task, where I have to think about those who have tightly-coupled their code to mine.

The questions and answers which come to my mind are…
a) is the existing Java codebase around the world usually automated tested? unfortunately, no
b) does Java want to be backward compatible? this change will not help it
c) does it want to help the creation of dsls? this change is not the solution
d) does Java want us to avoid writing the variable name multiple times? my IDE already helps me with that

Written by guilhermesilveira

August 17, 2009 at 1:24 pm

Comprehensible languages x Expressive code x The other side of the world

with 2 comments

One reason to care about expressiveness

Most developers agree nowadays that mantaining software is an important task, either refactoring it as a task is completed or one year later when new functionalities are added, the cost of maintainability should be kept as low as possible in most cases.

Mentioning most cases, i automatically exclude pieces of code or complete software written by any group who intentionally write in such a way that no common programmer is capable of understanding. I wrote this article only for those situations where the way you express your intentions becomes important in order to others – or even yourself – to understand it.

Lack of communication: a geek’s problem

Expressing ourselves was never the best of our abilities. As a stereotypical geek, I am a shy person whould only be able to freely express my intentions after a couple of beers. Being an uncommon practice to communicate with other type of people (not so much logical-driven thinking), does not give a geek a lot of knowledge on how to express his ideas in a more sensitive and human way.

Being also a hard task on its own to develop code without abusing from logical structures and tricks, everything contributes to make it a very difficult job for developers to write comprehensible code.

So why does your code looks comprehensible right now, but anytime later, completely uncomprehensible? And you just start to hate what you did? After refactoring it becomes, again, more comprehensible?

Its quite uncommon for one to get ideas quite clear in one’s head, prior to putting it on paper. How many times have we had those really bright ideas, and as soon as we write them down, the idea does not seem so clear? As we talk about it with other people, and come back to the same piece of paper, we can make our ideas more clear. It does not happen only with ideas being written on paper.

Artists face the same problem while painting, they do not know exactly what to paint, and may come back again and again in order to improve something they thought were ok, but later realized that was still not what they wanted to communicate through their art. The same thing happens with writers too, a book or an essay is not simply written. It is proof-read, re-writen, until the text passes to the reader the original idea that the writer wanted to pass.

Even great communicators may not achieve their best result on passing on their message on their first attempt. Why would a developer, sometimes a geek with dificulties to express himself as a person, would be able to express his idea in a great way at all?

So far, we have a few ideas on why is that expressing our ideas is important (maintaining software) and why is it hard for us developers to express our ideas (cultural issues, lack of practice, continuous improvement required).

Being born in a family of teachers and educators, I learned back home how important it was the ability to forget our current knowledge and talk to someone (express ourselves) as if the other end-point has no knowledge at all. This is the most important quality of a teacher… being able to level himself in such a way that his knowledge is exactly the same – nothing more – than his students.

Mindnote: it was not enough to lose my shyness, only enough to allow me (maybe) help some other people.

Being able to think in advance that our readers do not have the same knowledge that we do helps us to write (anything, not just code) text that can be easier understand by them. That is just a hint on the mindset one may have while writing.

Enough about communication skills, let me talk about what has been my passion for the past 2 years.

Koreans and japaneses

I still ask myself how do koreans and japeneses feel when they get a first glance at western grammar. Both languages share the same structure which is based on the “subject objects verb” sequence, in a completely different fashion of our’s commons “subject verb objects”. Furthermore, they share the notion of descriptive verbs and korean (I do not know any japanese) has suffixes to identify those objects in a much similar way that most languages uses prepositions or (german/latin) declinations.

We can illustrate the basic difference with a single sentence, when I would say “I went home late”, koreans would “I late home went”: “저는 늦게 집으로 갔어요”. Easy right?

Lets pick a daily life example with two phrases: “because i had no money with me, i went to the bank”. In korean? “with me money i had none because i to the bank went”. This single order change makes it really hard for us westerns to learn korean. But what about imperative sentences?

“you 1st room from 5th room until big room breakfast with rent!”

Maybe even for non-linguistics developers/fans, it might be easy to understand meaning hidden in the above paragraph. But might this change of order help us write better code? Should we start asking koreans and japaneses? Will it make it possible for me to write code which people will understand easier?

In the following paragraphs I will show what my mind went through to find out that:

  • I do not know the answer because korean is not my native language
  • It might be too late for korean developers to answer this question as they are already used to the way of thinking the programming languages oblied them to think
  • there is room for programming langauge improvement to allow us writing more expressive/easier to understand code

By the way, for those (if any) who did not understand, I gave an order to rent a big room checking in on the 1st and leaving on the 5th with breakfast inclusive.

Symbols x Language

Due to the obvious nature of this post, I am making no comments on languages as perl and haskell which appeals to (too many) symbols as a way to express one’s intention. Symbols are really great for defining abstract ideas. Symbols are hard to teach, to learn and to understand. And if someone makes just a small change to the set of symbols understood, your life becomes hell. Those languages go completely against what I – as a teacher/educator – think this is the right way of communicating one’s intention – in our case, express our code.

Symbols might achieve more results with less effort, but at the same time symbols are harder to understand. I will be glad to change my mind the day someone teaches a common person how to code in one of those languages faster than teaching someone how to code in ruby.

Our aim is not to create complex software or in cases where developing faster is not the only issue in game but keeping the code understandable is a issue, “too-much-symbols-based” languages do not offer what other languages do.

Coding, “korean style”?

This section will describe the problems I have faced while trying to do something similar to the way korean grammar expresses its sentences.

Because most languages were written with a western language mindset, they all only offer one way of declaring parameters, which describes them after what we recognize as the action being invoked. For example, in most languages, the rent order would be defined and invoked as:

invocation:
bigroom.rent (from: 1st, to: 5th, for: me, with: breakfast)

definition:
rent date from date to client for boolean with

I have chosen some type-definition-required-based language so the definition looks a little bit more natural to human eyes (yes, rent from to for with would be lesser compreensive).

But what if I wanted to use a language that values objects over actions. If you think about parameters as the objects, the object in which methods are invoked as the subject and methods/functions as verbs (this supposition might not always apply), one can see that our commonly used languages do value actions over objects. Actions define which objects they receive, instead of parameters defining which actions can be taken.

One simple change would be to write the invocation in a koren style:

invocation:
bigroom 1st부터 5th까지 ... rent

Soon, one starts to notice that 부터 (from), 까지 (until), 에서 (at) etc is not actually the variable type definition but something else! It is not the name of the variable itself, it is something else! What? Let’s come back to it really soon… but first,

What would be if things were completely written the other way around? In a way that parameters itreact with themselves and define the actions that can be executed with them? I have absolutely no idea how to define actions, given parameters, therefore I just left this question open and tried to think about other ways to improve what I write.

Language garbage

Note that if I define being garbage anything else that I would not require to express my idea to another human being, the above example if just full of it. Let’s remove some of the clutter:

invocation
bigroom rent from 1st  to 5th for me with breakfast
definition:
rent from checkin to checkout for client with optionalBreakfast

First of all, both sentences are much more natural, although the invocation could be written in a more imperative way as “rent the bigrrom from 1st to 5th for me with breakfast”, let me keep my exposition within OO based-languages.

We can also notice that I have removed type definition and added something else… that is still unclear what it is. And this is exactly what I think that we might try out. That is what I pointed out in the previous section.

Programming languages which do not allow us to invoke methods by using the parameter’s names are much less expressive than the ones which allow us (i.e. ruby):

invocation not using parameter names:
bigroom.rent(Date(1,7,2009),Date(5,7,2009), guilherme, true)

What??? What is the first, the second, the third and the fourth parameters? It is quite clear that the above piece of code lacks something in order to communicate what it really does. It lacks the parameter names (lets call them the parameter ID’s now, ok?).

But how do Java developers write expressive code without using named parameters? Easy, just extract variables!

invocation with “named” args:

from = Date(1,5,2009)
until = Date(5,7,2009)
client = guilherme
withBreakfast = true
bigroom.rent(from, until, client, withBreakfast)

Extracting variables was the refactor chosen in order to solve the problem or language limitation did not allow us to do it: use identifiers to our parameters. Now let’s see another example with a language which would accept parameter ids:

invocation in a language which uses named parameters:

bigroom.rent(from=Date(1,7,2009), until = Date(1,7,2009), client=guilherme, withBreakfast=true)

Its clear the same solution as with the Java language, but written in only one line. The disadvantage is that the line gets longer – and therefore more complicated. The advantage is that a language which obliges parameter ids to be passed forces our code to be more expressive and comprehensible. Unfortunately ruby does not (yet?) forces uses to write this way.

Note also that forcing parameter ids, one removes the need for creating tiny objects for developing small dsl apis. But this approach would not be recommended in a api which should be easily extended because tiny objects (used through their interfaces) are easier to extend.

Lets go further? The korean way of writing sentences showed me something that even the english approach does misses. Forcing parameter id’s was the first move and improves the ability to write invocations that are easier to comprehend. But what about the function/method definition? Can we improve something there?

current invocation:bigroom.rent(from=Date(1,7,2009), until = Date(1,7,2009), client=guilherme, withBreakfast=true)

current definition
rent from checkin to checkout for client with optionalBreakfast

But look, first of all the definition includes no parameter type definition, but does include the parameter id and something else. What is that something else?

If i rent, I have a checkin date, and the checkin date is identified with the from id. Therefore each parameter has actually “two unique identifiers”. An internal one which is used within the action/function/method definition, and an external one to be used when invoking the method. Our code would be implemented somehow as:

define rent from checkin to checkout for client with optionalBreakfast as

bookings add new Rent from checkin to checkout for client with optionalBreakfast

end definition

The above implementation invokes the Rent construction definition and invokes the add method in the bookings list.

Mindnote: symbols for adding items to lists and so on are, again, symbols, therefore not the most comprehensible feature of mankind.

Is it clear? Clear enough? Clearer than some other approaches? I can see it as a better way of writing codes but unfortunately I do not know any language so far that can help me this way. Let me try it a little bit further with a conditional statement:

if amUnavailable from checkin to checkout
then complain about unavailability
otherwise bookings add new Rent ...

Do I need to explain what is written here? Well, now ask your grand mother if she understands the above protocol. And yes, do not call it “logic” or “code”, call it a protocol… non-programmers would get it easier if you call it a procedure or protocol instead of “logic” or “code”… just a matter of names but allows people to better understand what you are saying.

Some languages would require the type definition, I understand those languages have reasons for thinking this is the best approach (yes, i am still a Java programmer and prefer defining variable types) and this could still be implemented in a more compreensible way using the above mentioned approach.

REST, URIs and experiments

Should URI’s express what they represent? What about the limitation on the Http methods when I am using web sites for human (not machine-to-machine) iteraction? That is what has been keep my mind busy yesterday, and will probably stick to mind while on the plane to Korea… it is just a pity I do not have access to Korean children so I could get their feedback on computer programming before they get a grisp of english.

Comprehensible languages

Summing up, I believe the code would be much more expressive and comprehensible if the language we use force us to use parameters with ids and IDEs helped us by given those names and not allowing us to change them. Simple changes, that would perhaps help others understand what we wanted to say.

Comprehensible languages would be programming languages which allow us as human beings to express ourselves in a way that we can understand each other instead of through abstract logical symbols.

Anyone willing to implement such language?

So what does Korea has to do with all this? Well, I always prefer telling people the history on how I come up with any idea.

Written by guilhermesilveira

July 12, 2009 at 11:51 pm