Learn about the technology, culture, and processes we use to build Hootsuite.

Everyone — our software developers, co-op students, high school students — 'works out loud' about the tools we use, the experiments we ran, and lessons we learned. We hope our stories and lessons help you.

Recent Posts:

Ask any one Scala developer what they enjoy about the language and I’m sure they’d rattle off a number of features. As a relative newcomer to Scala, I’d like to shine a light on three features of the language that have stood out to me in particular: pattern matching, error handling using Option or Either, and the collections API. For developers well-versed in Scala these features are no doubt standard fare. But for those unfamiliar with the language, these three features make a good case for how Scala can enable you to write succinct, readable code.

Pattern Matching

Much like switch statements in Java or Go, pattern matching in Scala allows you to define a number of cases against which a given variable is tested for equality. At its most basic, it looks something like the example below, with the wildcard _ being a catch-all for any value not captured by the defined cases.

Where pattern matching becomes particularly useful, however, and where it begins to distinguish itself from your standard switch statement, is when it is used in combination with Scala’s case classes. You can read more about case classes here. In brief, a case class is a data-holding object, where that data should depend only on the class’s constructor parameters. Consider the following case classes.

Vegetable is an abstract super class with three concrete case class implementations: Pea, Eggplant, and ChocolateCake. We can then pattern match on a variable of type Vegetable, as in the example below.

Note how pattern matching here allows us to unpack and access the fields of each case class. Unused fields are simply ignored with _. Also worth noting: were we to omit one of the case classes in the above match statement – Eggplant, for example – we would get a compiler warning saying that the match would fail with the omitted class as input.

We can go further here and add pattern guards to each case. A pattern guard is of the form if <boolean expression>, appended inline after the case. It makes the value being matched on more specific.

The power of pattern matching at this point should be clear. A switch statement does not allow matching on types or inline guards; nor does it give us easy access to a class’s fields. To achieve a similar effect in Java – while still avoiding modifying each subclass – we could use something like the visitor pattern. But that strikes me as a rather heavy-handed answer to what we’re able to do so easily in the above.

Error Handling

When a programming language allows developers to return null values, at best, nullable methods are annotated and null checks are performed only where necessary. At worst, however, a developer either isn’t aware of or doesn’t trust methods’ contracts and the code becomes littered with null checks.

A Scala idiom, which eliminates if (object != null) where we remember to check and NullPointerExceptions where we forget, is to use Option. For example, while in other languages we might attempt to get from a map and then check whether the returned value is null before proceeding, Scala allows us to return an Option, which we can then pattern match on:

An instance of Option is either of type Some or the object None. Some, here, indicates that there is indeed a value. Pattern matching allows us to unwrap it.

Option thus allows us to smoothly build in handling for calls that may fail to return a value. A method signature where the return value is Option[String], rather than plain ol’ String, efficiently communicates to other developers that the returned value may be empty and forces them to handle that case.

But what if you want more specificity? Rather than merely returning None when a method fails to produce a value, you want to communicate why it failed to do so.

Either works in much the same way as Option. Rather than None and Some, Either’s subcomponents are Left and Right. By convention Right is used to wrap the “right”, or expected, value. Left indicates an error much as None does, except that it can be used to pass through a value, such as an error message specifying why the procedure failed. See an example of Either’s use below.

Whether using Option or Either, what makes these types useful is what they’re able to communicate to other developers via the method signature. A developer that calls a method with a return value of type Either[MalformedURLException, URL] is forced to safely handle the case where something goes awry. It also makes for more elegant error handling than the usual null check.

The Collections API

This may seem a bit obvious, but it bears repeating: much of programming is manipulating collections. The value, then, of a good collections API should be clear. I could give a highlights reel of the methods that make up Scala’s collections API, but the API’s power is perhaps better illustrated with a “real world” problem. Here on Plan + Create’s infrastructure team, we had a list of encrypted messages, or posts to social networks, that we needed to decrypt.

Note that the list of encrypted messages in question was ordered, and that each of these messages had an associated key used to decrypt that particular message. So we had two requirements for our algorithm: (1) that the original order of the list be preserved and (2) that messages with the same key be batched into a single call to decrypt, so as to reduce the number of calls to our encryption service.

To tackle our first requirement and preserve the list’s original order, we used Scala’s zipWithIndex – this creates a tuple of the encrypted message and its index in the original list.

Then, to group the given messages by key, we used groupBy. This gives us a map, where the map’s key is the value we’re grouping by – in this case, the message decryption key – and the value is the list of messages associated with that key.

