Vitamin E - FinTech Special

To sign up to our newsletter at the bottom of this post!

Vitamin E FinTech Special - Blockchain myths and reality, exciting new projects and webinar announced…

Vitamin E
FinTech Special

Your monthly dose of all things Erlang & Elixir from Erlang Solutions

blockchain 2018 | Erlang Solutions

✨ It’s a FinTech Special ✨ 

Blockchain - Is it the future or will the bubble burst?

Behind the scenes, our teams have been blowing the lid off of the Blockchain scene! Last year’s involvement in a number of successful Blockchain and FinTech projects made us achieve the unachievable. 

Now that we are catching our breaths, we wanted to look through the myths vs reality of Blockchain to sift through the noise and give you a clear idea of what on earth is going on.

Blockchain 2018: Myths and Reality is an unmissable summary of the state of the art by Dominic Perini, our Scalability Architect and Tech Lead at Erlang Solutions.

Get involved in the discussion and be ready for more insights on how to disrupt FinTech and Blockchain with hyper-reliable, concurrent and scalable solutions.

Keep your eyes peeled and ears open for MORE FinTech and Blockchain reviews, webinars, and blogs.  

Read Blockchain 2018: Myths vs Reality →
 
BlockScout Webinar | Erlang Solutions

COMPANY FOCUS - POA Network

One of our substantial FinTech collabs has been with Ethereum-based platform POA Network. During the last year, we have been working closely to improve one of their systems, with great success! 

Elixir/Erlang Developer and Lead Architect of this project Felipe Ripoll explored the ins and outs of the NetStats System Dashboard in his latest blog post.

What’s more! We have a very special webinar approaching with POA Network’s Project Lead Andrew Cravenho entitled: 

‘BlockScout - Open Source EVM Blockchain Explorer’.

This is on Wednesday 14th November - sign up now! Even if you can’t make it, we’ll send this to all registrants personally, so it’s worth signing up!

Sign up to BlockScout Webinar →
Aeternity Focus | Erlang Solutions

COMPANY FOCUS - æternity

We teamed up with æternity to disrupt the Blockchain space! Together we are building a highly scalable system that caters for billions of users.

Kudos to the founder Yanislav Malahov and his æternity team and for their amazing work - long live scalability.

Have a look at Yani’s high praise on our new and improved FinTech and Blockchain page at Erlang Solutions!

We also partnered with æternity and WhatsApp to organise a free #OpenErlang party in London on Thursday 8th November. Make sure you sign up and celebrate 20 years of Erlang being open sourced. 

Explore FinTech Page  →
OpenErlang London Party | Erlang Solutions

#OpenErlang London Party 

Friends of the BEAM - please join us for an evening celebrating 20 years of open source Erlang!

Details
📆 Thursday 8th November 
📍ILEC Conference Centre, 47 Lillie Road, SW6 1UD
✅ Free event
🖊 RSVP

The choice to make Erlang available to everyone has created a powerful community, and its achievements have been exceptional. We’ve partnered with æternity and WhatsApp to say a BIG thank you and treat you to a good old-fashioned night out in London, entirely on us. This week we also published highlights from our Stockholm party to whet the appetite so don’t miss out! 

Along with our London shindig, we have a selection of #OpenErlang Interviews online. We’ve been asking key influencers in the Erlang, Elixir and open source community to share their experiences and milestones over the last 20 years.

The #OpenErlang Interviews have included Robert Virding and Joe ArmstrongChris PriceJane Walerud, Simon Phipps, and Anton Lavrik. More to come…

You’re invited! →

Want more Erlang and Elixir?
Alter your preferences

What’s happening in
the world of FinTech?

Hackernoon æternity article | Erlang Solutions

Advantages of Functional Programming for Blockchain Protocols 

This Hackernoon article asks “can functional programming support more efficient blockchain infrastructure, who is using it and why?”. The guys at æternity look through Erlang, Haskell, and OCaml, and the advantages of functional programming in the FinTech industry.

Read blog post →

Forbes | Erlang Solutions

Is Switzerland the secret hotspot for FinTech and Blockchain? 

Known for its diplomatic nature, Switzerland isn’t exactly the first to come to mind when you think “FinTech”, although it’s long been associated with entrepreneurial spirit and success business.  But this article in Forbes reveals the Swiss cities at the heart of the “global FinTech hub”. 

Read blog post →

Gaming and cryptocurrencies | Erlang Solutions

Video Games and Cryptocurrencies: A Perfect Marriage 

Like video games? Of course! But what’s the link between that and cryptocurrencies? 
This fantastic article is by Howard Marks who bought Activision and then rebuilt it into the “largest game company in the world”. Go through the evolution of gaming economics to present day…

Read blog post →

FinTech Newsletter Sign Up | Erlang Solutions

Sign up for FinTech and crypto specific news!

If you’re enjoying all this juicy FinTech information, you can sign up for specific email updates. These will be sent out quarterly - not monthly - and will consolidate all FinTech and crypto articles of importance. All you need to do is alter your email preferences to include “FinTech and Technology news”. 

Alter Preferences →

 

What’s happening in
the world of Erlang & Elixir

16 lessons webinar | Erlang Solutions

16 lessons I learnt from the BEAM - Webinar now online!

For our October webinar, we were joined by Joseph Yiasemides as part of the #OpenErlang celebrations. Some of these lessons are drawn from other functional programming communities, and beyond. They are broadly applicable, extending not only to other functional languages, but also to the more mainstream languages.

Watch webinar →

Extensible Elixir | Erlang Solutions

London Meetup - Extensible Elixir with Adam Lancaster

Elixir provides us with a really powerful way to achieve ad hoc polymorphism. In this talk, we will look at how this extensibility compares to what we might have in an OOP language, and what we can do with it. Adam is a software developer at Nested.

This talk will be at our London HQ on Wednesday 28th November.

Come along →

Code Mesh LDN | Erlang Solutions

Code Mesh LDN - only one week to go!

We’re excited to be back at Code Mesh LDN this year as gold sponsors. The London-based two-day conference never fails to inspire attendees when it comes to using the right tool for the job. Last minute tickets are still available for the conference and tutorials! Learn more about the conference, the speakers, and the tutorials on offer!

Learn more →

Code BEAM Lites | Erlang Solutions

Code BEAM Lites - Amsterdam and Munich

If you’re looking for even more ways to connect with the Erlang and Elixir community and get involved then why not attend one of these two fantastic one-day conferences happening in November (Amsterdam) and December (Munich). Tickets are on sale at only €109, and they are selling fast! Head over to the website to get yours before they are gone!

