Object-oriented after working with functional programming

Sometimes I need to divide my knowledge in phases: when I started to program, I felt that C/C++ were the best languages to make a software. Then, I’ve began to work with Ruby and learned Test-Driven Development. I divide my knowledge “before TDD” and “after TDD”, because it literally changed the way I could think about software and tests in general. Now, I’ll probably make the same division: “before functional programming” and “after FP”, and I only discovered that things have changed this week: I just discovered I don’t know how to do object oriented programming anymore – and to be honest, it’s not really a bad thing: I also saw in practice how object-oriented programming expects you to write lots of boilerplate in most situations.

This realization came to me when I was working in a peculiar kind of problem – it’s basically a ruby code that needs to connect on messaging system and, when it receives a message, needs to persist it in a relational database. The problem is that this specific system have a strong consistency requirement, so the message could only be updated on DB before a specific event happens: after that, we can’t change it anymore, except for some specific fields. Also, as we’re working with messaging, we can receive the message multiple times, out of order, and all of those strange things that happens on Internet-land. So, to summarize:

  1. The system will receive a message
  2. It’ll UPSERT a record on DB, just with some identification fields (they’ll never change, and if they do, they characterize another message to be persisted – think about an external id)
  3. It’ll BEGIN a transaction and SELECT ... FOR UPDATE my just upserted message
  4. It’ll find, on another table, the rest of the fields on the message
    1. If this record doesn’t exist, we’ll create it (and log)
    2. If it does exist, we’ll check additional info, and decide: or we ignore it (and log), or we upsert (and log), or raise an error

Now, for the implementation. Because consistency is a must have on this system, I don’t want to expose for future programmers (be it myself or some of my friends) some code that’ll induce me to errors: after all, who wants to do with_consistency_check(msg) { Message.upsert!(msg) } when I can just do Message.upsert!(msg), right? So, I don’t want to allow people to be able to modify, find, update, or anything else outside of the with_consistency_check (or whatever name I decide). So, how to do it?
Continue reading

Posted in Design | Tagged , , , , , | Leave a comment

Chlorine, Clematis, REPL Tooling

Recently I began to migrate some of the code on Chlorine to REPL Tooling, so things may become more testable. I already found multiple bugs in this approach and began an integration test methodology using Electron (I say that there are three kinds of developers in the field of automated tests – the ones that don’t test, the ones that do, and test freaks. I’m probably the later).

In the beginning, the idea would be to rewrite the renderer of results and exceptions so that I could fix lots of bugs that they have. So far, it’s progressing slowly, but I already can render datomic results in a meaningful way (the last renderer was interpreting as Java objects, which they indeed are) and fix some bugs with tags and other issues.

Now, one of the things that I wanted in the new renderer is the ability to copy/paste results in a meaningful way – as I’m using UNREPL, there are lots of tags that need to be reinterpreted, like #unrepl/browseable for datafy. These need to be “translated” to something useful for rendering on screen, with links to navigate inner details, but for copy-paste they should have a textual representation that makes sense (probably the hard part).

The results of all these experiments are quite interesting – when you evaluate something and th result is a Java object, there’s a link ... that can be used to navigate inside the object: it’ll show getters, the current class, methods that the object supports, so things like “goto definition for Java object” or “Javadocs” aren’t really necessary.

Then, one of my friends asked for a Vim option. Just for fun, I started Clematis, a port of Chlorine to NeoVim. And it seems they things are progressing faster than I thought!
Continue reading

Posted in Atom, Clojure, VIM | Tagged , , , , , | Leave a comment

Chlorine is thriving!

When I started this project, I was experimenting with shadow-cljs to see if I would be able to make an Atom package that would auto reload, run tests on ClojureScript, and se how far could I push ClojureScript in an Atom package.

Now, some months later, I’m seeing the package being used by a bunch of people, and I even discovered some bugs in UNREPL! Now, on this post, I’ll discuss a little bit more in detail the design decisions and my vision on the future of the project.