Notice that the map key is of type Option[Long], because message.key is of that type. If we would rather work with a key of type Long, and toss out the list of messages that isn’t associated with any key, we could then use collect.

The collect method maps the values defined by the case statement(s) and discards those that are not. In this instance, we map the defined keys – Some(key) – to a Long and toss out the key group for which the associated key is undefined. Our list of messages is now batched and ready to decrypt.

Finally, after those batches of messages have been decrypted and we’re ready to return the message list, having used zipWithIndex at the beginning, restoring the list to its original order is easy.

First, we sort by the indices we saved in the first step. Then, no longer needing them, we throw out those indices by mapping from the tuple to the message. This leaves us with the list of decrypted messages in their original order.

Now take a moment to consider how verbose these same steps would be in many other programming languages. That’s why I think the collections API is one of Scala’s greatest selling points – it allows us to do away with for-loops and work with maps and lists in a clear, succinct way.

The collections API, together with pattern matching and error handling as I discussed above, makes a compelling case for Scala and how the language can enable you to write clean code. Hopefully you’ll consider giving it a try for your next backend project.

About the Author
Madeleine Chercover

Madeleine is a Software Developer Co-op on the Plan+Create team at Hootsuite. She enjoys reading, beer, the great outdoors, and doesn’t really like writing about herself in the third person.

 

 

 

If you’re anything like me, taking on an 8-month work term for a UX position can be quite daunting especially as a 3rd year design student with zero industry experience. It’s even more unnerving if you’ve got constant Imposter Syndrome nagging at you. It’s the all too familiar feeling of “I don’t belong here,” “I don’t deserve this,” or “I don’t know what I’m doing” that creeps up on anyone as they begin to take on new opportunities in their lives.

 

My big takeaway at Hootsuite is the value of mentorship in both work and interpersonal-related experiences. My mentors helped me address my Imposter Syndrome.

 

I’m happy to share that my mentors here at Hootsuite have helped me address this personal obstacle. If you’re feeling the same as you start your first ever work term, then the best piece of advice I can give you is to make use of the mentors you’ll eventually cross paths with.

Wait, what’s Imposter Syndrome?

Imposter Syndrome is associated with those who internalise all their hard work and achievements out of fear that they’ll be exposed as “frauds”. It reflects a false belief that someone is inadequate and an incompetent failure, despite evidence that indicates they’re skilled and quite successful at their craft.

This is something that I struggle with constantly with my work. Imposter Syndrome doesn’t discriminate and it’s something many experience whether if you’re a student on a work term or a senior employee. Common themes behind Imposter Syndrome are:

01. Attributing your success to external factors

“Oh, I was just lucky.”

“The idea just came to me.”

“They probably hired me because there was no one else.”

02. Constant fear of being exposed as a fraud or being unmasked

“People are going to find out I don’t know how to do this.”

My manager is going to find out I don’t belong here.”

03. Downplaying your own success

“I didn’t really do much, it was more of a team’s effort.”

It was a small problem, anyone could have done it.” 

Imposter Syndrome grows on paranoia and perfectionism: paranoia driving the fear of being unmasked, which, in turn, fuels the need to have everything be perfect. It’s a really vicious cycle. 

Although there are countless strategies about overcoming Imposter Syndrome, I don’t think I’ll ever truly eliminate the general anxiety or the lingering effects it has on me. During my work term, I’ve struggled with addressing my anxieties, but I’ve come to a surprising way of mitigating them: Embrace your anxieties, especially by listening to the doubts that you may have, but just listen to your thoughtful mentors even more.

During my first two weeks, it was difficult to convince myself that a company had hired me for a position that I’d been exhaustively pursuing in school. Ironic, I know. Without romanticizing an unhealthy work ethic, I had 12 hour work days and long nights spent on campus. There was rigour, for sure, in what I was doing as a student. I’ve learned a lot and had put the time in, but Imposter Syndrome truly made me doubt the established skillset and work ethic that I was bringing to Hootsuite.

I mean, in hindsight, I had earned my opportunity. My projects excelled in my classes; I understood and could apply UX concepts; I had all the technical skills listed in the job description; I ticked all the general boxes for an applicant. But my self-doubt manifested by my Imposter Syndrome made me dismiss my previous work and accomplishments. I ended up spending my first two weeks painstakingly waiting for the moment someone would call me out for not knowing x concept or y method and validate that I was, indeed, a fraud.

But I’m not a fraud. That’s where mentorship comes in.

