1-ZEN

Being a software dev is an exciting adventure and a great way of life.  

It’s not all moonlight and roses, though.

Numerous challenges await you down the road. Nemeses who will summon distress and anxiety for you. They will tamper with your mood, undermine your confidence, jam the performance and turn your efforts into dust.

If you’re an emotional person, like me, then you know how easy it is to subdue to them.

But fear not, my friend!

There are ways to defeat the gloom. Let me share some of the tricks I am using while fighting off my everyday enemies.

 wall1. The Wall

This one comes from Robert Pankowiecki: How to get anything done.

There are times you’re just stuck. Be it a bug you can’t find, a problem you don’t know a solution for or a new tech you’ve never tried before. You feel intimidated and afraid. You want to get out, forget and procrastinate.

It’s fine. Don’t fight it.

Instead: accept these negative feelings and… just start.

It’s not easy, quite the opposite, I know. The trick is to realize: worrying gets you nowhere, bad feelings will remain intact.
But once you start, even with the smallest thing, and you progress, these feelings will start to fade away.
Remember to bite off the smallest possible piece for a starter – it’s just easier to digest.

To make it more effective, you need a little mind trick, a little routine.

A completion ritual.

It may be something as simple as pulling a card into a ‘done’ column on your Trello board. Ticking a checkbox on a todo list, going for a smoke, if you please. Whatever works for you.
It’s such a small, seemingly irrelevant thing and I’ve been failing on this for a long time. I didn’t see the value. But it can work magic.
Did you know that forcing yourself to a fake smile actually makes you happier? This is similar. The completion ritual has the positive effect on your brain, no matter how small and trivial the tasks you finish may seem to you.

 shame2. The Shame

So you’ve started. And you’ve written some good code. It’s decent, you’re proud and happy with it. All good. And then, after a couple of months you want to add a feature. You look at your previously-super-duper code and all you can think of is “Man, who wrote that crap?” Ask your experienced colleagues how many times they have felt the shame.

It’s fine. Don’t fight it.

It means that you’ve progressed, that you’re growing, that you can see your mistakes. Nevertheless, you still feel bad and ashamed.
The key is to understand that, just like you’re not your 8th grade English paper nor your college entrance score – you are not your code.
My tip here is very simple to grasp and difficult to master: detach yourself from the results, treat them as external to you as possible. It’s not going to happen overnight but if you keep reminding yourself often enough – you’ll get there.

 imposter3. The Imposter

Sometimes your code looks gross to you but there are people around saying it’s good. Users are giving feedback: “Hey, thanks, it solved my problem!” Your colleagues are appreciating your work, heck, you may even be getting a promotion.
And then, a funny thing happens – you feel like a fraud.

It’s fine. Don’t fight it.

It’s a proven psychological phenomenon called Imposter Syndrome. I rarely meet a developer who is completely free from it.

Dealing with imposter syndrome is arduous and I am still looking for my ways.

Please check out these articles for some tips that may work for you: How I fight the imposter syndrome, Feel like an impostor? You’re not alone.

imposter-syndrome

source: @rundavidrun

Keep in mind:

It’s not who you are that holds you back. It’s who you think you’re not.
~Denis Waitley

expert

4. The Expert

Knowing you’re not a fraud is one thing, but this alone doesn’t make you an expert yet. Speaking of experts, I absolutely love this definition of an expert:

An expert is a man who has made all the mistakes which can be made, in a narrow field. 
~Niels Bohr

And it’s really simple as that. Go, do your mistakes. Fail, fail and then fail better. Take a look at the picture. This is Lunar React workshop. These guys have years of experience in their respective fields. Wojtek has been testing apps on java, c and rails platforms for years. Ania is fluent in ruby, js, objective-C, swift and what not. Cichy, my good friend, is my js go-to-person. To me, they are all experts in their respective fields. And yet, guess what day was the workshop happening?

Lunar React Workshop