Chlorine is a clojure and ClojureScript atom package. It connects to a socket repl (opened via lein, boot, clj, shadow-cljs, lumo, or even REBL) and then upgrades the repl to be programmatically oriented with unrepl. Unrepl only works on Clojure, so for ClojureScript we use other techniques. Also, socket repl is a stream protocol, so to emulate a “request-response”, we need to coordinate things so Atom (and other editors) can react to commands and know exactly what’s the correct response for each command sent.

Design decisions

The choice for UNREPL was mostly because there is almost no documentation about prepl so far. Also, Socket REPL is literally everywhere: on Clojure , on ClojureCLR, on Lumo and Plank. Also, I wanted a better way to use ClojureScript, and I still have nightmares trying to use it over nREPL… and with Socket REPL things work fine.

Also, when I started the project Clojure 1.10 was just alpha software, and UNREPL offers us insanely good support for lazy lists, big strings, and other things that I wanted to use out of the box. One of the problems I’m still facing is coordination of evaluate/response, but this will probably be solved after a bunch of other fixes I’ll try.
Continue reading

Posted in Atom, Clojure | Tagged , , , , | Leave a comment

The perfect programming language (for me)

Disclaimer: the perfect programming language does not exist. Even if it did, different people want different things, so probably the ideas in this post would not reflect the ideas from different people. With that being said, let’s start with a little background:

I usually prefer dynamic languages. There are also moments when I miss static typing, but most of the time the “code/solution exploration” and a good REPL (and code design) do the job of reasoning about the shape of my data.

Except when it doesn’t. Then, things get ugly. Real fast. There’s always bad code that you need to work with, even one that you wrote about six months ago, and now you’re dumbfounded, looking at the code trying to remember what the hell were you thinking when you wrote the code and why you did think it was a good idea to wrote it that way at all. It happens with everyone. And that’s when static typing can (and will) help: it reasons about your data. You can have a variable named a, but at least you know it have the fields b: String, c: Int, whatever that means. But it helps.

Maybe we could have a language that allows you to turn on/off the typing whenever you wanted? With better REPL support? So, this would be my dream language to work with.
Continue reading

Posted in Clojure | Tagged , , , | Leave a comment

My fading frustration with ClojureScript

I’ve talked about at another post on how ClojureScript frustrates me, mostly because I was doing some Node.JS work and Figwheel simply wasn’t working correctly. Now, it’s time to revisit these points:

A little update: I talked a little with Thomas Heller, Shadow-CLJS creator, and he pointed me some issues with this article, so I’ll update it acordingly

Tooling

Figwheel and Lein are not the best tools to work with ClojureScript. Since I discovered shadow-cljs, things are working way better than before: I can reload ClojureScript code from any target, and I’m even experimenting with Hubot (and it works really fine too). The only thing I’m missing is my profiles.clj file, but I can live with that (and I can always use Shadow with Lein if I need profiles.clj).

Also, I’m working on a new package for Atom (and in the future, for another editors too) called Chlorine. One of the ideas is to offer better ClojureScript support (we have Autocomplete now!), using Socket REPL for solutions (even self-hosted REPLs like Lumo and Plank) and even wrap UNREPL protocol in Clojure. So far, is still in the very beginning but things are looking promising!

The stack

Forget Figwheel at all: Shadow-CLJS is probably the best tooling for ClojureScript ever. It auto-reloads ClojureScript code for the browser, for node.js, for node modules, and it integrates with almost everything that you want. It controls release optimizations, have sensible defaults, and even have post-compile hooks (so you can hook Clojure code to do something after some compilation phases). Also, it integrates with node-modules (no more maven-wrappers for JS libraries!) and have some warnings when you use some kind of ClojureScript code that would break :advanced compilation. And, let’s not forget that you can control the refresh reload phase, it adds a userful :include-macros in ns form (that will include all macros from the namespace being required), and controls exports in a sane manner. But first let’s begin with the feature that I found most useful: :before-load-async.
Continue reading

Posted in Clojure | Tagged , , , , , , , | 2 Comments

A new way to write Clojure on Atom