During my time at Hootsuite, I worked closely alongside 2 mentors, Noel Heaney and Paul Donnelly, as I was part of the Plan & Create team. Simultaneously, I was surrounded by 17 other members of the Product Design team. These were the folks I individually respected for their own personality, position, skillset, and merits.

The second project I took on with full ownership had design mockup deliverables. This was the first time I would be creating something and I felt the need to have perfect, ideal solutions in order to continue masking myself or else someone’s going to call me out for being a fake designer. To be honest, I didn’t necessarily trust myself that I had the skills or enough background in the product to pull off it off. However, I’ve learned that you don’t have to completely trust that you’re capable of the work asked of you, you’ll just need to trust the people who believe in you.

 

You don’t have to completely trust that you’re capable of the work asked of you, you’ll just need to trust the people who believe in you.

I spent hours being meticulous with the designs that when it came to presenting it I fumbled. I didn’t feel like I got the point across with why the designs mattered. That’s when my mentor, and friend, Noel Heaney, told me an important part of being a designer: Designers create conversations, not things. It took me a few minutes to process. It was something so simple I completely overlooked it. It was humbling. Removing myself from the minutiae of a solution helped me move forward as I saw the main reason behind presenting solutions in the first place. I understood why we had quick stand-up meetings, bi-weekly updates, or even table meetings for that matter. It was rarely a tick-in-the-box that x person is doing y, but moreso an opportunity to have a conversation about your work and get feedback on it.

My anxieties decreased over time as I asked around the team if they’ve too felt Imposter Syndrome and to my surprise, they have. I knew everyone goes through it, but it was another thing to hear that a majority of my team had more or less the same experiences.

So, why mentorship?

Mentorship is valuable, humbling, and, most importantly, free. As a student on a work term, the main objective is to absorb as much information as you can, but this goes beyond the work as you may end up learning something about yourself.

We seek out mentors for their wisdom, guidance, and opinions as we begin new journeys whether it’s career or life related. If you already hold your mentor’s opinion in high regard, shouldn’t that mean their opinion on your potential and skillset would, more or less, outweigh your own doubts and anxieties? So what does that say about your mentor’s decision to stick with you on your journey? Again, you don’t have to completely trust that you’re capable of the work asked of you, you’ll just need to trust the people who believe in you. And mentorship is a great way to have someone believe in the work that you’re doing and the career that you’re pursuing.

 

“Stay humble. Be teachable. The rest will follow.” – Russell Taylor

 
I look back on those words that my mentor and teacher, Russell Taylor, told me before I started my work term and I’m glad I stuck by it. My advice for future co-ops is to take on as many projects and meet as many mentors as you can because you’ll never know how one small conversation can change your perspective entirely. This blog post is for those starting their first work term, but also as a thank you to the lovely and thoughtful mentors I’ve come across on the Product Design team:

Sheryl Soo, Felix Tin, Paul Donnelly, Helen Park, Ashley Gadd, Madison Poon, Melissa Riby-Williams, Claire McCormick, Noel Heaney, Meghan Deutscher, Adrienne Tsang, Marjolein Visser, Tamasin Reno, Kerry McNamee, Vanessa Lew, Guillaume D’Arabian, Tim Kolke, Will Balladares, Eric Puchmayr.

 

About the Author

Sabrina Ng is a co-op UX Designer on the Product Design team. She’s collaborated across multiple teams, especially on Plan & Create. During her co-op term. When she’s not at work, you can find her hitting up local streetwear shops for new sneakers, supporting her favourite Premier League team (Chelsea FC) at a pub, or working away on the corner couch plugged in with her hood and hat on.

You can find her on these fun things: Instagram, Twitter, Medium or connect with her on LinkedIn!

 

Introduction

I’m Kenneth, a Fall 2017 co-op student at Hootsuite. I study Software Engineering at the University of Waterloo. I had the amazing pleasure of doing full-stack software development with the Amplify Team this term! Amplify is a software solution for employee advocacy, primarily accessed through a mobile app for iOS and Android, that grew out of being an experimental Labs project.

I worked on a number of interesting technical challenges this term, like scoping and implementing native-style playable Facebook videos in the mobile app, adding manual scheduling functionality so advocates can choose exactly when their content will be published to social networks, and contributing to the Leaderboard feature #gamification #LevelUp! Under Scrum methodology, I worked with Python, MongoDB, JavaScript, Angular, Ionic, HTML, and CSS, and saw the impact my contributions were making with each new app release and deploy to production servers.

