Tuesday, April 4, 2023

Elixir tips #2 - Doctest

A "hidden" gem of Elixir is the fact that you can actually test your documentation: yeah, you got it! you can test your documentation! 

Elixir makes documentation a first-class citizen in the language: it means documentation should be easy to write and easy to read.

If you are new about how to write Elixir documentation here the link .

We can now go directly to the concrete example. 

Let's start by creating a new project just by typing mix new doctest_demo :



If you now navigate to the lib and test folders you will find the following modules lib/doctest_demo and test/doctest_demo_test.exs (as described from the above output):



Without any further action let's run mix test and analyze the output:



Interesting fact is the output of mix test command: 1 doctest, 1 test, 0 failure. 

What does it mean 1 doctest
If you have a close look to line number 3 of test/doctest_demo_test.exs you will see the magic happens: doctest Doctestemo

With that syntax the code contained in the @doc snippet have been tested. How does it work? 

from official documentation:

Every new test starts on a new line, with an iex> prefix. Multiline expressions can be used by prefixing subsequent lines with either ...> (recommended) or iex>.


The expected result should start the line after the iex> and ...> line(s) and be terminated by a newline.

To run doctests include them in an ExUnit case with a doctest macro

 


Amazing! Did you know about it? We are actually making sure our documentation does not go out of date. 

Let's change the result of hello function to worlds and analyze what happens:



Niceee! doctest feature recognized that documentation is not aligned anymore with the code and it has been reported as error.

If you want to know more about it and its syntax and features here the link to the official documentation, enjoy it!

Wednesday, March 29, 2023

Elixir tips #1 - Performance

It has been a while since I started my journey with Elixir and I can say I'm more than happy so far by the journey. 

Elixir is an extraordinary language but now I'm not going to share my experience with Elixir, I'll do it in another post. 

I wanted instead to start with a collections of basic performance tips.

Always keep in mind time complexity when you write code:





Lists

Lists are not arrays as in other languages, but single-linked lists, then the above indicates that is important to know that dealing with Lists in Elixir is not efficient as other languages.   

`0(1) at the front` for `LookUpand `Updates` makes clear that we should use the `[ head | tail ]` pattern every time is possible.



Maps and Tuples

While `Maps` provide a more complex data structure, if we are dealing with few field a `Tuple` should be your preferred choice as the `LookUp` time complexity is `0(1)`. 

Counting Item vs > 1

Lists as written above are linked lists so when we try to count the items inside a list eg. `Enum.count( my_list)`; it is `O(n)` complexity operation. 




This is why in this specific case `if Enum.count( my_list) > 1 do` it is better to use `if Enum.empty( my_list) do`. In that case we avoid to count the entire list as it is not a stored info but a O(n) time complexity operation while the second case using the `head | tail` pattern is very fast

Checking empty strings

Strings can be considered like `LinkedList` for counts as there is not a stored information for fast access.

In case of understanding if a String is empty it is better to use `my_string_var == ""` rather than  `String.length( my_string_var) > 0`. 




In that case we avoid to count all the characters of the string, as it is not a stored info but a O(n) time complexity operation while the first approach is just a simple comparison.


I hope you will find them helpful!




Sunday, November 22, 2020

Delphi Event Bus 2.0 is here

 Hi folks,

I have been involved in the Ekon 24 conference and I held a session: Decoupling your application architecture using Delphi Event Bus. There I presented the 2.0 version of DEB and all the news along with this version:

  • Added new Interface based mechanism to declare and handle events
  • Added channels for simple string-based events
  • DEB available on GetIt 





Interface based mechanism

The new mechanism relies on the fact that an event must be an interface or its descendants:




This new architecture brings a great benefit in terms of memory management, because Interfaces are reference counted in Delphi. 

Breaking changes

  • Differently from the previous versions a subscriber method can only have 1 parameter that is an IInterface or descendants. 
    • You should change every Subscriber method to be compliant with that principle
  • On the same line of the previous one, because events now are interfaces EventBus.Post method can accept only an interface as parameter now
    • You should change every EventBus.Post method and pass it an interface - if you were using object with no interfaces 

Channels 

A very nice addition is the possibility to subscribe and post simple string-based events:  



Other improvements

  • Improved the internal post mechanism removing the CloneEvent due to the fact events were objects
  • Removed external sources needed because of the point above


How can I get it?

Since the version 1.5 Delphi Event Bus is available in GetIt (the Delphi integrated package manager):

You can also choose to download/copy/fork the library from github: https://github.com/spinettaro/delphi-event-bus

or downloading directly the release from here: https://github.com/spinettaro/delphi-event-bus/releases/tag/v2.0

Hope you find this version full of interesting features for you! 

Enjoy it!!