Plataformatec Blog http://blog.plataformatec.com.br Plataformatec's place to talk about Ruby, Ruby on Rails and software engineering Wed, 29 Oct 2014 13:22:47 +0000 en-US hourly 1 http://wordpress.org/?v=4.0 Playing with Elixir and Go concurrency models http://blog.plataformatec.com.br/2014/10/playing-with-elixir-and-go-concurrency-models/ http://blog.plataformatec.com.br/2014/10/playing-with-elixir-and-go-concurrency-models/#comments Wed, 29 Oct 2014 11:00:19 +0000 http://blog.plataformatec.com.br/?p=4271 »]]> In Go Concurrency Patterns talk, Google I/O 2012, presenter Rob Pike demos some great concurrency features from Go, like channels and Go routines, and how it can be used to build fast, replicated and robust software.

Concurrency patterns is a very interesting topic but there was one statement in special that got me thinking:

“The models are equivalent but express things differently.”

This is about the distinction between Go channels and its cousin Erlang messages passing approach to communicating between processes.

Implementing Go channels with Elixir processes and messages

Before discovering that it has been done before, I wrote some simple Elixir code to play with the theoretical equivalence between those two models.

Notice that this implementation is not meant to be complete, nor efficient and is not recommended for production software. Don’t do it at home.

defmodule GoChannel do
  def make do
    spawn(&GoChannel.loop/0)
  end

  def write(channel, val) do
    send(channel, { :write, val})
  end

  def read(channel) do
    send(channel, { :read, self })

    receive do
      { :read, channel, val} -> val
    end
  end

  def loop do
    receive do
      { :read, caller } -> receive do
        { :write, val } -> send(caller, { :read, self, val }); loop
      end
    end
  end
end

Some tests

defmodule GoChannelTest do
  use ExUnit.Case

  test "write and read to a channel" do
    channel = GoChannel.make
    GoChannel.write(channel, 'hello')
    assert GoChannel.read(channel) == 'hello'
  end

  test "write and read preserves order" do
    channel = GoChannel.make
    GoChannel.write(channel, 'hello')
    GoChannel.write(channel, 'world')
    assert GoChannel.read(channel) == 'hello'
    assert GoChannel.read(channel) == 'world'
  end
end

This pseudo channel implementation relies on a combination of messages between processes to simulate the original FIFO behaviour of channels.

The same way one could pass a channel as parameter to other functions, since it’s a first-class citizen, we could pass the result of GoChannel.make, since it’s a PID, which in turn is a first-class citizen in Elixir.

Back to concurrency patterns

The first pattern demonstrated in Rob’s talk was fanIn, where two channels were combined into a single one.

func fanIn(input1, input2 <-chan string) <-chan string {
    c := make(chan string)
    go func() { for { c <- <-input1 } }()
    go func() { for { c <- <-input2 } }()
    return c
}

We could translate this code to Elixir, using our borrowed abstraction:

defmodule Patterns do
  def fan_in(chan1, chan2) do
    c = GoChannel.make

    spawn(loop(fn -> GoChannel.write(c, GoChannel.read(chan1)) end))
    spawn(loop(fn -> GoChannel.write(c, GoChannel.read(chan2)) end))

    c
  end

  defp loop(task) do
    fn -> task.(); loop(task) end
  end
end

Some tests:

defmodule PatternsTest do
  use ExUnit.Case

  test "fan_in combines two channels into a single one" do
    chan1 = GoChannel.make
    chan2 = GoChannel.make

    c = Patterns.fan_in(chan1, chan2)

    GoChannel.write(chan1, 'hello')
    GoChannel.write(chan2, 'world')

    assert GoChannel.read(c) == 'hello'
    assert GoChannel.read(c) == 'world'
  end
end

We could go even further in this mimic game and try to implement the select statement, but that would be a very extensive one. First let’s reflect a little about composing more complex functionality with channels.

Channels as Streams

From a consumers perspective, reading from a channel is like getting values out of a stream. So, one could wrap a channel in a stream, using the Stream.unfold/2 function:

  def stream(channel) do
    Stream.unfold(channel,
                  fn channel -> {read(channel), channel} end)
  end

This function returns a Stream, which gives us lots of power to compose using its module functions like map/2, zip/2, filter/2, and so on.