So with all these different contributions throughout the term, how do I choose one to dive into and discuss? As a matter of fact, one project I haven’t mentioned above is a small addition to the Home view of our app that I worked on toward the end of the term. I like talking about it because it highlights the main value of Amplify and was a fascinating opportunity for me in terms of technical thinking and design.

Background

One of the core functions of the Amplify app is the ability to share content to all of the social networks that an advocate has connected to their account. Once a user of the app has their desired networks connected (e.g. Facebook, LinkedIn), they want to be able to keep sharing articles to amplify their company’s content across social media.

Each social network account is first connected by going into the Amplify app’s Settings and going through an authorization process for each network, in which the user logs into the account in a web view and has to accept the authorization request before being sent back to the Amplify app. Upon successful authorization, the app then makes a request to a web API endpoint that securely stores the authentication token(s) in Hootsuite’s database — the same one that is used for the Hootsuite Dashboard.

Then, we use those stored auth tokens to perform necessary requests to that social network’s web API, such as when the user shares content. This all works well until a token becomes invalidated. Why might this happen? Consider, for example, that as of 2017, LinkedIn is transitioning from V1 to V2 of their API, so anyone consuming their API (like Amplify) should update the URLs we use to their documented V2 ones. This retrieves a new type of LinkedIn auth token that we refer to as a “V2 token”.

As part of my work this term, I updated the mobile app to retrieve V2 tokens. This is all good, but after the end of 2017, V1 tokens may become invalidated, and the user will have to re-authenticate LinkedIn to their Amplify account if they wish to continue sharing content to LinkedIn.

Thus, we needed to make changes throughout the mobile app to deal with expired tokens. One of the tasks taken on by another Amplify dev was to bring up the re-authentication webview upon trying to share content if there is an auth token issue. This is an improvement over the previous behaviour where the share action would simply fail with a general error, leaving the user wondering what went wrong and when their next steps are if they want to share that piece of content.

Problem Statement

My piece was to proactively check for broken tokens, implementing a new “reconnect card” that would show up at the top of the app’s Home view to give the user a warning about any disconnected social networks and prompt them to go through the authentication steps.

Front-end: The Reconnect Card

The design for the new reconnect card was well-defined and fairly straightforward to implement. It would be an additional Angular component created in the app, so some JavaScript, HTML, and CSS work was required, as well as some time for testing and fine tuning the design. Upon tapping a button within the card, the re-authorization webview would show up, which would then generate new tokens upon completion.

Then a loading spinner appears, until either the card dismisses and a success toast notification appears indicating that the connection was successful, or an error toast appears displaying any issues contacting the back-end and persisting the newly acquired tokens.

The following images illustrate this flow:

 

 

 

 

 

 

 

 

 

 

 

 

Now the account is reconnected, and the advocate can get back to sharing content.

Back-end: Detecting Invalid Tokens

None of the available Hootsuite microservices exposed any endpoint that proactively determined whether stored tokens were still valid (implementing such a service would be a significant task in and of itself). My proposed solution was to create an API endpoint in Flask (the Python web framework we use for the Amplify back-end) that makes a simple “get profile” request through an internal Scala microservice available at Hootsuite that abstracts away communication with social networks. The usual Python requests library was perfect for this.

If the status code from the get profile request is HTTP 401 (Unauthorized), that means that retrieving a profile failed because of an invalid token. Using this knowledge, the logic for our new Amplify endpoint is simple: go through all of the social networks that are “supposed” to be connected for the currently logged in Amplify member (i.e. all networks that were previously connected). Perform GET requests (these could even be HEAD requests) to the Scala microservice, and if the status code is 401, add that to a running list of disconnected networks to be returned.

 

Now that the code was in place to obtain a list of disconnected networks for the current Amplify user, all that was left was to hook up the front-end Angular service to this web API endpoint and use that service in the new Reconnect Card component.

Performance and Optimizations

Through some quick testing, the Python endpoint I created took between 2 and 3 seconds to run for a user with 5 social networks connected. Making this check every time the user opens their Home feed on Amplify is a bit much, since if the user switches from Home to another view and then back, it is unlikely the token expired or failed within that short time.

Thus, I made a few changes to the Angular controller class for the reconnect card, modifying the condition starting the call to the back-end. Specifically, we now only check for disconnected networks when the user opens the Amplify app, rather than on every refresh of the Home feed content. This reduces the number of requests to the Amplify back-end, thus reducing the number of requests to the Scala microservice. It’s a performance win all around.