This will be just a simple anouncement: I’m publishing my (still very crude!) plug-in for Clojure’s Socket REPL on Atom.

Chlorine was an experiment that grew more than I could imagine: I wanted a better way to write ClojureScript on Atom, and that’s the reason I made Clojure-Plus (also, I wanted to seamlessly integrate CIDER and other refactoring/helper libraries on my workflow). But there were lots of bugs, problems, with my approach: I was using CoffeeScript (the default language on Atom packages, at the time) to write my plug-in. This meant lots of conversions from Clojure to JS, and every single bug I needed to reload atom to re-activate my plug-in.

Then, I tried to work with Figwheel. Atom packages are a mix of Node.JS with Browser target: figwheel was simply a lost cause (lots of problems when reloading when it didn’t knew what to reload, inconsistent state, flaky compilation failures that sometimes did work, sometimes not, without any logic). When I migrated to Shadow-CLJS, things worked a lot better.

Then, Microsoft bought Github. Atom always had a bunch of things that I did not like (quasi-semantic versioning, lots of feature requests that were simply ignored, multiple bugs that were not being addressed, performance issues) and with Microsoft buying Github (and already having an electron-based editor – VSCode), I’ll not wait to see Atom becoming obsolete. Most of the people that I work with don’t use Atom anymore, and it’s kinda difficult to see people working with Clojure with Atom too, so I started to think on a better way to port my work to other editors.

Then, it came the idea: most editors nowadays can run Javascript. Maybe I could work with ClojureScript and make a layer that would be used by all editors, and just code the parts that are specific for Atom in a separate plug-in. Then, it came the idea for REPL Tooling.

Then, I ended up too far on the rabbit hole: I lost track multiple times of what I was doing on REPL Tooling. So, for now, I’m developing both packages in parallel (if you look at Chlorine repository, you’ll see a submodule registered) so that I could code a tool, integrate immediately on Atom, then see the results in real time. This became a much better workflow (at the expense of unit tests for now). And then, one day, I was working on a ClojureScript project on my current job, and after multiple auto-completes, evaluates, and other things, I realized that my plug-in was good enough to be usable (and in a way that I would prefer to use it instead of other solutions).

So, I’m publishing it. Expect bugs (lots of it!), but it’s a start. I’ll try to release every new feature as soon as possible (possibly in an automated way – who knows?), and there are still multiple things to do (go-to definition, for instance, is completely absent) but I’m sure that there are lots of interesting things to happen!

Posted in Atom, Clojure | Tagged , , , , , , | Leave a comment

Atom packages with ClojureScript – upgraded

Last time I talked about plug-ins in atom with ClojureScript, I was using Weasel. Since then, I tried figwheel but it never worked as good as I wanted.

Then, I’ve decided to try shadow-cljs. Also, with shadow, we can build a node library instead of a “generic node application”, and this helped a lot in my current tests. So, right now, I’m going to show how I am developing the next version of Clojure Plus plug-in, and what to expect in the future.

Also, I must add that this is so far the best experience ever on creating Atom packages, so I’ll probably stick with ClojureScript for every future package too (I just need a way to make atom’s spec tests work better with ClojureScript – I’m thinking about using a helper library or something).

Preparation

First, you’ll use atom to create a package. It doesn’t matter if you produce a CoffeeScript or Javascript version, because we’ll delete all source files.

On package.json, we’ll modify the entrypoint: on the key "main":..., we’ll write "main": "./lib/main".
Continue reading

Posted in Clojure | Tagged , , , , , | Leave a comment

Understanding Ruby’s Awesome Nested Set

Recently, I saw people migrating from Awesome Nested Set to Ancestry. The reasons are simple – Ancestry is very simple, it just need a new string field in your table, and it’s easier to reason about. So, why should I even consider to use an alternative?

The answer is simple, and I’m going to quote H. L. Mencken: For every complex problem there is an answer that is clear, simple, and wrong.