One test to demo that:

  test "compose channel values with streams" do
    channel = GoChannel.make
    stream = GoChannel.stream(channel)

    GoChannel.write(channel, 1)
    GoChannel.write(channel, 2)
    GoChannel.write(channel, 3)

    doubles = Stream.map(stream, &(&1 * 2)) |> Stream.take(2) |> Enum.to_list

    assert doubles == [2, 4]
  end

Reviewing comparisons

The following quote from Rob Pike's talk is one common analogy used to compare channels and Erlang concurrency models:

“Rough analogy: writing to a file by name (process, Erlang) vs. writing to a file descriptor (channel, Go).”

I think analogies are really useful for communication but I believe they work better as the start of an explanation, not its summarization. So I think we could detail differences a little further.

For example, PIDs are not like “file names” since they are anonymous and automatically generated. As we just saw, PID is a first-class citizen and in the language’s perspective, is just as flexible as a channel.

I would say that channels abstraction reinforce isolation from producer to consumer, in the sense that Go routines writing to a channel doesn't know when nor who is going to consume that information. But it doesn't mean that using processes and messages one could not achieve the same level of isolation, as we just demoed.

On the other hand, identifying producers and consumers explicitly allow us to monitor and supervise them, allowing language like Erlang and Elixir to leverage the so-called supervision trees useful for building fault-tolerant software in those languages.

Besides been an interesting exercise to mimic Go’s way of solving problems, one should be aware that Erlang and Elixir have their own abstractions and patterns for handling concurrency.
For example, one could use the GenEvent module to implement a pub/sub functionality.

Elixir, Erlang and Go have some common goals, like the ones cited in the first paragraph of this post, but they also have their specifics. Embracing differences provides better results in the long term because it helps leverage each language power.

References












]]>
http://blog.plataformatec.com.br/2014/10/playing-with-elixir-and-go-concurrency-models/feed/ 0
Estamos contratando mais desenvolvedores! http://blog.plataformatec.com.br/2014/10/estamos-contratando-mais-desenvolvedores/ http://blog.plataformatec.com.br/2014/10/estamos-contratando-mais-desenvolvedores/#comments Wed, 22 Oct 2014 11:00:38 +0000 http://blog.plataformatec.com.br/?p=4253 »]]>  

Plataformatec team

Neste ano a Plataformatec completou apenas 5 anos, mas olhando para tudo que nós conseguimos conquistar, parece que se passou muito mais tempo. É fato que nós cometemos alguns erros, mas é uma enorme certeza de que aprendemos muito mais.

E agora, que nós estamos olhando para os próximos anos, queremos convidar mais pessoas a juntarem-se ao nosso time. Nós queremos pessoas que compartilhem dos nossos valores, que se importem com o que fazem e que não cansem de aprender e de se superarem.

Se você está interessado em trabalhar em um ambiente que exige colaboração e que estimula as pessoas a se desenvolverem, então queremos te convidar para participar do nosso processo seletivo.

Estamos contratando mais desenvolvedores e os requisitos da vaga são:

  • Inglês intermediário
  • Experiência com desenvolvimento de aplicativos web em qualquer linguagem (pelo menos 1 ano)
  • Experiência com Ruby e Rails (pelo menos 6 meses)
  • Disponibilidade integral
  • Local: São Paulo (nosso escritório)

Para participar do processo seletivo visite http://plataformatec.com.br/careers. Veja também nossa página no Facebook para conhecer mais sobre o nosso time.

Estamos esperando por você!

]]>
http://blog.plataformatec.com.br/2014/10/estamos-contratando-mais-desenvolvedores/feed/ 0
The brand new Plataformatec blog http://blog.plataformatec.com.br/2014/09/the-brand-new-plataformatec-blog/ http://blog.plataformatec.com.br/2014/09/the-brand-new-plataformatec-blog/#comments Tue, 30 Sep 2014 12:00:35 +0000 http://blog.plataformatec.com.br/?p=4235 »]]> Today we are shipping a whole new design to improve your navigation and reading experience on our blog!

The brand new Plataformatec blog

Back in 2012 we rolled out our new visual identity and website, but we didn’t change our blog much at the time. So we decided that it was time to give some love to our blog and work on a full redesign over the last couple of months. We are really excited to release this work for everybody who reads our posts.