With everything in place, my code changes went through code review and then I sent off the ticket to quality assurance. The back-end changes (i.e. the new web endpoint I added) were deployed to Amplify’s production servers and the app improvements are scheduled for release in mid-December.

Conclusions

Out of the many exciting technical challenges I got to learn from as a co-op student on the Amplify team in Vancouver, a memorable one toward the end of my term was one that allowed me to think carefully about software design while keeping the core value of the Amplify app in mind throughout the entire process.

After having made the code changes to update to LinkedIn API V2, I got the opportunity to do front-end and back-end development work to empower advocates using the Amplify app to keep a close check on their account and proactively address social network connection issues.

I am extremely thrilled that I had such an enjoyable and productive co-op term, and I can’t wait to see and work with the Amplify team and Hootsuite as a whole in the future!

About the Author

Kenneth Sinder is a Fall 2017 co-op student on the Amplify team at Hootsuite. He will be entering his third year of Software Engineering at the University of Waterloo in January 2018, and in his spare time he enjoys programming, reading about personal finance, and exploring the city. Connect with him on LinkedIn.

 

 

At Hootsuite, we value innovation. We believe that it is important to allocate time to step back and tackle impactful issues. That is one of the reasons why we hold regular internal hackathons. Hackathons are a great way to get people thinking out of the box, sharing ideas, and growing their skills.

Hackathon 11/17 Logo

How does a Hackathon work exactly? First, employees pitch ideas (usually based upon a problem that they are trying to solve). Everyone has the option to either pitch online (through Workplace) or live on stage. Either way, they express their idea concisely and specify what skills and resources they are looking for to help bring the idea to life. Then everyone gets to decide what they want to work on. You can sign up with someone who pitched an idea or you can always do your own thing.

Ideas don’t have to be strictly technical, and non-technical people can always ask for technical help in their pitches, if they need it. We make hackathons inclusive because processes, media, and other aspects of the business can also be hacked.

Once everyone has a team the hacking begins! This time we allocated three days of hacking. On the last day everyone gets to demo what they achieved, good or bad. After all, you learn the most when failing.

Themes

This time around we had two main themes: “Enabling the Platform” and “Automagically”. The themes are there for focus, but also to encourage participants to align their hacks with company goals. You can always stray from the main themes and #gorouge as we like to call it.

The “Enabling the Platform” theme is geared towards the Hootsuite third-party app ecosystem. We want to have a great platform in which other developers can add-on capabilities. Hacks in this category would make it easier for developers to contribute to the ecosystem or improve the overall platform experience.

The “Automagically” theme looks to make our customers’ lives easier, or to automate their tasks. From batching of tasks to advanced artificial intelligence, anything that makes repetitive tasks easier or more intuitive qualifies.

The Pitches

We hosted the live pitches on the HQ1 main stage. The pitches were also broadcasted live for our owls in other offices to watch and participate. There were 15 live pitches and 24 online pitches for a total of 39 great ideas. The atmosphere at the pitches was very lively, a great way of getting everybody excited and ready for three days of hacking.

People then got a chance to find a team. Every person that pitched an idea was standing with the name of their idea on a piece of paper. Interested participants approached the idea holder and had a chat. From there, the teams were born. Form Birds of a feather to #hoggr, teams both large and small got to hacking.

People hacking People hacking People hacking People hacking

There were a total of 43 teams of which 13 hacked on the Automagically theme, 13 hacked on Enabling the Platform, and 17 were #goingrouge. The total number of participants was 129 people, almost all of our Product and Development teams across the world (some of them in more than one team #youmaketherules).

Demo Time

On Friday, starting at 1pm, everyone got a chance to demo their hack. Every team had three minutes to demo and one minute for questions. Our Toronto and New York offices kicked off the demos via live feed. Then we demoed Automagically-themed hacks in Vancouver followed by Enabling the Platform and finished off with #goingrouge.

People demoing

At the end of each theme group everyone got a chance to vote for the best hack in that group. This also allowed for much needed breaks.

And the winner is…

After four long but exciting hours of demos the votes were cast and we had the winners. We had 2 theme categories and 3 extra categories:

Automagically

Create AI Create.ai can predict the performance of a tweet as a user composes it. The team created and trained a deep neural network on a dataset of 50,000 tweets with the goal of predicting likes and retweets.

Enabling the Platform

APIs and webhooks The team, created a new integration for third-party developers. We don’t want to reveal too much, but keep an eye on the Hootsuite developers blog for a follow-up announcement.

Learning Opportunity (Failure)