Lunar React Workshop

Saturday.
These guys came to the office on their free day and studied React for 8 hours.
The message here is clear. Keep learning and accept the truth: You will suck in the beginning. But then again:

It’s fine. Don’t fight it.

Sucking at something is the first step to becoming sorta good at something.
~Jake the Dog

perfectionist

5. The Perfectionist

Needless to say, in the beginning you’ll make a graveyard of mistakes and your work will be far from excellent. You’ll encounter complex problems with many rational solutions and it will be difficult to decide which way to go. Should I use inheritance or mixins? Does this belong to a separate class? Am I using too many mocks in this test? Questions, questions. Questions everywhere.

It’s fine. Don’t fight it.

There is always more than one solution to a given problem. There is always something you can fix or refactor forever. There is never one definite answer to a design problem. The golden answer to any architectural question is “it depends”. Every design decision has it’s tradeoffs. Learning how to assess these tradeoffs is a lifetime challenge.

If you ever happen to delve on some issue for days, remember: better done than perfect. Don’t try to reach the absolute. Focus on delivering and take shortcuts if you need to. We all did. Sometimes we’re laughing at it:

shady_tricks

Must-have programming books

The truth is we’ve all made those shady things. Who has never copy-pasted some code from Stack Overflow? Googling an error messages? Every freaking day. Trying stuff until it works? The story of my life.
They are probably not the best practices but you should not hesitate to use them. If it helps you to move on, to deliver, to solve a problem you’re stuck with – do it! You’ll revisit later. Or not. The world is not going to fall apart.

 hermit6. The Hermit

It’s fine. But fight it. Don’t go alone.

The biggest mistake I made in early days of my career was not engaging enough with the community. You know, social fears, low self-esteem etc.
Find yourself a programming buddy, a mentor, go to a local programmers meetup and leverage social media (Programmers on snapchat).

Find people who are interested and talk to them about what you do. There are lots of them out there waiting to listen and to help you.

Programming is not a solo act, it’s a team sport. And it’s not so much about the code as it is about the people.

Final round

No one said it’s going to be easy. The enemies are real, the challenges are big.

But once you learn how to deal with them, once you manage to reach your inner zen – you’ll be rewarded. If you’re lucky you may even get into the state of flow. And then you know, you’re in the right place.

For me programming is a satisfying job and a one that keeps me in a positive state of mind for most of the time. A mental shape, in which I feel that I am constantly growing. Not only in terms of technical skill but, more importantly, as a human being.

Do you have similar experiences? Or perhaps you have other enemies you’re fighting every day? Please share your story in the comments and let’s talk about it!

PS. All drawings by the one and only Gosia.

How We Hire

A story that I frequently share when speaking at conferences is the one when I finally re-hired Ania. Once she agreed to rejoin us, I was so ecstatic to share the news with everyone. And then Tomek and Marcin popped up at my desk with sad faces to tell me: “Pawel, it’s not how we hire here anymore.”

One thing I realized back then is how successful we were with distributing autonomy. After all, two developers telling the CEO that he had no right to make a call about hiring a new employee tells quite a story. Another thing though was how much our hiring process had evolved up until then.

Since that awkward conversation, evolution has continued. While I think that by now we have a fairly stable hiring process I do expect it to be subject to change in future. After all, our experience in recruitment, as well as awareness of what we are looking for in candidates, improves as we get more and more chances to practise.

Hiring_What_We_Are_looking_ForWhat We Are Looking For

First things first. What we are looking for when we talk to a candidate. As the lead text on our job page suggests technical skills are only a part of the story, and not even the most critical one. Don’t get me wrong. It’s not that you can slip through hiring after finishing a couple of online courses for software developers. In fact, the technical bar is set fairly high.

You can, however, be a damn good developer and still fail. I told you: engineering skills are neither the only nor the most important skill set that we seek.