Fonts are bigger, colors are brighter and everything looks much better on your smartphone than it used to. We focused on improving the reading experience and on a more up to date look for our blog.

The whole development process was a great experience, from design to code, and I want to share some of the story of how we got there:

The (re)design process

At first we started sketching everything with HTML and CSS trying to put together our new look with some elements of our existing layout. As things started coming into shape, the next step was to put together a Jekyll website with all of our blog posts (thanks to jekyll-import) so we could easily test the new design against our existing content, rather than against a bunch of “Lorem ipsum” posts. This was really useful when reviewing the code snippets in our posts and visualizing how we could improve the syntax highlight using something else than the previous WordPress plugin we were using.

As we designed and prototyped each piece of our new layout, people outside the redesign project jumped in and participated through the Pull Requests that we used for building those blocks. A good part of our team was part of the whole process helping out with design/code/copy feedback.

One of the Pull Requests in our new theme

The Journey into WordPress

One of the first decisions was to keep using WordPress as our blog engine. Over the last years a lot of alternatives have surfaced (like Ghost), but WordPress still feels the most complete blogging solution for us, so we’re still using it for the time being.

Given that, one of our challenges was to learn how to work with WordPress and convert our design (built on top of a Jekyll site) into a WordPress theme that we could install in our blog. This task ended up being much easier than expected.

After finishing the first complete iteration of the layout, I spent a few days watching some of the WordPress courses on Treehouse to learn how to work with WordPress themes and the whole PHP API behind it. I’ve mixed together some Bash scripts, a proxy server built with rack-legacy and some Gulp tasks to automate a local WordPress environment and migrated our Jekyll templates into PHP ones and we were set!

This might sound a bit too complicated, but the idea of starting with Jekyll to focus on the design process and quick iterations to later worry about the theme “infrastructure” was a well payed bet so I didn’t have to juggle both problems at the same time.

The best is yet to come

The idea is to not stop here. There are still a lot of improvements we want to do on our blog and all the tooling we have put together makes it easy to jump back and iterate over the design and the code.

Let us know if you find anything broken around here and we will jump on it to fix it. We hope you enjoy this new look and feel while reading through our blog posts :heart:!


]]>
http://blog.plataformatec.com.br/2014/09/the-brand-new-plataformatec-blog/feed/ 3
Writing assertive code with Elixir http://blog.plataformatec.com.br/2014/09/writing-assertive-code-with-elixir/ http://blog.plataformatec.com.br/2014/09/writing-assertive-code-with-elixir/#comments Wed, 24 Sep 2014 12:00:01 +0000 http://blog.plataformatec.com.br/?p=4228 »]]> Functional languages are typically great languages for writing assertive code and Elixir is no exception. In this blog post, I would like to discuss some anti-patterns I have seen in Elixir code and how to rewrite them in a way to make the best of Elixir.

Pattern matching

Imagine you have a string with format foo=bar&token=value&bar=baz where you want to extract the value for the key token which may appear anywhere or not at all in the string.

Here is one solution a developer not very-acquainted with pattern matching would try:

def get_token(string) do
  parts = String.split(string, "&")
  Enum.find_value(parts, fn pair ->
    key_value = String.split(pair, "=")
    Enum.at(key_value, 0) == "token" && Enum.at(key_value, 1)
  end)
end

At first the code seems to work fine but once we go deeper we can see it makes many assumptions we have not really planned for!

For example, what happens if someone passes "foo=bar&token=some=value&bar=baz" as argument? The code will work and will return the string "some". But is that what we really want? Maybe we wanted "some=value" instead? Or maybe we wanted to reject it all together?

There are other examples where the code above would work by accident, possibly adding complexity to the codebase as other users may start to rely on such behaviour.

The most idiomatic way of writing the code above in Elixir is by using pattern matching:

def get_token(string) do
  parts = String.split(string, "&")
  Enum.find_value(parts, fn pair ->
    [key, value] = String.split(pair, "=")
    key == "token" && value
  end)
end

With pattern matching, we are asserting that String.split/2 is going to return a list with two elements. If someone passes "foo=bar&token&bar=baz", it will crash as the list will have only one element. If someone passes "token=some=value", it will crash too as it contains 3 items.

Our new code does not contain any of the accidental complexity of the previous one and it will also be faster. Any input that does not match the given pattern will lead to a crash, giving us the perfect opportunity to discuss and decide how to handle those corner cases.