Scoring Social Engagement Scoring user’s social behaviour from 0 to 5 using machine learning; social behaviour being your engagement with post and engagement on your posts. The idea is to help gauge a user’s social change after going through Hootsuite Academy training or using Amplify / Amplify + Selling.

Non-Technical Hack

Goodbyes are hard David rounded out his previous set of Hackathon animated emoji with a brand new set for slack.

Mobile Hack

Drag n’ Drop Apple introduced drag ‘n drop with iOS 11, allowing to easily move content from one app to another. Until now, the Hootsuite app was left out – no more! Drag ‘n drop allows to drag text, URLs, images and GIFs from any app straight to the Composer to attach them to the message. The feature will be available in the next release of the app.

Takeaways

A hackathon is a great way of getting a group of people to really focus on one thing. It’s amazing what a small team can achieve in a small amount of time.

Despite most of the participants being in Vancouver, it was a global effort with participants in Toronto, New York and Bucharest. So much so that a team from the New York office won best “Automagically” hack. As a global team which is working to be #bettertogether, it was great to see a project presented through the livestream get chosen as the best hack.

This hackathon produced a lot of great working implementations but it also was a great learning opportunity. Not all hacks were technical successes, but we recognize that failing is part of the learning process. Having a “Learning Opportunity” category in the prices encourages participants to stand in front of everyone and talk about what they tried and what they learned about it.

We will definitely continue to have hackathons at Hootsuite and we will improve how we do it to maximize impact and minimize friction. One thing we want to do better next time is the demos. Some demos are great but other ones can sometimes drag on for more than three minutes. We are thinking of ways to make this process better for next time.

Last week, I had the great honour to be an attendee and a speaker at the very first KotlinConf in San Francisco. As a self-described Kotlin evangelist, it was a great opportunity to be inspired by the stories and projects of other Kotlin developers from around the world. With three session tracks, and 1200 attendees, there was no shortage of things to do!

I wanted to write a post about my experiences at the conference while it is still fresh in my mind. All the sessions were recorded and will be uploaded to Youtube sometime this month, I will post again a link to my talk when they are public.

Speakers Dinner

In addition to the two days of conference proceedings, as a speaker, I was invited on a Hornblower cruise around the bay the night before the conference began.