By the way, while in the examples I will use an archetype of a software developer as this is the most common role at Lunar, the story is true for graphic / UX designers, testers and all the other roles too.

The lens we use to look at engineering skills of a candidate is craftsmanship. I tend to phrase what craftsmanship is by saying that it’s taking pride in the quality of work that we do and continuously looking for better ways of doing things.

In a way, it is fuel to our personal learning vehicles. We want to get better at what we do because that’s who we are.

And that’s crucial as whenever we hire a person we don’t hire them for what they know right now; we buy their long term potential. That’s why a craftsman with lower technical skills will most likely win with someone who is already damn good but who doesn’t share that attitude.

Then we have the most important set of traits that we look for. Team skills.
I guess the meta-trait that we seek, and you’d find a hint in our job page, is that we want people who join us to notice and help a troubled colleague.

It means an understanding of teamwork as collective effort as opposed to an independent race for everyone involved. We are only as fast as the slowest person on the team. This rare trait basically makes everyone else on the team better. It is the true north for us. Interestingly, it doesn’t matter that much whether that person is the most technically skilled engineer in a team.

It means perception of others. How they are feeling. How they are acting. How they are behaving. It may be through empathy. It may be through sensitive perception. It may be through conscious effort. Whatever the means, we want team members to notice others.

It also means acting on what you see. It’s not only a willingness to help others but also how one helps. Inflicted help is often counterproductive. We need to understand others enough to know what kind of help they look for and what kind of help they are willing to accept.

It takes a lot of soft skills and awareness to excel at that. While we don’t look for perfection on this account, we need people who show the potential to excel as team members and leaders. Interestingly enough, the way we understand leadership means that we expect everyone to be a leader in a fitting context.

Oh, there’s one more skill that I keep forgetting about. You can score high on everything else but if you don’t speak really good English then it’s a no. For us, communication in English is like a driving licence for a driver. We. Really. Need. That. No. Kidding.

Hiring_Cultural_Fit

Cultural Fit

There is also something that is fairly vague but super-important. We look for a cultural fit. This one requires a little bit of explanation, though.

Most frequently when I hear about cultural fit and I have a chance to ask what people think when they say “cultural fit” I end up disheartened. The most typical notion of cultural fit is people who we would get on well with. Well, there’s a huge problem with such an approach.

In general, we tend to like people who are fairly similar to ourselves. Folks who have similar interests, similar walks of life or similar characters would likely be those who will make us feel most comfortable. The problem is that they are culturally very similar to us. In other words, if we defined cultural fit this way it means that we’d end up with a very homogeneous culture.

We’d feel comfortable at the office. That’s for sure. Would it help us to be more effective? Not at all. Conversely, we’d risk a close encounter with a phenomenon called groupthink, that leads to conformity and lack of critical evaluation. Nothing that you’d want to see in an industry that has solving complex problems at its core.

The way we understand cultural fit is that someone fits our (very broad understanding of) culture, shares our values, but at the same time would stretch that culture in a way. We want people who won’t introduce too much friction. But some tension is actually a plus.

We want people to have the potential to lead us in at least one of many dimensions which we want to improve. Be it how we learn, a technology skill, interpersonal dynamics, atmosphere, organizational stuff, empathy, respect, etc. It doesn’t have to be something specific. It should be something, though.

In other words, ideally, we look for people who would be thumbed up by most of us (a signal of fitting into the broad culture) and thumbed down by few (a signal that we’d likely feel pulled out of our comfort zones by a candidate).

Hiring_Process

Process

Now you know what we look for, here’s how we look. We kick things off with technical evaluation. Yup, you hear me. I mentioned that technical skills are neither the most important nor the only part that we focus on and yet we start with this.

The reason is very simple. We want to make sure that a new hire won’t be a burden for their team. In other words, wherever the bar is for a specific role, we want a candidate to be above that. Now, depending on the context, we’d expect different expertise levels. We don’t expect interns to be ready to instantly jump into a commercial project (even if it has happened here before). We don’t want developers to have a half a year learning curve before they are ready to get the ball rolling on a billed project either.