Polymorphism is opt-in

Elixir provides protocols as a mechanism for polymorphism. A protocol allows developers to express they are willing to work with any data type, as long as it implements the protocols X, Y and Z.

I have previously compared Elixir protocols to alternatives in languages like Swift and Ruby. One nice aspect of Elixir protocols is that they are explicit, you need to explicitly outline and define a protocol for data structures to implement.

For example, one protocol in Elixir is the String.Chars protocol, which converts any data type to a string, if that data type can be converted to a human-readable string. The to_string function uses such protocol for conversions:

iex> to_string("hello")
"hello"
iex> to_string(1)
"1"
iex> to_string URI.parse("http://blog.plataformatec.com.br")
"http://blog.plataformatec.com.br"
iex> to_string %{hello: :world}
** (Protocol.UndefinedError) protocol String.Chars not implemented for %{hello: :world}

Imagine you have a function that converts underscores to dashes in a string:

def dasherize(string), do: String.replace(string, "_", "-")

Now imagine that at some point you decide to call to_string/1 before calling replace/3:

def dasherize(data), do: String.replace(to_string(data), "_", "-")

Albeit small, this is a drastic change to our code. Our dasherize function went from supporting only strings as argument to support a large number of data types. In other words, our code became less assertive and more generic.

That said, before adding protocols to our code, we should ask if we really intend to open our function to all types. Maybe we want dasherize to support only atoms and strings? If so, we should rather write:

def dasherize(data) when is_atom(data), do: dasherize(Atom.to_string(data))
def dasherize(data), do: String.replace(data, "_", "-")

However, if we are confident we want a protocol, then we should indeed use the protocol and write a test case that guarantees our function works for at least a couple types that implement such protocol. Such tests are extremely important to guarantee we don’t make a different assumption somewhere in the same function.

Note this trade-off does not only happen in protocols, but in any polymorphic API, like the Dict module. In practice, one should rather use specific dict implementations, like the Keyword and Map modules, and rely on the Dict module only when polymorphism is desired.

Map/struct access

Elixir provides maps, known as dictionaries in other languages, as a key-value data structure. Maps are created as follows:

map = %{name: "john", age: 42}

Maps allow two types of access. A strict access, that requires the field name to exist in the map, and a dynamic access, that returns nil if the field does not exist in the map:

# Strict access
iex> map.name
"john"
iex> map.address
** (KeyError) key :address not found in: %{age: 42, name: "john"}

# Dynamic access
iex> map[:name]
"john"
iex> map[:address]
nil

Both syntaxes have their use cases but we should prefer the strict syntax when possible as it helps us find bugs early on. The same applies to structs, which are named maps:

defmodule User do
  defstruct [:first_name, :last_name, :age]

  def name(user) do
    "#{user.first_name} #{user.last_name}"
  end
end

User.name %User{first_name: "John", last_name: "Doe"}
#=> "John Doe"

In the example above, we have defined a User struct and a name/1 function that receives the struct and returns its name. Since we are using user.first_name, if we accidentally pass a struct that does not contain such a field, it will crash immediately, with a nice error message!

In fact, the strict aspect of the user.first_name syntax is one of the reasons why structs do not support the dynamic syntax out of the box:

user = %User{first_name: "John", last_name: "Doe"}
user[:first_name]
** (Protocol.UndefinedError) protocol Access not implemented for %User{...}

In case you want to use the dynamic syntax, you need to derive the Access protocol for the User struct:

defmodule User do
  @derive [Access]
  defstruct [:first_name, :last_name, :age]

  def name(user) do
    "#{user.first_name} #{user.last_name}"
  end
end

However, only derive Access when you truly need to do so, as it is much better to push yourself to rely more on the strict syntax. I would even say relying on Access for structured data is an anti-pattern itself!

Wrapping up

