Hacker News new | ask | show | jobs
by triskweline 2212 days ago
Our Ruby / Rails agency tried implementing a project in Elixir. After 3 weeks we stopped the experiment and re-did everything in Ruby.

What stopped us was not so much the lack of libraries, but programming ergonomics. E.g. when using keyword lists for function options, callers need to pass the keywords in the exact same order. Also mocking was difficult in tests.

Elixir is a great project with a friendly community, it just didn't work for us. YMMV so by all means try it out if you're interested!

3 comments

> E.g. when using keyword lists for function options, callers need to pass the keywords in the exact same order.

That's not generally true in the language. Were you trying to pattern match options in your own functions? Newbies to the language can get excited about the pattern matching feature and try to apply it in places where it's not right (well I may be projecting there).

> Also mocking was difficult in tests.

This is true. Were you using Mox? Mox makes things considerably easier at the cost of some boilerplate, with the added benefit that you can run concurrent mocks. You also have to not think of mocks in elixir like Ruby, they are very different.

I'm sorry I wish someone more experienced with Elixir could have helped onboard you.

> E.g. when using keyword lists for function options, callers need to pass the keywords in the exact same order.

This would've been fixed by creating a map from the passed in list, which would remove the order dependency but still keep the ergonomics of a keyword list, or just querying the keyword-list with `Keyword.*` functions. Not that big of an issue, to be honest, and not a showstopper. There are much bigger issues with the language, but Ruby doesn't offer any upsides in those cases either.

>when using keyword lists for function options

Proplists should be replaced with maps pretty much everywhere.

>Also mocking was difficult in tests

Interesting, what exactly was difficult? You just replace one function with another.

> Interesting, what exactly was difficult? You just replace one function with another.

I'm not the person you're asking, but iirc, that replacement is global - so once you replace function/module X with MockX, you can't test X itself, nor anything else that relies on X.

This is 100% correct, and a very huge pain point, and why you're supposed to use Mox, which solves that problem (arguably in a more conceptually "correct" fashion than ad-hoc Ruby Mocks). Admittedly there is a very steep learning curve, but it's worth it, because once do it you start to be able to do things you can't do in any other PL (not even erlang).

It's a pity that the elixir community doesn't make this clearer, because I'm seeing "not being able to Mock" be a common complaint.

It probably depends more on where they are coming from. Mox has more overheads for sure than options in Ruby or Javascript. Its more like mocking in Java or C++; where you declare an interface(behaviour), program against that, and then use dependency injection to load the mock or real code at the right time. I'd been working with Elixir for several years when I first tried using Mox and it still took awhile to get my head around it and figure out how to integrate it into our project. I would not be surprised to hear that newer teams really struggle with it.
> I would not be surprised to hear that newer teams really struggle with it.

I completely agree. Not having an expert Elixirist able to help me: It took me a full six months of fooling around with Mox (and a cryptic feature announcement in the 1.8 release) to really dig into and grok it. At this stage in my elixir experience, I have even PR'd a feature that's been integrated into Mox, so it's not completely incomprhensible, it's a super-well-written library.

Honestly, It's a totally (alien/from-the-future)-technology (in both the good and bad senses) library. The bad senses could be almost trivially fixed with an in-depth, free, online video masterclass or, hell, even a conference lecture on it, and blog posts. More people that really know how it works should blog about how amazing Mox is. Unfortunately, I suspect that the people who are using Mox to its fullest extent are too busy pushing code to prod, ha.

>and why you're supposed to use Mox, which solves that problem

I never used that Mox and never had a need to. I just use `Mock` which allows `passthrough` as I stated in another comment, what other clarity is needed I don't understand. Can you give any example of the problem you can not solve instead of pitiness?

You can't run concurrent tests doing direct mock injection in that fashion, because the mock is global. If you use Mox (or similar), your mocks are tied to your test.
Erm, yes this is why you mock it. I still fail to see the problem, here is an example how you mock a function: https://hexdocs.pm/mock/Mock.html

Inside `with_mock` code will only access mocked function. In case you want to call original function in some condition - you have `passthrough` available inside a new function which will call the original one. So what is the problem exactly?