Anyway, the critical part of that stage is that as long as a candidate is above the bar it’s fine. It doesn’t matter whether it’s slightly above the bar or it’s more like “phew, that was left-handed” kind of case.

Ultimately it’s a kind of a filter. Depending on the context it may consist any of these three elements.

Recommendation
We trust referrals made by Lunar folks. If one of us knows someone and strongly believe that they’re a good fit then it’s a pass.

Interview
A short, typically around a half an hour long, interview with a couple Lunar engineers. In other words, a candidate would be talking with fellow developers, designers or testers and not a manager (we don’t have one so that would be hard anyway). We focus mostly on technical stuff but the most obvious personal characteristics will be evaluated too. Normally the interview is done at the office but it occasionally occurs on a video call too.

Homework
Most likely practised when it comes to internships but we may also try it in other cases. We give a candidate homework to do and then evaluate the result. A follow-up to the homework will almost always be an interview. Homework may mean writing a bit of code, which is the most common case, but it can be as weird as asking candidates to read a book.

Once a candidate makes it through the initial filtering, which may require literally nothing on candidate’s end in the case they had a strong recommendation, we’re down to the last part. We call it Happy Hours and originally it was dubbed Demo Day.

Happy Hours means spending a few hours with us, typically between 4 and 6, during our regular workday. The goal is twofold. First, we want a candidate to develop an opinion whether Lunar Logic is a good place for them to work at. Second, we want to give all Lunar folk an opportunity to develop an opinion about the candidate. The latter part is not mandatory, i.e. everyone at Lunar is invited to take part in Happy Hours but nobody is forced or even encouraged to do so.

The activities that happen during Happy Hours would vary from those focused on craftsmanship (e.g. pair programming), though those that validate how one thinks (e.g. design workshop), to those that tackle soft skills (e.g. a chit chat about candidate’s stories of teamwork).

Happy Hours are not structured so it feels a little bit like passing a candidate from one person’s hands to the others. There’s quite a lot of loose discussion in the kitchen in a bigger group too. Ultimately these kind of interactions would be happening on a regular day at Lunar.

After Happy Hours, we collectively make a decision. It follows the Decision Making Process pattern so there’s a broader discussion among everyone who took part in Happy Hours. Then someone makes an autonomous call whether we make an offer or not.

We don’t seek consensus in these discussions. However, for a positive decision, a significant majority for “yes” is typically required. In other words, a set of fairly evenly distributed opinions (some for “yes”, some for “no”, some for “meh”) most likely means a “no”.

The last step is figuring what a financial offer for the candidate would be. To simplify things we typically run a super quick salary process, exactly the way we do it for ourselves when we discuss raises. This makes the offer fair in relation to current salaries at the company.

It does mean that, while we obviously are interested in how much you expect to earn, we will propose a salary. Since the offer aims to keep our payroll fair it is highly unlikely that we’d be open for heavy negotiation. As one famous football coach said: no player is bigger than the club.

That’s it. It may sound like quite an elaborate thing but in some cases, it boils down to fairly informal, few-hour long visit at the office.

I’d like to write something like “Since we adopted that technique…” but it wouldn’t be true. There wasn’t a single point when we started hiring this way. It is more an outcome of how this process evolved over time. Throughout this evolution, we’ve been making fewer and fewer hiring mistakes, which seems to validate how well the process works for us.

Some time ago

Few months ago we published a series about creating applications using React and related architectures (flux and redux).
Since then, we also started using React Native and we think it’s awesome!
reactive-native-logo

The goal of the post

This post is not meant to be yet another React Native tutorial because I believe there are already many good ones available all over the Internet.
I just want to show you the app from my previous posts, implemented in React Native. I’m really excited about how similar it looks to the web version and how smoothly you can implement things.