The most interesting aspect of all examples above is that writing in the assertive style leads to faster, more concise and maintainable code. Even more, it allows us to focus on specific scenarios, postponing any complexity (incidental or accidental) to only when we need them, if we need them.


]]>
http://blog.plataformatec.com.br/2014/09/writing-assertive-code-with-elixir/feed/ 0
Splitting long CSS files to overcome IE9 4095 rules limit http://blog.plataformatec.com.br/2014/09/splitting-long-css-files-to-overcome-ie9-4095-rules-limit/ http://blog.plataformatec.com.br/2014/09/splitting-long-css-files-to-overcome-ie9-4095-rules-limit/#comments Wed, 17 Sep 2014 12:00:37 +0000 http://blog.plataformatec.com.br/?p=4197 »]]> CSS preprocessors like SASS and LESS improved the way we write CSS nowadays. It provides better ways to organize styles into files, that can represent a component or page, and then compile into a single file, following the idea of reducing HTTP requests. Also there are other features like variables, mixins and placeholders that help with code reuse and maintenance.

However, it is possible that with the growth of your application code base the number of CSS styles will surpass the limit rules supported by IE9 or above. The current limit is up to 4095 rules per file.

But it is good to note that only the overflowed styles will be ignored. So, considering this detail, you might take some time to figure out that your layout is broken unless you are aware of this issue, since other browsers like Chrome, Safari and Firefox does not have such limit.

The simplest way to fix that is to split your main stylesheet into multiple files. Using a pre-processor makes the job easy, just create another manifest and move some imports to the newest one and problem solved.

Easy, huh? Well, if you have a well organized CSS the job might be straightforward, but if you don’t, you may struggle with some difficulties.

Here are some experiences that we got when addressing this issue.

Prefer to use placeholders instead of classes

We had some CSS styles that used @extend .some-class and it caused some problems as the .some-class definition is written to the CSS file, even if it is never used. One options is to convert classes into placeholders so they can be reused without being generated.

To make matters worse, .some-class was often defined in another file, which led to the file being imported, duplicating its rules over different files. This takes us to our next tip.

Organize variables and mixins into separated files

As your codebase grows, it is possible that variables, mixins or placeholders get spread in different files. So, if you have to split a CSS file, or even reorganize it, you will have to carefully ensure that all variables, mixins and placeholders are ported over. Keeping them in their proper files like _variables.scss and _mixins.scss cleans up the code and makes future refactoring much easier.

Use tools to break the compiled CSS file

There are projects that try to address the problem of long CSS files using a CSS parser to count the number of styles and generating multiple files when necessary. It is another solution to be aware of, but if you have a well organized CSS structure and guidelines to keep them clean, you can achieve the same result without adding another dependency or step in your asset pipeline.

Ways to detect the number of styles

From the command line

$ curl --silent  | grep -o '{' | wc -l

or if dealing with a compressed asset

$ curl --silent -H 'Accept-encoding: gzip'  | \
> gunzip - | grep -o '{' | wc -l

For example:

$ curl --silent http://plataformatec.com.br/stylesheets/all.css | \
> grep -o '{' | wc -l
339

Another easy way is just opening the CSS file in your browser and search for {.

Note that if you want to check the resulting CSS file in development you need to enable assets concatenation. One options is to set config.assets.debug to false in your development.rb file.

Summary

Preprocessors help a lot but it also requires discipline like any other code that you write. If you need inspiration to organize your files, you can take a look on Bourbon and even the well known Bootstrap project.

Do you know any other cases where a well structured CSS saved you?


]]>
http://blog.plataformatec.com.br/2014/09/splitting-long-css-files-to-overcome-ie9-4095-rules-limit/feed/ 0
Floating Point and currency http://blog.plataformatec.com.br/2014/09/floating-point-and-currency/ http://blog.plataformatec.com.br/2014/09/floating-point-and-currency/#comments Wed, 10 Sep 2014 12:00:05 +0000 http://blog.plataformatec.com.br/?p=4168 »]]>

“Do not use floating point for currency”

This simple statement is useful for both novice and experienced developers alike. It avoids problems that might otherwise compromise the correctness of the software you’re building.

But behind every piece of wisdom, every history of success, there is hard work from lots of people. Exploring this background is an enriching experience, the kind of thing that elevates the level of knowledge and makes you more confident about what you are doing.

Do not expect to find here a complete guide to floating point or currency handling. There are enough references on each matter separately out there already. The idea is to provide a brief exploration in a top-down fashion, gradually digging each layer of the stack, from the perspective of someone that do not master floating point.

Let’s start with a simple example in irb (Ruby’s Interactive Shell), which happens to be a common source of questions:

0.1 + 0.02 == 0.12

# => false

