Igor Šarčević wrote this on October 13, 2015

Banning Iteration

In the last couple of months I have had the honor of being a mentor to several students that were taking part in our summer internship program. I had a ton of fun, learning not only about programming, but also about the art of teaching other programmers and helping them overcome their fear of complexity.

Even though they were all exceptional computer science students, a common pattern was their overdependency on the good old for loop. This was, of course, understandable. Java and C/C++ are the most popular teaching languages on our local universities. None of which, in my opinion, are good enough to prepare the students for the modern web and the level of abstraction required for working on bigger projects.

Basic iteration

One of the first things any computer science undergraduate learns is the for keyword. The magic word that can repeat common tasks and can even make our programs run forever. Here is a simple Java example that counts from one to ten:

for(int i=0; i < 10; i++) {

Another common thing is iterating over a list of values. For example, to collect the age of every user in an array, we could write:

int[] ages(User[] users) {
  int[] result = new int[users.lenght];

  for(int i=0; i < users.length; i++) {
    result[i] = users[i].getAge();

  return result;

The issue with iterating with a for loop

Take a look at the above example that transforms the array of users into an array of numbers. It is a lot of work for such a simple task. The following list contains the mental steps needed for writing the above implementation:

  1. Create an array that will hold the results
  2. Set the capacity of the array to match the number of users
  3. Create an iterator named i that will hold the current index of the array
  4. Set up an iteration construct that will loop over every user in the array
  5. Limit the iteration when the iterator i is the same as the number of users
  6. Increase the iterator i after each step in the iteration
  7. In every iteration lookup the user on the i-th location in the array
  8. Get the age of that user
  9. Save the age value in the result array on the i-th place
  10. When the iteration is over, return the result to the caller

Well… this was a lot of typing. Plenty of room for making an error while writing the implementation.

Luckily, there are much better ways to achieve our goals.

Eliminating the redundant i iterator

Many students learn the for(int i=0; i < N; i++) construct by heart and replicate it everywhere, replacing the value of N with an appropriate value. But why would we do this? Automating things is one of the core principles of our craft. We should never let the computers make a fool of us!

Let’s switch from arrays to lists and use the newer for loop syntax:

List<Integer> ages(List<User> users) {
  List<Integer> result = new ArryaList<User>();

  for(User user : users) {

  return result;

The above code looks nicer. Let’s write down the mental steps for this implementation.

  1. Create an array that will hold the results
  2. Set up an iteration construct that will loop over every user in the list
  3. Get the age of the user in each iteration
  4. Save the age value in the result list
  5. When the iteration is over return the result to the caller

Much nicer and easier to understand. Here are some steps that we don’t have to worry about anymore:

  1. Set the capacity of the array to match the number of users
  2. Create an iterator named i that will hold the current index of the array
  3. Limit the iteration when the iterator i is the same as the number of users
  4. Increase the iterator i after each step in the iteration
  5. In every iteration, look up the user on the i-th location in the array
  6. Save the age value in the result array on the i-th place

Language switch

Unfortunately, vanilla Java can take us only this far. It is still possible to conceptually improve the above, but it takes a lot of effort and it is against the flow of the language.

Introducing Ruby! The language that can easily take us to the next level.

First, let’s rewrite the above snippet in Ruby:

def ages(users)
  result = []

  for user in users do

  return result

A note for experienced Ruby programmers: I know you want to tear your eyes out, but please bare with me. The above monstrosity is only for demonstration purposes.

Let’s continue!

Eliminating the result set

First, let’s remove the non-typical for loop. Ruby programmers always prefer the each method over the for operator.

def ages(users)
  result = []

  users.each do |user|

  return result

While the above snippet looks quite nice, it is still far from perfect! Notice the redundant result list that we explicitly create for every list transformation.

Introducing the map method. It is very similar to the each method with a simple but very important feature. It creates the result set instead of us, and places the result of every iteration in the appropriate spot.

def ages(users)
  return users.map do |user|

Let’s review the mental steps in the above code snippet:

  1. Set up an iteration construct that will loop over every user in the list
  2. Get the age of the user in each iteration
  3. When the iteration is over return the result to the caller

The following steps are no longer needed:

  1. Create an array that will hold the results
  2. Save the age value in the result list

Eliminating the return statements

The last step that returns the value of the calculation is usually not needed in Ruby. The language is smart enough to return the last calculated value from any method.

def ages(users)
  users.map do |user|

This snippet reduces the number of mental steps to only two steps.

  1. Set up an iteration construct that will loop over every user in the list
  2. Get the age of the user in each iteration

Making the code nicer and more idiomatic

A true Ruby programmer would never write a get_age() method. Explicit actions are a relic of the past. Welcome to the age of declarative programming.

To access the age attribute of the method, we can simply write .age. Also, parentheses are optional. We will optionally remove them :)

def ages(users)
  users.map do |user|

The above method could be even shorter. A one-liner. In Ruby, the do ... end block is equivalent to curly braces.

def ages(users)
  users.map { |user| user.age }

Going even further by eliminating an explicit get

You probably thought that we could not go any further and declared it finished. However, there are still a couple of things that can be done. Notice that in the above example we explicitly read out the age value from every user.

Ruby has a shorthand operator for this.

def ages(users)

The above code snippet is equivalent to the previous one, but with one less mental step. Here is the current list of needed mental steps:

  1. Collect the age of every user

The following step is no longer needed:

  1. Set up an iteration construct that will loop over every user in the list

With the above code snippet, you could become good friends with any Ruby programmer. I am always happy to drink a couple of beers with programmers who can write code like this. Just saying…

The second Language switch

We are still not finished! Ruby is a great language but it has its limitations. But what could possibly be left to improve, you ask. Come and see. Introducing Haskell!

First, let’s start by rewriting the above snippet into executable Haskell code.

ages users =
  map age users

Eliminating the arguments

Haskell is quite smart when it comes to handling function arguments. It can pass the arguments to the end of a function’s body. The following is equivalent to the above:

ages = map age

It looks weird. I know! But you get used to it :)

Finally, let’s review the necessary mental steps for this implementation:

  • None. The above code is practically effortless.


We came a long way from our original implementation in Java. Just for comparison, here are two identical implementations:

int[] ages(User[] users) {
  int[] result = new int[users.length];

  for(int i=0; i < users.length; i++) {
    result[i] = users[i].getAge();

  return result;
ages = map age

I hope you, beloved reader, understand why I think that Java is far from ideal when it comes to teaching the next generation of engineers and overcoming the challenges that our craft presents.

Marko Anastasov wrote this on September 10, 2015

Enjoying The Conversations

One of the less obvious things that I enjoy about running a product company are the diverse conversations that I get to have with our customers. It starts with a formal correspondence, initiated by a support request, customer interview or feedback discussion. And it often ends there. But sometimes after you’ve exchanged enough words or spent enough time talking, something clicks. People relax and tell you more about what it is that they do, what’s happening, what have they learned recently, or what’s bothering them. It’s just a common human trait to enjoy sharing and hearing stories, I suppose. Count me in.

I’ve noticed that it is an often repeated startup lesson to go out and talk to your current or potential users. People get a little obsessed with the ideas that they have and start ignoring the rest of the world. And I can relate to that. New ideas can be really exciting. But if you’re building a product and not talking to your users on a regular basis, it’s not only the product-market fit that you’re likely going to miss. It’s the timeless pleasure of establishing human contact too.

Marko Anastasov wrote this on June 4, 2015

Our First Hackathon

On May 30 and 31st we organized the first Rendered Text web hackathon. Five teams of students from Novi Sad, Belgrade and Niš competed in developing a static code analysis web application for Elixir, using Elixir of course. They didn’t know the language or the objective prior to coming to the hackathon, as we held it as a surprise.

The hackathon was a big success: for 24 hours the teams worked hard to show what they can do, met fellow hackers and had some fun. We just enjoyed helping them do all that. The iPads went to good hands: the winning app can tell you a few basic things about the coding style and function complexity in a snippet of Elixir source code.

Rendered Text Hackathon

The 30 hours later picture

Keeping an Open Mind

Telling people to program in a functional, dynamic language which they’ve never used before is simply our idea of fun. It’s what we’d like to do on a hackathon ourselves.

Most of the software companies in Serbia are quite conservative when it comes to using and exploring new platforms. The term “new” in this context is relative: many regard Python and Ruby as new, even though they’re over 20 years old. This feeds back into the local education system, creating an environment in which students are often trapped in a closed mindset.

We believe the opposite — that during your studies is a great time to try very different things. This helps you discover what’s possible, try various programming languages, stack levels and paradigms. You also get to know and compare communities and start getting a sense of what is happening in the industry. For this reason we decided to make this hackathon an opportunity to work with something previously unknown. Darko wrote earlier about what makes Elixir particularly interesting. It has grown to version 1.0 since then and Phoenix has become a fully functional web framework.

“The topic was interesting and the atmosphere great. We never programmed in a functional language, so learning Elixir was both interesting and a big challenge. With a little more experience, you could use Elixir and Phoenix to build quite powerful things in a simple way,” said Marko Papić from the winning team.

Congratulations to all teams for the work and effort they put in!

You can view more photos from the hackathon here.

Marko Anastasov wrote this on February 18, 2015

Semaphore in DZone's 2015 Guide to Continuous Delivery

Many thanks to DZone for including Semaphore again in its annual report on continuous delivery, recognizing Rendered Text as a featured vendor.

DZone’s Guide to Continuous Delivery is a a premium resource focused on continuous integration and DevOps management trends, strategies, and tools. It gives an overview of continuous delivery practices and how continuous delivery affects many aspects of an organization.

You can download a free copy of the guide here.

Marko Anastasov wrote this on January 27, 2015

Photos from Rails Girls Novi Sad #1

Last weekend we co-organized the first Rails Girls event in our town.

Rails Girls Novi Sad #1

View more photos from the first Rails Girls Novi Sad in our Flickr album.

It was a great pleasure to introduce these curious girls to Ruby on Rails and the world of programming in general. They were only a fraction of those who applied to attend, so we’re looking forward to repeating this event and sharing the joy of coding again.

For news about future events, you should follow @RailsGirlsNS and @RenderedText on Twitter, or subscribe to our events RSS feed.

Marko Anastasov wrote this on July 4, 2014

Redesigned: The New RenderedText.com

This week we’re very excited that we launched a brand new design of renderedtext.com.

Our website looked like this for a very long time:

It was a great representation of us back around 2009-2010: a small and lean team doing full service web development. The layout was optimized for a few pages as they were conceived at the point of design and while we loved it, it was not flexible enough for new content ideas. As a result everything but the blog has eventually become out of date.

The new site looks like this:

The first thing you see is us, as our goal was to tell you more about who we are.

Nowadays there are always some events which we are either organizing or attending, places where you can meet us. So we are introducing a new section for events, with it’s own RSS feed which you can subscribe to. Our blog feed remains the same, however the fate of FeedBurner is questionable so we now encourage you to subscribe directly to renderedtext.com/posts.atom.

Visually, we looked for style over fashion. A layout that is simple, text-driven, pleasant to read and free from elements which look cool only to become passé soon.

We hope you like the new design. Our sincerest thanks goes to Superawesome for the collaboration on design and Nikola Bradonjić for photography. And to you — for listening.

Marko Anastasov wrote this on May 16, 2014

base-app and admin_view work with Rails 4

I just released admin_view 0.3 and tagged base-app at a point where they both work great with the latest Rails 4 (4.1.1 to be precise).

base-app is the Rails application template we use to jumpstart new projects. It includes the full BDD stack set up and a number of helpful gems configured to work out of the box.

admin_view is a small code generator that can create a nice Bootstrap-friendly admin interface for existing Rails models. In our practice we almost always want to be able to access some data from the database with a domain-specific twist. This gem helps us get the data immediately and the flexibility to customize whatever we need.

Marko Anastasov wrote this on May 15, 2014

Rails Girls Belgrade 2014 Applications Open

Just like last year, Rendered Text is supporting a Rails Girls event in Belgrade with mentorship.

The goal of Rails Girls is to give tools and a community for women to understand technology and build their ideas. This is done through a two-day workshop where women with no programming experience create a simple Rails web application.

The event will take place on May 31st and June 1st. More information (in Serbian) and how to apply is at railsgirls.com/beograd.

Please spread the word if you’re in the area. Feedback from last year was great and we’re looking forward to helping this year’s participants learn something new.

Browse Archive

If you like what you are reading, subscribe to our RSS. You can also follow us on @renderedtext for updates.


Rendered Text is a software company. For questions regarding Semaphore, please visit semaphoreci.com. Otherwise, feel free to get in touch any time by sending us an email.

Rendered Text
Svetozara Miletica 10
21000 Novi Sad