Let’s build the app!

package.json

We will install very similar list of dependencies as in we did in the webapp:

We can leave out the dependencies related to making the app universal because there is no such problem in the native app – we don’t need to add server-side rendering because native app is not crawlable, we don’t have to worry about SEO.
More information about the importance of the universal feature of a web app can be found in the first post of the series.
Also, it is not necessary to explicitly define the babel stuff, because it’s part of the React Native dependencies.
Lastly, we don’t need to worry about building and compiling assets – React Native does this for us. Therefore, we can leave out Webpack.

index.ios.js

Entry point the whole application is index.ios.js:

There we render our main component – App.

App.js

Let’s create a src directory, where we will put all of our source code.
Also, create a components directory inside, we will store all components there.

So let’s add first one – App.js:

It looks very similar to the application.js file, we had in the web version. The whole idea is the same – we use the same redux library.

store.js

To make it work we need to add a store:

This is also almost the same as the web version. The only difference is that we can remove all stuff related to making the app universal – so store is even simpler.

Routes.js

On top of store we also need Routes:

I found react-native-router-flux very convenient to use. And again, it’s very similar to react-router that we used in the web app.

SubmissionsContainer.js

Now we can finally define our first container – SubmissionsContainer – which will be responsible for displaying the submissions list:

This is the simplest version that you can implement and the most similar to the web version. But you can also use React Native built-in component that will be translated to the native list control. See the documentation here.

Other redux stuff

The rest of the redux stuff here is exactly the same – create action_creators, reducers, constants and lib folders (as we had before) and put there SubmissionsActionCreator, SubmissionsReducer, ActionTypes and Connection accordingly.

My favourite feature

Apart from developing for two platforms at once, for me, the killer feature is that it’s so easy to do pretty things. The thing I hate while developing a pure Objective-C/Swift app is that many things related to the UI (like colors, font sizes, etc) are mixed with application logic.
Of course, you can set some things using Interface Builder but there are a couple of problems with that. Firstly, I’m not a big fan of Interface Builder. Secondly, not everything can be set there and it’s just better to have main colors and things like that saved in constants.

React Native uses Flexbox for styling your components. Although not all the features from web flexbox are implemented yet, I love it!

And styles are the last file needed to make our app working:

Run

Now you can open ios/ProjectName.xcodeproj file in the Xcode and run the app!
react-native-screen

Platforms supported

At the time I was playing with React Native, there was support only for iOS and Android.
While developing an internal project I noticed that, for now, iOS is supported better. But provided you don’t do too much custom stuff, you should be good with Android too.

If you implement the app with common controls you should be fine. If you want to do things like drawing custom shapes using native libraries, you need to check Android support before ;]

Just a week ago, React Native team announced that they joined forces with Microsoft bringing React Native support for the Universal Windows Platform. It means that it will be possible to develop for Windows Desktop, Xbox and Windows Phone in React Native.
I didn’t test this yet, but looks promising. See more details here.

Differences in native controls between platforms

You are probably wondering what if you need to make one version (e. g. Android) different.
That’s not a problem! You can easily make different components by just adding platform suffix to the file name – e. g. SubmissionsContainer.android.js.
React Native will render proper one depending on the platform.

Summing up

Implementing React Native is smooth and enjoyable. The only thing you need to keep in mind is that this is a tool for doing front-end. If your mobile application needs to perform high load operations then it’s not the right tool for you. But if all your high-performance operations happen in your backend and you use the mobile app only as a client, it’s very convenient to use.

puzzled-cat-01The problem I have with functional programming concepts is that whenever I learn about them, it’s usually about monads, closures, folds, infinite streams etc. I know they are cool and all but, honestly, I rarely see a good use for them in my daily work. I am a Ruby dev mostly; I like to get stuff done without too much ceremony. And I really like OO, despite all its shortcomings. There are times, however, when situations call for something better.
This is a story of how we ended up with pretty cool functional code in an evolutionary way.