And the reason that using Ancestry is a bad idea is simple: it doesn’t reflect good design. It treats a single field as a multi-valored column that keeps the ancestry of your object. This means that there’s no way to fetch all records AND their parents in a single query, or fetch all records AND their children, because we need to split the string (ruby-side) and then create a query (also ruby-side). So, in this post, I’ll show some tricks of what we can do with Awesome Nested Set, or even beter, how does it implements the tree pattern (and why it calls it a “set”, not a “tree”).

First, when we think about categories and sub-categories, we think like this:

But this is, in fact, a terrible way of representing trees in SQL. So, the alternative, is to transform it in a group of sets: Parent 1 (P1, for short), is a super-set containing subsets C1 and C2 (Children 1 and Children 2, for short). Each of the children have its own grandchildren, so C1 is a super-set containing G1, and C2 is a super-set containing G2 and G3.


Continue reading

Posted in Ruby | Tagged , , , , , | Leave a comment

Clojure with SQL databases

There are times when a specific piece of technology captures my attention in such a way that I feel the need to study more, and do things with it. Since I began to study Clojure, and after two jobs working with it, I’m still in love with it – I think it matches what I expect in a language most of the time, and also matches my repl-driven-development workflow.

So why I’m not considering it for new projects? Even personal ones?

When I need to prototype something really fast, I end up going for Ruby, with Sinatra (sorry rails, but you’re a terrible choice for me). I saw that in my last project, I worked with Sequel, postgresql, and Sinatra. For tests, I used VCR and recorded the external api calls that I had to make.

Well, I could probably prototype a simple VCR that would record a specific function call in Clojure. Sinatra, I could use Compojure. As for Sequel… Or ActiveRecord, for that matter…

There are a few libraries that can be used to communicate with SQL: Korma, that doesn’t support select ... for update and have some implicit connection problems and other issues, HoneySQL that interprets Clojure maps and converts then to SQL, and lots of other libraries that simply ask you to write your query and then, somehow, call then for you. I didn’t care too much for the later, after all, if I want to write queries I prefer to not depend on a library that does it to me – I know that there are people that don’t like to have SQL in the middle of the code, but I don’t see any problem with it.
Continue reading

Posted in Clojure | Tagged , , , , , | 2 Comments

To be wrong, even when you’re not

There’s a time when we must assume that we are wrong – even when we are doing the right thing. At my last job, I realized that it was happening with me.

After Nubank, I began to work on a company that, in a way, was a bet in my career – most of the systems in this new company were written in C# (a language that I had never written a single line), there was a huge codebase without a single line of test, the systems did not run on the developer’s machines, and one of the reasons that I was interested in working with then was to organize this codebase, in Clojure, with microservices. Also, to coach the development team, so we would migrate away from monolithic systems to a better architecture, with tests, microservices, and multiple programming languages.

In other words, to apply what I learned at Nubank in this company.

It was a long journey, first to be able to make the code, at least partially, compile on my Linux machine (the default configuration of our development machines was Windows with Visual Studio). And no, there wasn’t simply a matter of swimming against the flow that made me want to work on Linux: it was simply because the mandatory configuration of our Windows workstations was a very slow machine with a very slow antivirus and monitoring systems (to see if anyone was installing pirate software). Also, we had no access to USB, could not download external software, and our antivirus sometimes identified our git blobs as “suspicious software”, effectively corrupting our code every git commit. My machine booted in 10 minutes, and I had to wait another 20 for Visual Studio to be responding (and I’m not faking these numbers).

Then, the migration to Clojure. It wasn’t really that difficult to write the code. The problem was to publish it – the company did not want to use docker, nor containers, nor continuous integration/delivery. We migrated our code from TFS to Bitbucket to GitLab, then to a self hosted GitLab, then back to Bitbucket. Also, we had to fight – a lot – to be able to access our Q/A docker environment, as we had no access to production, staging, or homologation environments. We caught lots of bugs only in production, because we simply had no idea on how the calls for external APIs worked (there was not a single mocked/stubbed external system, and the very few external services that did offer sandboxed environments were so misconfigured that even API versions were different).

Then, after a long fight, more than a year later, we lost.
Continue reading

Posted in Work and Jobs | Tagged , , , , , , , , | Leave a comment