More about Code Beam Lites →

Lambda Days | Erlang Solutions

Lambda Days Krakow February 2019

With the first two keynote speakers announced (Don Syme and Manuel Chakravarty), Lambda Days invites all functional programmers to join the excitement! Their next committee call is just around the corner, and they are hungry for more inspiring proposals

You can get your Early Bird ticket now!

Find out more →

Code BEAM SF | Erlang Solutions

It’s Bitcoin’s 10th birthday - Here’s what people are saying 

Ten years ago, Satoshi Nakamoto created bitcoin offering more offering over your money following the 2008 global financial crisis.
Vlad Dramaliev, the head of marketing of æternity, has since called the currency the “most exciting technological experiments of our time”.  find out more about the history of bitcoin in this Forbes article. 

Find out more →

senior Devs vs Junior Devs | Erlang Solutions

The Classic Rivalry - Senior Devs vs Junior Devs

Why senior devs write “dumb code” and how to spot a Junior a mile away - an interesting and quick read!
Scott Shipp leaves us with a quote from Dave Carhart, and in the spirit of Halloween; “Always code as if the guy who ends up maintaining, or testing your code will be a violent psychopath who knows where you live”.

Read blog post →

Code Review Checklist | Erlang Solutions

A Clear, Concise & Comfy Code Review Checklist

Sometimes you just need a simple checklist amidst the formulas. When the Erlang Solutions teams met at our annual Get2Gether in Budapest earlier this year, we had a number of talks, and checklists were of high interest! Not only code checklists, but formalities outside of developing/programming such as approaching your manager. 

Read blog post  →

 
      

Erlang Solutions Ltd
London | Stockholm | Kraków | Budapest | New York
The Loom, 14 Gower’s Walk, London, E1 8PY
Unsubscribe • Edit email preferences • Privacy policy

Permalink

Retiring old performance pitfalls

Erlang/OTP 22 will bring many performance improvements to the table, but most of them have a broad impact and don’t affect the way you write efficient code. In this post I’d like to highlight a few things that used to be surprisingly slow but no longer need to be avoided.

Named fun recursion

Named funs have a neat little feature that might not be obvious at a first glance; their name is a variable like any other and you’re free to pass it to another function or even return it.

deepfoldl(F, Acc0, L) ->
    (fun NamedFun([_|_]=Elem, Acc) -> lists:foldl(NamedFun, Acc, Elem);
         NamedFun([], Acc) -> Acc;
         NamedFun(Elem, Acc) -> F(Elem, Acc)
     end)(L, Acc0).

This is cool but a bit of a headache for the compiler. To create a fun we pass its definition and free variables to a make_fun2 instruction, but we can’t include the fun itself as a free variable because it hasn’t been created yet. Prior to OTP 22 we solved this by creating a new equivalent fun inside the fun, but this made recursion surprisingly expensive both in terms of run-time and memory use.

As of OTP 22 we translate recursion to a direct function call instead which avoids creating a new fun. Other cases still require recreating the fun, but they’re far less common.

Optimize named funs and fun-wrapped macros #1973

List subtraction with large operands (– operator)

While the Erlang VM appears to be pre-emptively scheduled to the programmer, it’s co-operatively scheduled internally. When a native function runs it monopolizes the scheduler until it returns, so a long-running one can severely harm the responsiveness of the system. We’ve therefore written nearly all such functions in a style that breaks the work into short units that complete quickly enough, but there’s a steadily shrinking list of functions that misbehave, and list subtraction was one of these.

It’s usually pretty straightforward to rewrite functions in this style, but the old algorithm processed the second list in a loop around the first list, which is problematic since both lists can be very long and resuming work in nested loops is often trickier than expected.

In this case it was easier to just get rid of the nested loop altogether. The new algorithm starts out by building a red-black tree from the right-hand side before removing elements from the left-hand side. As all operations on the tree have log n complexity we know that they will finish really quickly, so all we need to care about is yielding in the outer loops.

This also had the nice side-effect of reducing the worst-case complexity from O(n²) to O(n log n) and let us remove some warnings from the reference manual and efficiency guide. It’s worth noting that the new implementation is always faster than the proposed workarounds, and that it falls back to the old algorithm when it’s faster to do so.

This change will be rolled out in OTP 21.2, big thanks to Dmytro Lytovchenko (@kvakvs on GitHub) for writing the better half of it!

Optimize list subtraction (A – B) and make it yield on large inputs #1998

Lookahead in bit-syntax matching

The optimization pass for bit-syntax matching was completely rewritten in OTP 22 to take advantage of the new SSA-based intermediate format. It applies the same optimizations as before so already well-optimized code is unlikely to see any benefit, but it manages to apply them in far more cases.

For those who aren’t familiar, all bit-syntax matching operates on a “match context” internally, which is a mutable object that keeps track of the current match position. This helps a lot when matching complicated patterns as it can zip back and forth as required, saving us from having to match components more than once.

This is great when matching several different patterns, but it comes in real handy in loops like the following:

trim_zero(<<0,Tail/binary>>) -> trim_zero(Tail);
trim_zero(B) when is_binary(B) -> B.

As the compiler can see that Tail is passed directly to trim_zero, which promptly begins with a bit-match, it can skip extracting Tail as a sub-binary and pass the match context instead. This is a pretty well-known optimization called “match context reuse” which greatly improves performance when applied, and a lot of code has been written with it in mind.

The catch of passing a match context like this is that we have to maintain the illusion that we’re dealing with an immutable binary. Whenever it’s used in a non-matching expression we either need to convert the context to an equivalent binary, or admit defeat and skip the optimization.

While the compiler did a pretty good job prior to OTP 22 it gave up a bit too easily in many cases, and the most trivial example is almost funny:

calls_wrapper(<<"hello",Tail/binary>>) ->
    count_ones(Tail).