Context

We have a project, which is a tool that enables users to get a mortgage online. Actually, it’s the first app that lets you get a mortgage sitting at home in your pajamas. 100% online.
Firstly, customers fill in lots of data about themselves and the property, then the system presents a list of mortgage offers from various banks. To get those offers as exact as possible, we need to calculate many determinants (things like property pledge, financial portability, amortisation, etc.). These calculations are pretty straightforward, but there’s a lot of them. Moreover,  they’re interconnected: results of some may be used in following calculations down the road. Finally, we end up with few important values (which determine the final mortgage decision) and a considerable amount of data, all of which needs to be stored e.g. for presentation purposes.

MVPs are like cheap wine.

Cheap wine is good because it’s good and cheap. So are MVPs. You’ll want something better much sooner than you’d expect.

At first there only were 2 banks and one robust algorithm that was separated into many classes for clarity. Then, as we added more banks to the platform, things started to get complicated. Various requests from clients began to emerge: calculate retirement age differently, use gross income instead of net income, divide instead of multiply, etc. Different banks had different formulae for things. You get the idea.

Enter the strategy pattern.

We started spinning-off parts of the algorithm to separate classes and injecting them dynamically into the main template. Nothing unusual – classic strategy pattern. It all looked good. But it grew and grew, and then it grew just a tad to big. The code became messy and unreadable. Strategies started to have their own sets of strategies; layers of abstraction were multiplying like crazy and it was killing us. For newcomers to the project, it was almost impossible to understand what was going on. The domain knowledge was lost between the lines. The bus factor plummeted.
The project was live and starting to generate income, but adding each new bank to the platform was taking 1-2 weeks. It was a crucial process for the business and it simply took too long.

It never rains but it pours.

As if this wasn’t bad enough, then came a real bummer. A new feature request for a view with a summary of all the calculations. Now, not only did we have to save all the numbers, but now we also had to persist the formulae used to calculate them… How can we add another layer to this already messy code?

We didn’t. We created a separate set of decorators just to handle this. It worked for the moment, but now the knowledge was in two separate parts of the system. We were facing a shotgun surgery issue on top of all the previous problems.

We realised, it’s time to take a step back and reassess.
After talking to our client, we decided that we are going to spend some time to refactor and pay back part of the technical debt.function-cat-01

Back to square one.

Refactoring started with gathering the requirements:

1. We have initial data, mostly numbers, and booleans coming from user input.
2. We have an ordered list of calculations to be performed on the input data. These are our previous strategy objects.
3. We should be able to reuse results from all calculation steps.
4. We need all the results in the end.
5. For some of the results we need not only values, but also the formulae.
6. We need all of the above to be as flexible as possible. When a new bank joins the table, we should be able to adjust independent parts of the algorithm without too much hassle.

Input and output. United we stand.

The input hash:After calculations the output will look like this:

Strategy objects.

What are the strategy objects we’ve been using so far? They are the atomic pieces of the algorithm. Like steps in a cake recipe. Do we really need the OO boilerplate? Strategies could be stateless, so why not just use functions? Oh, it’s Ruby. There is no first-class function concept. Perhaps, we could use lambdas. But we’d like to get the strategies tested and possibly reuse some of them for various banks. How about modules with one static call method? Since we are passing entire data hash to each calculation function, we need to “swallow” unnecessary keys. This is a moment when Ruby’s keyword arguments and the double splat operator come in handy. Dig it, it’s awesome.

Banks.


Bank parameters are an example of externally configurable factors, you can get them from the DB for instance. The evaluation steps are what’s interesting here. It’s a line up of calculations to be performed on data. This is each bank’s recipe for a the final answer.

Putting it all together.