(0.1 + 0.02) + 0.3 == 0.1 + (0.02 + 0.3)
# => false

Wasn’t it supposed to return true? What’s going on behind the scenes?

Debugging the results from each side of the first expression.

0.1 + 0.02

# => 0.12000000000000001



0.12

# => 0.12

It looks like there is something wrong with the operation 0.1 + 0.02. Lets take a closer look, using a more accurate format.

sprintf("%0.50f", 0.12)

# => "0.11999999999999999555910790149937383830547332763672"



sprintf("%0.50f", 0.10 + 0.02)

# => "0.12000000000000000943689570931383059360086917877197"



sprintf("%0.50f", 0.02)

# => "0.02000000000000000041633363423443370265886187553406"



sprintf("%0.50f", 0.10)

# => "0.10000000000000000555111512312578270211815834045410"

So the error happens even before the arithmetic operations. It’s time to dive deeper into the stack.

Conversions

Once the interpreter parses the decimal string 0.1, for example, it converts that to an internal representation, which we’ll review briefly. This is achieved with the help of C strtod function, in MRI.

Curiously, this conversion step had already lead to security issues before.

Another conversion takes place when printing a float back to the decimal string. These transformations are not as trivial as one might think. There had been many studies in the development of the algorithms used in order to make it accurately and efficiently.

Since all of this happens transparently, some might expect that all languages work this way by default. It does, but not always for free. For example, in the infant days of the Elixir language, a developer had the following question after typing a decimal string into IEx (Elixir’s Interactive Shell). This had been solved by borrowing functionality already present in Erlang.

A counter intuitive fact is that even if a decimal number is not exactly representable as float, say 0.12, we are able to convert it back and forth without ever seeing the rounding error due to such carefully designed algorithms.

This automatic rounding behavior hides complexity but may encourage some to operate on floats expecting that the final conversion is going to provide a desired decimal result. But that is not always true due to rounding errors accumulation.

But what’s this internal representation and why does it impose such limitations?

Thinking in terms of binaries

We are not going to dive into the details of the IEEE754 nor explain how to do such conversions. That’s an interesting topic but it has been covered before and would end up being too extensive to fit in this post.

Instead we are going to show some examples that provides a glimpse of the real problem.

For instance, take the decimal number 0.625. This number represents the sum of fractions 6/10^1 + 2/10^2 + 5/10^3. The same reasoning can be used to find the binary representation replacing the denominator by powers of two 1/2^1 + 0/2^2 + 1/2^3 = 0.5 + 0.125 = 0.625, which leads to the binary 0.101 when we place the numerators in a row.

But if we had chosen another number, let’s say the decimal 0.1, we would find that it’s not possible to write it as a finite sum of fractions whose denominator is a power of 2. E.g. it does not have a finite binary representation.

Since the space to store a double precision float is limited to 64 bits, some sort of rounding would be required. And here we have one of the causes of precision loss.

What type should I use for representing currency?

The two most frequent answers include Integers or BigDecimals as the way to go. I’ve personally used both and it worked fine, but it would be too pretentious to say that one or another is the best for your problem.

Most Rails applications use databases. If that’s your case, it’s important to understand the limitations offered by the types available and the conversions done by the adapter during information storage and retrieval.

For example, Postgres recommends using its numeric type for currency, which Rails maps to BigDecimals. This type also supports the aggregation functions we are used to.

Other databases may require other approaches, like mongodb that does not have a type compatible with BigDecimal. But it doesn’t mean that it’s impossible to use BigDecimals with mongodb either.

Currency in cents, like $19.90 could be represented as the integer 1990. It avoids precision problems and works well with most databases too. One inconvenience is formatting numbers as currency, but there are gems to make this task easier and coding your own helper methods is also an alternative.

Some may experience performance issues when using BigDecimals, but I’ve never faced such issues personally. One thing to be aware of is that BigDecimals are not as simple as Integers and I like to keep things as simple as possible.

Even floating point may be required under some contexts if numerical methods get involved. The most important thing is to be aware of the limitations and make informed decisions.

So have you ever had problems with currency handling? I’m really willing to hear about how you solve this problem. If you have an experience to share, please, leave a comment below or find me on twitter @rcillo.

References


]]>
http://blog.plataformatec.com.br/2014/09/floating-point-and-currency/feed/ 4