%% This simple wrapper prevents context reuse in the call above. :(
count_ones(Bin) -> count_ones_1(Bin, 0).

count_ones_1(<<1, Tail/binary>>, Acc) -> count_ones_1(Tail, Acc + 1);
count_ones_1(<<_, Tail/binary>>, Acc) -> count_ones_1(Tail, Acc);
count_ones_1(<<>>, Acc) -> Acc.

A trickier example can be found in the string module:

bin_search_inv_1(<<CP1/utf8, BinRest/binary>>=Bin0, Cont, Sep) ->
    case BinRest of
        %% 1
        <<CP2/utf8, _/binary>> when ?ASCII_LIST(CP1, CP2) ->
            case CP1 of
                Sep ->
                    %% 2
                    bin_search_inv_1(BinRest, Cont, Sep);
                _ ->
                    %% 3
                    [Bin0|Cont]
            end;
        %% ... snip ...

What we’re looking at is a fast-path for ASCII characters; when both CP1 and CP2 are ASCII we know that CP1 is not a part of a grapheme cluster and we can thus avoid a call to unicode_util:gc/1. It’s not a particularly expensive function but calling it once per character adds up quickly.

At first glance it might seem safe to pass the context at 2, but this is made difficult by Bin0 being returned at 3. As contexts are mutable and change their position whenever a match succeeds, naively converting Bin0 back to a binary would give you what comes after CP2 instead.

Now, you might be wondering why we couldn’t simply restore the position before converting Bin0 back to a binary. It’s an obvious thing to do but before OTP 22 the context tracked not only the current position but also previous ones needed when backtracking. These were saved in per-context “slots” which were mutable and heavily reused, and the match at 1 clobbered the slot needed to restore Bin0.

This also meant that a context couldn’t be used again after being passed to another function or entering a try/catch, which made it more or less impossible to apply this optimization in code that requires looking ahead.

As of OTP 22 these positions are stored outside the context so there’s no need to worry about them becoming invalid, making it possible to optimize the above cases.

Rewrite BSM optimizations in the new SSA-based intermediate format #1958

Permalink

20 years of open source Erlang: OpenErlang Interview with Miriam Pena

We’ve been holding a year-long celebration in the honour of Erlang’s 20th anniversary as an open source language. This week, we’re excited to introduce Miriam Pena as our next #OpenErlang enthusiast.

Previously, we looked into WhatsApp with one of their talented Server Engineer’s Anton Lavrik. WhatsApp has used Erlang since its humble beginnings back in 2009, but what other giants use the language? Miriam Pena is one equally talented Staff Engineer at AdRoll, a company that uses both Erlang and Elixir!

Adroll uses both languages “to respond to each bid request in less than 80 milliseconds” and Miriam wouldn’t have it any other way. Here, she discusses when she saw the real potential of Erlang and how its concurrency methods are used to full advantage at AdRoll.

We have the transcript listed at the bottom of this blog post.

About Miriam

Miriam has been an engineer at AdRoll for nearly 5 years. During that time, she has worked with Erlang, Elixir, AWS, Python, Dynamodb, Kinesys and Memcached. Currently, AdRoll’s real time bidding system handles a peak volume of 1.5 Million req every SECOND. Previously, Miriam has worked as an Erlang specialist software engineer, including with us at Erlang Solutions back in 2008-2011!

With over a decade of experience working with scalable systems, at AdRoll, Miriam designs critical parts of their Real-Time Bidding and Ad Server infrastructure, organizes the Erlang and Elixir meetup in San Francisco and has previously been voted one of the “women to watch” by Women 2.0.

Miriam loves working with distributed, scalable, high performance, high concurrency, and high availability systems. Bonus points if they are written in Erlang and Elixir! She has also open sourced a lightweight Memcached Erlang library called Mero that is used at a massive scale in their RTB infrastructure.

About AdRoll

AdRoll was founded in 2007 with the purpose of advertising online without the need for massive budgets only rewarded to major corporate companies, and the needless complexity that came with this.

It works by retargeting - those ads that follow you around the internet encouraging you to buy whatever it was that your willpower denied you the first time around!

Retargeting is an extremely successful advertising tool, and AdRoll has allowed businesses of nearly any size to benefit from it. The benefit for us? Much more variety! It keeps a particular brand at the front of the consumer’s mind, so when they decide to commit to a purchase, they commit to your business.

To retarget most effectively, you must segment your users so the ad they’re receiving is 100% relevant. You must also consider the type of product. For example, if a user wants to buy flights or hotels, it’s best practice to target near immediately, whilst bigger/luxury purchases require further thought and therefore you shouldn’t bombard the consumer.

Why AdRoll uses Erlang

AdRoll has said that they have generated over $7 billion in revenue for their customers, and as previously mentioned, AdRoll must deal with approximately 1.5 million actions per second and answer them in less than 80 milliseconds.

This huge amount of requests requires a highly reliable system such as Erlang to process actions very quickly and even more efficiently. Erlang is an extremely concurrent system that can handle this real-time bidding with a very minimal possibility of the systems crashing. AdRoll’s two main issues are:

Real-time bidding - there will be multiple businesses battling it out for the same ad space. Real-time bidding, like an online auction for the best spots. AdRoll participates in over 1 million programmatic auctions per second. Erlang also allows buyers to respond just as quickly. Ad targeting - AdRoll has a thorough system in place to funnel users to the correct advertisement on the correct website.

The main benefits of Erlang for AdRoll:

• Erlang/OTP offers AdRoll scalability - robust building blocks can be easily replicated. • Erlang/OTP offers robust system designs that means if something crashes, the system will continue. • Erlang’s syntax and design means there is less coding and therefore a reduced chance of bugs.

AdRoll also has an Erlang MultiLangDaemon interface launched by their Erlang node that means each stream is processed as a shard processing program. Each shard is an independent Erlang process. This has the benefits of Java without writing any Java code.

AdRoll also uses ‘profile data systems’ written in DynamoDB (Amazon’s proprietary NoSQL database service).

You can read more about AdRoll, Erlang and Elixir on AdRoll’s blog. You can visit their careers page too.

Interview Transcript

At work with the boss breathing down your neck? Or don’t want to be one of those playing videos out loud on public transport? Here’s the transcript, although not as exciting as the real thing.

Miriam Pena: I first got in touch with Erlang when writing my thesis in La Coruña University.

The first time I saw its potential in a real professional environment was this time we had to implement a software to monitor a solar-powered station. We have 15 different types of devices, each with its own protocol which was really easy to implement with binary comprehension and pattern matching. Also, the concurrency model of Erlang allows scaling the system to a thousand devices.

At the moment, I work as a Staff Engineer in AdRoll in San Francisco. AdRoll is a marketing company. We use Erlang and Elixir in most of our most complex systems.

We participate in over one million actions per second. We have to respond to each of these requests in less than 50 milliseconds. The amount of volume of data we have to process is really high and Erlang is really great for these. It’s very lightweight. The concurrency model allows us to scale thousands of requests at the same time per machine. When there’s a problem in one of the requests, the whole system doesn’t fall.

Well, these 20 years of Erlang has had many amazing contributions. One of the most important ones is the recent addition of maps in Erlang and doing the pattern matching. The system is so compact, it’s just so great. That one thing that really changed my life was when they were able to add line numbers to the error reports. It really only took them 2 hours to get that done.

[00:01:42] [END OF AUDIO]

OpenErlang; 20 Years of Open Sourced Erlang

Erlang was originally built for Ericsson and Ericsson only, as a proprietary language, to improve telephony applications. It can also be referred to as “Erlang/OTP” and was designed to be a fault-tolerant, distributed, real-time system that offered pattern matching and functional programming in one handy package.

Robert Virding, Joe Armstrong and Mike Williams were using this programming language at Ericsson for approximately 12 years before it went open source to the public in 1998. Since then, it has been responsible for a huge number of businesses big and small, offering massively reliable systems and ease of use.

OpenErlang Interview Series

As mentioned, this isn’t the first in the #OpenErlang Interview series. We have three more existing videos to enjoy.

Robert Virding and Joe Armstrong

It only seems fitting to have launched with the creators of Erlang; Robert Virding and Joe Armstrong (minus Mike Williams). Robert and Joe talk about their journey with Erlang including the early days at Ericsson and how the Erlang community has developed.

Christopher Price

Last week was the launch of our second #OpenErlang Interview from Ericsson’s Chris Price. Currently the President of Ericsson’s Software Technology, Chris has been championing open source technologies for a number of years.

Chris chats to us about how Erlang has evolved, 5G standardization technology, and his predictions for the future.

Jane Walerud

Jane is a serial entrepreneur of the tech persuasion. She was instrumental in promoting and open sourcing Erlang back in the 90s. Since then, she has continued her entrepreneurial activities, helping launch countless startups within the technology sector from 1999 to present day. Her work has spanned across many influential companies who use the language including Klarna, Tobil Technology, Teclo Networks and Bluetail, which she founded herself.

Other roles have included Member of the Board at Racefox, Creades AB and Royal Swedish Academy of Engineering Sciences, and a key role in the Swedish Government Innovation Council.

Simon Phipps

Having become an open source programming language, Erlang was allowed to flourish. It gained a passionate following which has since developed into a close community. Simon Phipps dedicates his time to open source promoting languages such as Erlang through the Open Source Initiative and other similar schemes.

Why are open source languages such as Erlang so important? Find out more!

Anton Lavrik

Anton is a Server Engineer at one of the biggest mobile applications in the world. Yep, we’re talking about WhatsApp, which runs on Erlang! WhatsApp is capable of sending billions of messages every single day, and Erlang’s stability and concurrency is a significant reason why it’s perfect for the amount of traffic WhatsApp received. Discover WhatsApp’s Erlang journey with Anton.

The #OpenErlang Parties

Catch up with our Stockholm party held in May 2018!

Other Erlang Solutions Activities…

BlockScout - Open Source EVM Blockchain Explorer Our November webinar is with POA Network’s Andrew Cravenho who is the project Lead in our exciting new collaboration; BlockScout - Open Source EVM Blockchain Explorer. Sign up for the webinar and received the recording straight in your inbox.

OpenErlang London Party Have you signed up to the OpenErlang London party yet? Held on 8th November, we have partnered with æternity and WhatsApp to celebrate this momentous milestone. Tickets are free but you still need to register at Eventbrite. We can’t wait to celebrate with you - great company, great food, and great entertainment! You’d be mad to miss it.

If you’re interested in contributing and collaborating with us at Erlang Solutions, you can contact us at general@erlang-solutions.com.

Permalink

20 years of open source Erlang: The OpenErlang Parties

It’s party time! To celebrate the 20th anniversary of open sourced Erlang, we have already held two great parties in San Francisco and Stockholm - now it’s London’s turn!

This year we’ve been also holding meetups, webinars, producing blogs and interviews to mark the occasion, but like any celebration, a party should be on the cards!

The London Erlang Party is coming and we invite you all to join the Erlang, Elixir and Open Source community on the evening of 8th November. Put your name on the list and we will send you a free ticket!

The choice to make Erlang available to everyone has created a powerful community, and its achievements have been exceptional. We’ve partnered with WhatsApp and æternity to say a MASSIVE thank you and treat you to a good old-fashioned night out in London, on us!

This is a free event full of drinks, food and a few surprises, and we can’t wait for you to join us in celebrating open source languages and in particular ERLANG! Please RSVP on our Eventbrite page to register your attendance.

When: Thursday 08 November 2018 - 18:30 - late Where: ILEC Conference Centre, 47 Lillie Road, London. SW6 1UD

OpenErlang Interviews

Along with our London shindig, we have a selection of #OpenErlang Interviews online. We’ve been asking key influencers in the Erlang community to chat to us about their experiences and Erlang milestones over the last 20 years.

If you’ve signed up, check out a sneak peek of what’s to come! And if you haven’t - what are you waiting for? It’s free after all…

We have the transcript listed at the bottom of this blog post.

About #OpenErlang

You can find out more about our activities - past, present and future - at our #OpenErlang page. Catch up with past webinars, sign up for current ones, and watch our complete #OpenErlang Interview series.

About Erlang

Erlang was created in the Ericsson labs in the mid-80s by Robert Virding, Joe Armstrong and Mike Williams where Ericsson continued to use it until it was made open source in 1998. Jane Walerud was a key figure in helping the language become open source as well.

The name “Erlang” came from an abbreviation of “Ericsson Language” along with reference to the Danish mathematician and engineer Agner Krarup Erlang who invented fields of traffic engineering and queueing theory.

The language was designed with the aim of improving the development of telephony applications, and a garbage-collected runtime system. The key positive of Erlang is the “write once, run forever” motto coined by Joe Armstrong in an interview with Rackspace in 2013.

The successes of the language can often be down to “robustness” - the ability to run multiple processes whilst still maintaining the amazing speed and efficiency. Error handling is non-local so if one process breaks or encounters a bug, it continues running! And then of course Erlang is famous to be scalable, distributed, highly concurrent, highly available and fault-tolerant functional programming language.

Erlang can be used interchangeably with Erlang/OTP.

Interview Transcript

At work with the boss breathing down your neck? Or don’t want to be one of those playing videos out loud on public transport? Here’s the transcript, although not as exciting as the real thing.

[background instrumental music]

Stuart Whitfield: This year is the 20th anniversary of the open sourcing of Erlang. The BEAM Community wouldn’t exist if that fateful decision hadn’t been taken two decades ago.

Anna Neyzberg: Open Source really did change the way they built software and seeing that people are still committed to continuing that and passing that on is really critical so we can continue doing what we do.

Francesco Cesarini: It’s really, really exciting to see how they are all getting along, sharing ideas and learning from each other.

Osa Gaius: Different countries of all races, backgrounds. We hope that in the next 20 years, the diversity of people in the community will still be large.

Stuart: Erlang success as a technology would not have happened without your contribution. Let’s congratulate ourselves on what has been achieved in the first 20 years of open sourcing Erlang.

[applause]

[00:00:58] [END OF AUDIO]

OpenErlang; 20 Years of Open Sourced Erlang

Erlang was originally built for Ericsson and Ericsson only, as a proprietary language, to improve telephony applications. It can also be referred to as “Erlang/OTP” and was designed to be a fault-tolerant, distributed, real-time system that offered pattern matching and functional programming in one handy package.

Robert Virding, Joe Armstrong and Mike Williams were using this programming language at Ericsson for approximately 12 years before it went open source to the public in 1998. Since then, it has been responsible for a huge number of businesses big and small, offering massively reliable systems and ease of use.

OpenErlang Interview Series

As mentioned, this isn’t the first in the #OpenErlang Interview series. We have three more existing videos to enjoy.

Robert Virding and Joe Armstrong

It only seems fitting to have launched with the creators of Erlang; Robert Virding and Joe Armstrong (minus Mike Williams). Robert and Joe talk about their journey with Erlang including the early days at Ericsson and how the Erlang community has developed.

Christopher Price

Last week was the launch of our second #OpenErlang Interview from Ericsson’s Chris Price. Currently the President of Ericsson’s Software Technology, Chris has been championing open source technologies for a number of years.

Chris chats to us about how Erlang has evolved, 5G standardization technology, and his predictions for the future.

Jane Walerud

Jane is a serial entrepreneur of the tech persuasion. She was instrumental in promoting and open sourcing Erlang back in the 90s. Since then, she has continued her entrepreneurial activities, helping launch countless startups within the technology sector from 1999 to present day. Her work has spanned across many influential companies who use the language including Klarna, Tobil Technology, Teclo Networks and Bluetail, which she founded herself.

Other roles have included Member of the Board at Racefox, Creades AB and Royal Swedish Academy of Engineering Sciences, and a key role in the Swedish Government Innovation Council.

Simon Phipps

Having become an open source programming language, Erlang was allowed to flourish. It gained a passionate following which has since developed into a close community. Simon Phipps dedicates his time to open source promoting languages such as Erlang through the Open Source Initiative and other similar schemes.

Why are open source languages such as Erlang so important? Find out more!

Anton Lavrik

Anton is a Server Engineer at one of the biggest mobile applications in the world. Yep, we’re talking about WhatsApp, which runs on Erlang! WhatsApp is capable of sending billions of messages every single day, and Erlang’s stability and concurrency is a significant reason why it’s perfect for the amount of traffic WhatsApp received. Discover WhatsApp’s Erlang journey with Anton.

Other Erlang Solutions Activities…

BlockScout - Open Source EVM Blockchain

Our latest webinar is open to registrants! On Wednesday 14th November, we will be speaking to Andrew Cravenho from POA Network about our recent project together, creating the Open Source EVM Blockchain Explorer!

Blockchain 2018; Myths vs Reality

Continuing our blockchain theme is our Scalability Architect and Developer Dominic Perini who has written a highly informative and entertaining article regarding the state of blockchain this year. Find out his thoughts and join the conversation online! Read Blockchain 2018 here.

NetStats System Dashboard for Ethereum-based platform

Our second blog treat during our focus on blockchain is from another fantastic scalability Architect and Erlang/Elixir Developer Felipe Ripoll. His article on the NetStats System Dashboard offers a concise overview of our project with POA Network.

If you’re interested in contributing and collaborating with us at Erlang Solutions, you can contact us at general@erlang-solutions.com.

Permalink

How many functions do you have?

A while back this question popped up in one of the many places where the Erlang community gathers, I think it was IRC:

How many functions do you have in your Erlang node?

As an answer, Craig posted this beauty:

1> length([{M,F,A} || {M,_} <- code:all_loaded(), {exports,Fs} <- M:module_info(), {F,A} <- Fs]).
2531
2> length([{M,F,A} || {M,_} <- code:all_loaded(), {exports,Fs} <- M:module_info(), {F,A} <- Fs]).
2539
3> {ok,2}.
{ok,2}
4> length([{M,F,A} || {M,_} <- code:all_loaded(), {exports,Fs} <- M:module_info(), {F,A} <- Fs]).
2628
Original from KissPNG

What’s going on here?

As usual, it’s better if you try understanding this by yourself. If you are up for the challenge, just boot up an Erlang VM and try to figure out what’s happening.

I’ll jump straight to the answer instead: Erlang has Dynamic Code Loading. As the docs point out…

The code server loads code according to a code loading strategy, which is either interactive (default) or embedded. In interactive mode, code is searched for in a code path and loaded when first referenced. In embedded mode, code is loaded at start-up according to a boot script. This is described in System Principles.

Alright, mystery solved: The new functions that appear once we evaluate the list comprehension a second time are loaded right there because they’re needed to evaluate the first list comprehension and print its result.

Let’s see if our observations match with that hypothesis. And just for fun, let’s do it in Elixir. First, let’s see if the same behavior is experienced in iex, too:

iex(1)> length(for {m, _} <- :code.all_loaded, {:exports, fs} <- m.module_info(), {f, a} <- fs, do: {m, f, a})
4239
iex(2)> length(for {m, _} <- :code.all_loaded, {:exports, fs} <- m.module_info(), {f, a} <- fs, do: {m, f, a})
4319
iex(3)>

Excellent! Now let’s see what functions are those new ones. Actually, since modules are loaded all at once (i.e. code server doesn’t load individual functions, it loads the entire module when it needs it), let’s see which modules are the new ones. To do that, we need to start a new VM, of course, and then…

iex(1)> ms = :code.all_loaded; length(ms)
172
iex(2)> new_ms = (:code.all_loaded -- ms)
[
{Inspect.Integer, 'path/to/Elixir.Inspect.Integer.beam'},
{Inspect.Algebra, 'path/to/Elixir.Inspect.Algebra.beam'},
{Inspect.Opts, 'path/to/Elixir.Inspect.Opts.beam'},
{Inspect, 'path/to/Elixir.Inspect.beam'}
]
iex(3)>

And there you have it, the new modules are no others than the ones required to print out 172 on the screen.

Spawnfest 2018 is Around the Corner

We are less than a month away from Spawnfest 2018, the annual international online FREE 48-hour-long hackathon for the BEAM community!

For this year we have an amazing panel of judges (Miriam Pena, Kenji Rikitake, Juan Facorro, René Föhring, Tristan Sloughter and Andrea Leopardi), some great sponsors (Erlang Solutions, AdRoll, Peer Stritzinger, ScrapingHub, 10Pines, Fiqus and LambdaClass) and, more importantly… some AMAZING PRICES!! You can win tickets to conferences, gift cards from Amazon, books, GRiSP boards, GoPros, headsets, ElixirCasts.io, t-shirts…

Build your team, register at our website and join us on November 24th and 25th! It will be great!

If you don’t have a team, you can register your self in our super find-a-team machine™️ and we will help you find one.

And if you don’t have an idea, check our list of suggestions.


How many functions do you have? was originally published in Erlang Battleground on Medium, where people are continuing the conversation by highlighting and responding to this story.

Permalink

Is Elixir a scripting language?

Elixir is known for being a language made for building distributed applications that scale, are massively concurrent, and have self-healing properties. All of these adjectives paint Elixir in a grandiose light. And for good reasons!

But is Elixir also a language that can be used for the more mundane tasks of this world like scripting? I think the answer is a definite yes.

To see this, let’s take a look at all the ways we can write scripts using Elixir. We’ll build using the same example, going from simple to more complex solutions.

Defining the script

Our script will simply create a new markdown file with today’s date so we can write our To Do list. The structure of the directories will be YYYY/MM/DD.md, so we will nest each day under a month and each month under a year.

# Get today's date
date = Date.utc_today()
year = Integer.to_string(date.year)
month = Integer.to_string(date.month)
day = Integer.to_string(date.day)

# Generate the month's full path with YYYY/MM format
month_path =
  File.cwd!()
  |> Path.join(year)
  |> Path.join(month)

# Create the month and year directories
File.mkdir_p(month_path)

# Generate the filename with today's date
filename = Path.join(month_path, day) <> ".md"

# Check existence so we don't override a file
unless File.exists?(filename) do
  # include sample header
  header = """
  ---
  date: #{Date.to_string(date)}
  ---

  To Do
  =====

  - What do you need to accomplish today?
  """

  # write to the file
  File.open(filename, [:write], fn file ->
    IO.write(file, header)
  end)
end

# Print out confirmation message
final_message = """

> Created #{Path.relative_to_cwd(filename)}
"""

IO.puts(final_message)

Excellent! That is the full extent of our script. Let’s now see how we can run it.

elixir todo.exs

The first and perhaps simplest way to run an elixir script is just to run elixir name_of_file.exs from the shell. So let’s do that.

  1. Save the above code in a file named todo.exs
  2. Run elixir todo.exs
  3. You should see the following message (with the date you’re running this script instead of the date I ran it):
$ elixir todo.exs

> Created 2018/9/28.md

If we inspect the file that it created, we can confirm that the template is there,

---
date: 2018-09-28
---

To Do
=====

- What do you need to accomplish today?

bin/todo

A second way to run the script is to make it into an executable. This is perhaps an extension of the one above, but I include it as a separate step because I think it could prove useful in some projects.

Follow these steps:

  1. Move todo.exs under a bin/ directory (not required but nice)
  2. Mark it as executable with chmod: chmod +x bin/todo.exs
  3. Add a shebang #! /usr/bin/env elixir at the top of your file
  4. Rename it to bin/todo

And run bin/todo!

If you’re unfamiliar with using chmod and shebang to turn a file into an executable, take a look at the notes in this let’s build a CLI video.

When would I use these?

Our todo.exs and bin/todo scripts are examples of standalone scripts. They are useful when you want to run a task that is self-contained. bin/todo has the benefit that the user of the script need not know that the script is running Elixir (though it still needs to have Elixir installed). It’s just a script like any other one you may find in your bin/ folder.

mix run todo.exs

Now if you’re working with Elixir, it is very likely you are already working in a mix project. If that is the case, mix allows you to run arbitrary scripts via mix run [name of file].

To test this, let’s go ahead and create a new project called tasker and run our script there.

Follow these steps:

  1. mix new tasker,
  2. cd into the tasker directory,
  3. make a scripts/ directory,
  4. copy the todo.exs file from the first section into scripts/todo.exs

Now run mix run scripts/todo.exs!

When would I use this?

The benefit of running this script via mix (as opposed to the previous two options) is that the script is part of your project, so it has access to all the code you have defined in the project.

Let’s bring that point home by extracting most of the logic to a TodoBuilder module:

# lib/todo_builder.ex
defmodule TodoBuilder do
  def run(date) do
    year = Integer.to_string(date.year)
    month = Integer.to_string(date.month)
    day = Integer.to_string(date.day)

    month_path =
      File.cwd!()
      |> Path.join(year)
      |> Path.join(month)

    File.mkdir_p(month_path)

    filename = Path.join(month_path, day) <> ".md"

    unless File.exists?(filename) do
      header = """
      ---
      date: #{Date.to_string(date)}
      ---

      To Do
      =====

      - What do you need to accomplish today?
      """

      File.open(filename, [:write], fn file ->
        IO.write(file, header)
      end)
    end

    {:ok, filename}
  end
end
# scripts/todo.exs

{:ok, filename} =
  Date.utc_today()
  |> TodoBuilder.run()

final_message = """

> Created #{Path.relative_to_cwd(filename)}
"""

IO.puts(final_message)

In the wild

If you’re interested in seeing this “in the wild”, Phoenix seeds data in their applications by running mix run priv/repo/seeds.exs.

mix tasker.todo

Having it as a script that can run with our project code is nice. But sometimes we want to make it a more explicit part of our project. Turning our script into a mix task can do just that. This is especially true if we expect external parties to use our project since mix tasks have the extra benefit of documentation!

Let’s change our script into a mix task. In the tasker project,

  1. Create a lib/mix/tasks/ directory
  2. Create a todo.ex task
  3. Move the code we have in scripts/todo.exs into that file
  4. Add use Mix.Task at the top of the module
  5. Add a @shortdoc and @moduledoc with descriptions of what the task does
# lib/mix/tasks/todo.ex
defmodule Mix.Tasks.Todo do
  use Mix.Task

  @shortdoc "Creates a new todo file with today's date"

  @moduledoc """
  Creates a new todo file with today's date

  ## Example

  mix todo
  """

  def run(_args) do
    {:ok, filename} =
      Date.utc_today()
      |> TodoBuilder.run()

    final_message = """

    > Created #{Path.relative_to_cwd(filename)}
    """

    Mix.shell().info(final_message)
  end
end

Now run mix todo and voila!

But that’s not all. Note the use of @shortdoc and @moduledoc. The documentation that we added in those two module attributes makes our script especially friendly to other users.

If you check mix help, you’ll see that our task is listed right after mix test, and it uses @shortdoc for its documentation.

image-of-mix-help

Now check out mix help todo. It uses your @moduledoc for documentation!

image-of-mix-help-todo

In the wild

If you’re interested on how this gets used in the wild, take a look at how Phoenix and Ecto use mix tasks for commonly performed actions and for their generators. Things such as mix phx.new, mix phx.server, and mix ecto.migrate are all mix tasks!

./tasker escript

Wow, it’s been a long road but we’re finally down to the last way we can script in Elixir (that I know of).

One of the built-in mix tasks that comes with mix is mix escript.build. It packages your project and dependencies into a binary that is executable. It even embeds Elixir as part of the script, so it can be used so long as a machine has Erlang/OTP without requiring Elixir to be present.

Let’s get to it. We have to first update our mix.exs file to define an entry point for the escript.build task,

# mix.exs
def project do
  [
    app: :tasker,
    # other options
    #
    # add this line below
    escript: escript()
  ]
end

# add the entry point
defp escript do
  [main_module: Tasker.TodoCLI]
end

Now let’s create Tasker.TodoCLI and put our code there,

# lib/tasker/todo_cli.ex
defmodule Tasker.TodoCLI do
  def main(_args) do
    {:ok, filename} =
      Date.utc_today()
      |> TodoBuilder.run()

    final_message = """

    > Created #{Path.relative_to_cwd(filename)}
    """

    IO.puts(final_message)
  end
end

Now we can simply run mix escript.build to build the executable. And you should see that you have a new executable called tasker in the main directory. Run it with ./tasker and see the magic happen!

When would I use this?

Much like a mix task, an escript has the ability to use the rest of your project’s codebase. But it has that ability because the project and its dependencies are compiled and packaged in. That means you can use it outside of your mix project. And since Elixir is embedded, all you need is to have Erlang/OTP installed. So it makes our little script into an executable that is easily shareable with others!

To test that, feel free to move the ./tasker script out of your mix project into another directory and run it. You’ll see it does its work just fine!

Anything else?

We covered a lot of ground, and we saw that Elixir has great tooling for creating scripts. But I would be remiss if I didn’t include a mention of the OptionParser module. It’s a little module that helps parse command line options from something like this,

--flag true --option arg1

into a keyword list like this,

[flag: true, option: "arg1"]

So if you’re writing Elixir scripts, it’s sure to come in handy!

Permalink

10 Lessons from Decade with Erlang

The year was 2008. I had a steady job as a .NET developer. Then I read an ad from a company that was looking for developers with knowledge of Erlang… or functional programming in general and I applied.

I had learned a bit of Haskell in college and I loved it but I was not even remotely close to having experience in functional programming. Nevertheless, something told me that it was the right path.

Totally unprepared but ready to just improvise and see, I arrived at Novamens for an interview. I met Juanjo there but, more importantly, I met Erlang!

And that moment changed my life.

Erlang was celebrating just 10 years of open source back in 2008 :’)