I admit that I had to fight the feeling of imposter syndrome on the boat with some of the great names in Kotlin. I saw Andrey Breslav, the father of Kotlin, Dmitry Jemerov and Svetlana Isakova, authors of “Kotlin in Action” that we had previously read at Hootsuite in our Kotlin Book Club. I spoke with Hadi Hariri, myself and Simon Tse had previously appeared on his “Talking Kotlin” podcast. I also got a chance to thank Alina Dolgikh, who has been instrumental in the success of our Vancouver Kotlin Meetup Group (join at http://vankotl.in).

The cruise was great, we travelled out underneath the Golden Gate Bridge and braved the wind for a good view of the city. Sadly, my Pixel 2 has not yet arrived, otherwise my picture taken from above deck might have been clearer. Meeting some of the JetBrains team as well as the other speakers and connecting with them on a personal level was an experience that helped me to feel more comfortable speaking myself.

Conference Day 1

The conference began the following morning, in beautiful Pier 27, on the Embarcadero. Immediately upon entering the venue, we were greeted by all things Kotlin: banners, swag, even pillows on the couch!

Keynote

In the keynote, Andrey and team introduced some amazing new things for Kotlin. Kotlin Multiplatform Projects sound very interesting! In the future, you will be able to share code between your iOS, Android, and web clients as well as your backend servers. An official Kotlin wrapper for React is out now meaning you could soon swap jsx for kotlin, exciting!

There were a lot of great things announced so check out the KotlinConf Keynote Recap that JetBrains posted on the Kotlin blog.

The Morning Sessions

There are so many new stickers, I’m running out of laptop room!

Cords and Gumballs

The first session that I attended was Mike Hearn’s talk “Cords and Gumballs”. The first part of his talk was about how Corda is using Kotlin in the banking industry. Some of his stories of the way in which they trained devs on Kotlin in house reminded me of our own adoption here at Hootsuite. We found that it was very easy to have devs fall in love with Kotlin.

The second part of Mike’s talk was about a side project that he has been working on to package Kotlin into native go-like binaries. The tool, Gumball, is open-source, and he invites people to contribute to the project.

What’s New and Cool in Kotlin Tools

Dmitry Jemerov, the aforementioned coauthor of “Kotlin in Action” spoke on new features of Kotlin and its tooling. In this talk we got a closer look at Kotlin multiplatform. This initiative is incredibly exciting. Being able to share code across Mobile, Web Backend, and Web Frontend has the potential to save vast amounts of development time and effort. Additionally, in the new serialization library, protobuf is supported out of the box!

I had made it one of the objectives of my attendance at KotlinConf to get my copy of “Kotlin in Action” signed by both of its authors, after this Dmitry was kind enough to be the first.

Over lunch I ran into Svetlana and she was happy to sign as well, now I am the proud owner of a signed copy of the book.

The Afternoon Sessions

After getting some lunch, it was time for the afternoon sessions.

Kotlin Static Analysis with Android Lint

This talk with Tor Norbye was a real eye opener. The Android lint program is incredibly extensible and powerful. I can envision how much time we could save on pull requests if we wrote a few lint checks to automatically flag and fix common errors. My big takeaway from this talk is that our Android team needs to sit down for a few hours with Android lint.

Lessons Learned Building a Build Tool

The next talk I attended was Cedric Beust on the build system that he created, “Kobalt”. There were two things that stood out to me from this talk.

The first were the problems of figuring out what nodes of a dependency graph are safe to build. Simon Tse and I created a tool called “Peon” that automatically creates Pull Requests based on changes to dependencies in a graph. I will expand on the details of this tool in an upcoming blog post but the core similarity with Cedric’s problem was that we had to figure out how to create the minimum number of pull requests and in which order to merge them, to propagate changes through the graph.

The algorithm that Cedric used in Kobalt was a similar to (though more advanced than) the algorithm that Simon and I used in Peon. Cedric’s algorithm allowed for the parallelization of builds, it could be a great extension to the peon tool.

The other piece of the talk which stood out was Cedric’s discussion of Ad-hoc Polymorphism. His solution of how to implement it in Kotlin is similar (though more structured) than some of the things that we do in our own app to decouple the way we call APIs for displaying streams of social content. Both I and Andy Fisher, an Android developer at Hootsuite, who was with me at the talk, resolved to take this lesson back to our own code base, to perform ad-hoc polymorphism in a cleaner fashion.

Kotlin Puzzlers

The final talk of the day was Anton Keks speaking about “Kotlin Puzzlers”. His talk was inspired by Java Puzzlers and it had a very interactive format. Anton showed small snippets of code and had the audience guess the output of the program, then explain why they thought it was so.

The whole talk was great fun and full of head scratching and even counting exclamation marks for:

println(!!!!!foo!!!!)

In the end, I walked away from the talk with a smile on my face and a healthy distrust of the Kotlin compiler in certain circumstances. Check out Anton’s repo of puzzlers here: https://github.com/angryziber/kotlin-puzzlers.

Day 1 Evening

After the final session of the day, there was an evening full of events, a party in Pier 27 kicked off by a “Party Keynote”. I had to ask myself, “What the heck is a Party Keynote?”

Party Keynote

Thankfully our Party Keynote speaker, Michael Carducci answered that question for us. Starting with illusions on a software development theme and ending with some mentalism, including guessing that Stephanie Cuthbertson was thinking of her son Peter.

After the keynote, everyone was ready for a bite to eat. There was a lot of great food waiting for us, unfortunately everyone had the same idea and so it left to some long lines at the start.

After the lines settled down, there was still plenty for everyone and in the meantime, Andy and I were able to get a photo to commemorate the event.

Conference Day 2

After a great first day of the conference, I woke up on day 2 anxiously awaiting my presentation slot as the first after lunch. However, the first thing we had in store for the day was a talk from the always interesting, Erik Meijer.

My Life as a Tech Transfer Monad

I’m still reeling from this talk by Erik Meijer, on what exactly probabilistic programming is and how we as programmers can apply it to real world problems. However, There were two things I loved immediately from this talk. First, near the beginning, Erik had a very succinct description on the expressiveness of Kotlin.

The other is that, we as programmers need to learn to think and develop differently because machines are coming for our jobs vis-à-vis Machine Learning Algorithms.

My Talk

Now it was time for me to do some final preparation for my talk. I presented earlier this year at AnDevCon and I covered my experience here. KotlinConf was a lot larger though, with some 1200 attendees.

Kickstarting Kotlin Culture: The Journey from Java to Kotlin

I had been scheduled at the same time as Andrey Breslav and so I wasn’t sure if anyone would show up. However, I was pleasantly surprised when I had a room more than half full to present to.

As I mentioned in my talk, which I won’t go into detail until a later date when the video is published, I try to live by the principle of “working out loud”. Noel Pullen (who also wrote on Guilds at Hootsuite) gave me that advice on my first day at Hootsuite and it has really stuck with me. To me, working out loud means: Work passionately, know that what you’re doing will be valuable to someone, and strive to share what you’re working on with those around you.

This was a major motivator for me wanting to share our story of Kotlin adoption at Hootsuite. I hope that my talk helps others accelerate their adoption and to grow Kotlin culture in their own organizations and communities.

I was honoured to be able to tell our story at KotlinConf but I certainly had help doing so. I would like to thank my director, Paul Cowles, for supporting me and the team through our Kotlin journey here at Hootsuite, and for helping me tell this story. I also need to thank Simon Tse, who appeared on Talking Kotlin with me, and who wrote the first line of Kotlin at Hootsuite. Finally, my team at Hootsuite for driving Kotlin Culture with me, both within and outside Hootsuite.

When the slides and video of my talk are posted by JetBrains, I will share them here in another post!

The Cost of Kotlin Language Features

The next talk after mine was about the cost of Kotlin features relative to Java by Duncan McGregor.

The talk was very enlightening and despite there being a measurable cost to some of the features of Kotlin, null safety, let blocks, etc. Duncan’s conclusion is that “Everything is reassuringly OK”. So based on his research, keep using your fancy Kotlin language features.

Going Serverless with Kotlin

Next was a talk that I knew I had to attend from the title alone by Marcos Placona. Paul Cowles and I wrote on our experience using AWS Lambda functions for cross platform iOS and Android development earlier this year. That blog post formed the conference talk that I gave at AnDevCon in July of this year.

Marcos had experimented with a variety of cloud providers which was interesting as we have just used AWS Lambda and API Gateway here at Hootsuite. One of his points aligned with what we found, Serverless functions are very cheap to execute and the free tiers from cloud providers is generous.

I chatted with Marcos shortly after his talk about Serverless and about the open source library that we created at Hootsuite to help people set up and maintain Lambda functions with Terraform and Gradle. Our function currently uses Java, he inspired me to cut a ticket to convert it to Kotlin.

Two Stones, One Bird: Implementation Tradeoffs

In the final talk of the conference, Christina Lee talked about tradeoffs in implementation while reviewing some Kotlin language features.

She discussed some of the differences between: let, with, run, apply, and also. When I see these features discussed I think of the graphic that we created at Hootsuite last year to help us understand the symmetry of these functions. I’ve since seen a similar illustration in other places (a missed opportunity to work out loud on my part) but I will also share it here.

apply and also return the object that the functions are called on while run and let return the last expression of the lambda.

apply and run have ‘this’ as the receiver inside the lambda while also and let have the renamable ‘it’.

The symmetry of these functions makes them easier to understand and we have cases we each at Hootsuite described in our style guide.

Closing Panel

All good things…

The closing panel was very insightful and the panel answered a lot of hard questions. There were some laughs when Andrey was asked what else he might add to Kotlin. He rephrased the question as “What haven’t I stolen yet?” and gave immutable data as a possible answer.

It’s at the panel that I learned there are around 50 people working full time on the Kotlin language, no wonder they’re making such great strides with Kotlin/Native, multiplatform, and other initiatives! I’m very happy that Jetbrains has invested and continues to invest so much in the Kotlin language.

I also learned that 17% of all apps in the Google Play Store are using Kotlin! I’m sure that number will rise before the next KotlinConf. The conference app, on web, Android, and iOS was programmed in Kotlin using Kotlin/Native, Kotlin/JVM, and Kotlin/JS.

Andrey and Stephanie Cuthbertson also talked about the language foundation which was promised when Kotlin was made an official Android development language during Google I/O this year. They currently have a language committee and they are committed to developing Kotlin in a thoughtful manner. The committee so far has: William Cook, University of Texas at Austin, Andrey Breslav, JetBrains, Jeffrey van Gogh, Google.

Andrey reiterated that with Kotlin, he’s more concerned about the features that are not added than the features that are. He doesn’t want the language to become too large, if they add many new features in the future, it will likely be coupled with the gradual phasing out of other features.

Conclusion

After two whirlwind days the first KotlinConf is over! I can’t overstate how honored I was to be selected as a speaker and how happy I was to simply attend. I hope that I can continue to #workoutloud and share my journey with Kotlin and more!

If anyone would like to reach out to me about my talk, about growing Kotlin culture, or about the Atlas and Peon tools that we use at Hootsuite, please contact me at neil.power@hootsuite.com or on Twitter.

Loading ...