This is our entry point:Let’s roll. We pass the hash from one step to the next one, using inject method. Each one is taking whatever it wants from the hash, working on it and adds the result as a new key-value pair to the hash. In the very end, it’s all in the final hash (it smells a bit of primitive obsession, but let’s keep it simple for the sake of example).

New boys in town.

When you need to add new strategies, which may be different for the banks, you’ll do it like this:

Fail Better.

One problem that we’ve encountered, were ambiguous error messages when strategies couldn’t find the required key. With a little bit of ruby magic we’ve managed to improve that.
Now, when you get the error, you know exactly where to dig:

Final thoughts.

sleeping-cat-01The solution meet requirements mentioned above. It looks simple and indeed it is. Not only it is easy to use but also elegant and extensible. We’ve been using it in production for 4 months and haven’t encountered big issues so far. What’s more important, however, we have successfully reduced the time needed to add a new bank to the platform from 5-10 days to 2-4 days. It’s something.

Additionally, testing is now super easy. You can unit test each atomic strategy independently.

As a bonus, if you’re as lazy as we are, you can always make an inline strategy by defining a lambda in the evaluation steps template like this:

 

Of course, this is not a silver bullet and has issues of its own.

The high connascence of name for input and output keys is the biggest problem. We work around that with one integration test for each bank to make sure that we’ve got good coverage. Another problem is that modules can’t have static private methods, which would be helpful for some more complex strategies. Should you see any other issues, please let us know in the comments.

All in all, it’s been an interesting exercise for us and a one which proves how flexible and fantastic the Ruby language is.

Please do share your thoughts in the comments.

PS. If you’re wondering what happened to the formulae requirement, stay tuned. We’ll cover that in the second part.

Lunar on Snapchat

snapcode-face

szynszyliszys

UPDATE 22.04: This post has been updated with new information on 22.04.2016.

As you may know already, we are quite a unique company when it comes to organizational culture. We value empathy and transparency. We collectively manage the company. We have open salaries, advisory process, collective hiring, self-organizing teams etc. For the last 3 years, we have been evolving toward becoming a no management organization.

We’ve been blogging and tweeting about this for some time now, but today we want to try something new: Lunar on Snapchat!

We are heavily inspired by Andrzej Krzywda and his ongoing experiment Programmers on Snapchat. The idea is neat and simple: share programming related content on snapchat and create a community using this new, ephemeral medium. Please do read Andrzej’s article to learn more about it.

favicon-120 Update 22.04: Andrzej have created a very simple app: DevSnap: a directory of developers on snapchat. It’s growing like crazy. At the time of writing this post we have 55 developers. So please check it out and follow these programmers, they share good content. Also, don’t hesitate to add yourself there, even if you don’t snap much. You’ll start soon enough :) And once you’re hooked, you’re hooked.

Besides taking active part in this experiment, we want to add another layer to it. A little more personal one. We strongly believe that programming is not only about code and tools but, most of all, about people and interactions (sounds familiar?). So we are going to share snaps from our day-to-day office life.

Do you want to know what Lean Coffee is? How Happiness Chart works? How feedback works in no-management environment? What we do to keep our company going in the participatory leadership model?

If you are interested in all this and want some first-hand experience – follow us on snapchat! And do expect solid amount of inspiration. Of course, we are going to share a lot of programming stuff too and some personal snaps here and there.

Find our snapcodes below. Scan them or add us by usernames. We’ll add you back :)

Tomek @ Lunar: rusilko, Artur: arturtrzop,  Ania: szynszyliszys, Dawid @ Lunar: cichaczem

10289858_10153795931557745_8215933735273622601_nsnapcode   cichaczem_snapcode-1


Update 22.04: New folks on board:
Paweł @ Lunar (our CEO): pawelbrodzinski, Tomek Giereś: tomaszgieres, Maro: mareczekc

Screen Shot 2016-04-22 at 08.32.15 Screen Shot 2016-04-22 at 08.31.24Screen Shot 2016-04-22 at 08.52.54