Ten years later…

10 years after those events, I have learned a few lessons that I want to share with you.

Notice though that these lessons are things that helped me to write better code, they should not be taken as strict rules to follow. As my mentor Hernán likes to call them, these are heuristics. They’re likely to help you in your quest to build the best Erlang system ever, but more as a reference or guideline. In some scenarios, you’ll certainly need to bend and even break them entirely…

Higher-order Constructs

Erlang as a language is pretty simple, with few types, few keywords and a set of very basic operations. Those are the building blocks of huge systems and you should totally learn and understand them well.

But you should also learn to build abstractions on top of that. Think of things like higher-order functions, list comprehensions, OTP behaviors, libraries like sumo_rest and others. They all encapsulate shared knowledge that makes your life as a developer easier by removing the repetitive parts and letting you focus only on the specific stuff you need just for your system.

Things like message passing with ! and receive, recursion over lists, parsing xml manually, etc. should be scarcely used in large systems. You should instead use the proper libraries, frameworks o syntax (e.g. OTP, list comprehensions, xmerl, etc.). And if you find yourself writing similar things over and over again, you should consider abstracting that generic pieces to a library.

Use higher-order constructs (libraries, frameworks, tools) instead of building everything from scratch. If there is no higher-order construct yet, build one.

Find more about this on this in this article I wrote at Erlang Solutions blog.

Opaque Data Structures

Software development (as Hernán describes it in Spanish) can be seen the process of building computable models of reality, particularly in the early stages of development when you’re designing your system.

Those models include representations of the entities that exist in the real world. In OOP one would use objects for that. In other functional languages, like Haskell, we would use types. But Erlang has a pretty narrow set of types and, in principle, you are not allowed to define your own ones.

So, what to do? You have to combine those types to represent your entities (for instance using tagged tuples, records, etc.). But that gets messy pretty quickly.

That’s why I recommend using Opaque Data Structures, instead. ODSs are modules with opaque exported types and all the logic needed to manage them. They expose a functional interface for others to consume without worrying about the internal representation of the types.

Use Opaque Data Structures to represent your entities.

Learn more on this topic in these two talks I gave (one at EFLBA2017 and the other at CodeBEAM SF 2018)…

https://medium.com/media/a19f45ef634ba3b22d1d6f1a11494e76/hrefhttps://medium.com/media/1db810547d096c1a11611e579820876e/href

Test Driven Development

This is not particular to Erlang, TDD is a great methodology to create software in general. I will not go over its virtues here, but I will say that Erlang makes working with TDD very very easy.

For instance, here is an example of an assignment I provide my students when teaching them recursion:

-module my_lists.
-export [test/0].
test() ->
[] = my_lists:run_length([]),
[{a,1}] = my_lists:run_length([a]),
[{a,1}, {b,1}] = my_lists:run_length([a, b]),
[{a,2}] = my_lists:run_length([a, a]),
[{a,2}, {b,1}, {a,1}] = my_lists:run_length([a, a, b, a]),

ok.

That module compiles (thanks to its dynamic nature, Erlang compiler won’t blame me for not having a run_length/1 function defined there) but when you try to run it…

1> c(my_lists).
{ok,my_lists}
2> my_lists:test().
** exception error: undefined function my_lists:run_length/1
in function my_lists:test/0 (my_lists.erl, line 4)
3>

There you go, in pure TDD fashion, I’m prompted to define run_length/1 now.

See how easy it is? And for more complex systems you have tools like Common Test that work exactly like that test/1 function above, using pattern-matching to determine if a test passes or fails.

In my mind, there is no excuse not to work this way when building systems in Erlang.

Develop your systems incrementally using Test Driven Development.

Meta-Testing

Meta-Testing, as the Inakos d̶e̶f̶i̶n̶e̶d̶ borrowed from Hernán, is the practice of writing tests to validate particular properties of your code instead of its behavior. In other words, the idea is to check your code with tools like dialyzer, xref, elvis, etc. as part of your tests or continuous integration processes.

If you start using dialyzer, xref or elvis once your project is mature… you’ll have to spend a lot of time trying to detangle the cryptic meaning of dialyzer warnings. And don’t forget…

Dialyzer is never wrong. A warning emitted by dialyzer means there is a bug somewhere.

Dialyzer may not warn you about some problems, but if it emits a warning (confusing as it may be) that means you have an issue, somewhere. Maybe it’s not where the warning is reported, but you do have something to fix.

Now, deciphering what dialyzer found when you run it for the first time on a codebase with tens of thousands of lines of code can be challenging. But, if you run dialyzer on your code from the very first day, and you keep your code warning-free, whenever you get a warning it can only be something you just changed and that’s far easier to debug.

Use dialyzer, xref, and elvis in your projects constantly and consistently.
Start using those tools as soon as you start developing your system.

Katana Test (as explained in the link above) will make that extremely easy for you if you use common test. You just need to add a suite like the one below and that’s it. In fact, this one is usually the first suite I add to all my projects.

-module(your_meta_SUITE).
-include_lib("mixer/include/mixer.hrl").
-mixin([ktn_meta_SUITE]).
-export([init_per_suite/1, end_per_suite/1]).
init_per_suite(Config) -> [{application, your_app} | Config].
end_per_suite(_) -> ok.

Test Speed

Large systems tend to have even larger batteries of tests. As good practices go, you generally run all those tests at least once for every pull request and/or before every deploy.

That’s all good, but if kept unattended, those large batteries of tests will start making your everyday development cycle longer a longer. The goal of test completeness (i.e. covering as much functionality of your system as possible with tests) should be balanced with test speed. And that is not an easy thing to do.

Keep your tests running smoothly and fast.

In this article you’ll find some useful techniques to achieve that balance.

Behaviors

Behaviors live at the core of OTP, yet time and again people struggle with them. If you come from OOP land, probably somebody already told you that behaviors are like interfaces.

While that’s generally true, it hides a lot of complexity and it sometimes leads to some false beliefs that will needlessly complicate your code.

Invest time in understanding how the behaviors you use work and how to define and use your own ones.

Behaviors are great, they’re very powerful and yet extremely simple. You can learn more about them and unlock their whole potential with these articles I wrote a while back: Erlang Behaviors… and how to behave around them.

Tools

Erlang/OTP comes with many useful but somewhat hidden gems that will help you in your everyday life as an Erlang developer and boost your productivity. You should learn how to use them.

From .erlang and user_default to dbg, xref, and observer. Have you checked the sys module? What about erlang:system_info/1 or et? There are many hidden gems that can make your life easier.

Learn about all the tools that Erlang/OTP already provides to work better and avoid reinventing the wheel.

You can find 10 of these things in this article I wrote for Pluralsight.

No Debugging

Coming from the OOP world, one of the first things I tried to use when I started working with Erlang was the debugger. Turns out, that’s not a great idea when you’re dealing with a concurrent and distributed programming language.

Don’t get me wrong, the debugger works really well and it’s very powerful, but it will mostly just help you debugging sequential code. Debugging big systems and applications with it is… cumbersome at best.

Do not debug, inspect and trace instead.

On the other hand, Erlang/OTP comes with tons of tools to make tracing and inspecting systems easier. You can find several of them in this article by Dimitris Zorbas. And on top of the ones provided by Erlang/OTP itself, you have amazing libraries like redbug and recon.

Engage with the Community

This is easily the most common advice I ever gave to anybody who asks me about Erlang: Engage with the Community.

The community is not huge (we know each other by first name, as Monika Coles pointed out not so long ago), but it’s proactive and always helpful.

When you start working in Erlang it’s not uncommon to feel lost, many things are new and others are just unique for someone who never used the language before. Since the main benefits of Erlang are experienced when you build large systems, the initial steps can be challenging. Everyone in the community knows that (we’ve all been through those things) and we’re here to help.

Join the community and don’t hesitate to ask for help.

Join the mailing lists. Join the Erlang Slack. Find us on IRC. Find a meetup near you.

Have fun!

The most important lesson of all: The fact that you might end up building massive high-reliable backend systems with Erlang (and those seem really serious to me), doesn’t mean you can’t just have fun with it!

Erlang, being designed with fault-tolerance and concurrency in mind from day 0, allows you to worry less on those things and more on the interesting aspects of what you’re building. That’s The Zen of Erlang.

Enjoy your time working with this amazing language!

Besides that, if you just want to play with Erlang, you can test your knowledge of the language with BeamOlympics or challenge your friends to a game of Serpents

Or… you can build a team and win some awesome prizes at SpawnFest, too!

Thank you!

Finally, I want to use this chance to thank everybody who joined me, pushed me and guide me through this path. In no particular order…

📝

Do you want to contribute to Erlang-Battleground? We’re accepting writers! Sign up for a Medium account and get in touch with me (Brujo Benavides) or join the Inaka Community.

☕️

As usual, you can buy me a coffee.

You are also invited to join the Inaka Community.


10 Lessons from Decade with Erlang was originally published in Erlang Battleground on Medium, where people are continuing the conversation by highlighting and responding to this story.

Permalink

Copyright © 2016, Planet Erlang. No rights reserved.
Planet Erlang is maintained by Proctor.