MarcinKasprowicz

MarcinKasprowicz

Blog Post: Elixir for JavaScript developers: first impressions

What I genuinely value at my workplace is that I can easily explore new languages through internal mobility. Throughout my career within Schibsted, I have been building things with JavaScript, TypeScript, Go, Kotlin, and recently Elixir…

https://medium.com/schibsted-engineering/elixir-for-javascript-developers-first-impressions-72d87b6eb1ad

First Post!

Sebb

Sebb

maybe I’m missing the point, but

def reverse_sentence(sentence) do
  sentence |> String.split() |> Enum.reverse() |> Enum.join(" ")
end

and if reverse is the point and you do not want to use stdlib

defp reverse([]), do: []
defp reverse([word | rest]), do: reverse(rest) ++ [word]

Also, you should check you code, as it is not correct.
Elixir has the great ExUnit and mix test.

Most Liked

stevensonmt

stevensonmt

Nice article, but you might want to edit this:

Elixir, also known as Phoenix/LiveView, the most loved web framework

which is just not quite true. You probably meant something more like

Elixir, probably best known as the language behind Phoenix/LiveView, the most loved web framework in the StackOverflow 2022 survey …

Eiji

Eiji

Unfortunately that’s not true, but I like your dreams. :smiling_imp:

Enum was added to provide generic API for every Enumerable. If I’m not wrong some optimizations were even rejected on GitHub. Even if Enum would have every optimization there is still one extra call for Enumerable implementation. Since the post is for Elixir newbies we should avoid going this topic too long. :exploding_head:

In mentioned post I have added a comment with both reduce and fast implementations. If we want to do it really fast we should only use pattern matching and recursion, for example:

defmodule Example do
  # function head with default arguments as described in article
  # `?\s` or `?\ ` returns a codepoint of space
  def sample(string, separator \\ ?\s, word \\ "", acc \\ "")

  # we simply pattern match if
  # current input, word (characters joined so far) and acc (words joined so far)
  # are empty which is true only if
  # the whole string is empty or contains only separator characters
  def sample("", _separator, "", ""), do: ""

  # when we reached end of input string
  # the only thing left is to join last word with our accumulator
  # Note: acc is common naming and short version of accumulator
  def sample("", separator, word, acc), do: <<word::binary, separator::utf8, acc::binary>>

  # trimming goes here
  # we simply pattern match checking if next 2 characters are our separator
  # in such case the function calls itself with only one separator
  def sample(<<separator::utf8, separator::utf8, rest::binary>>, separator, word, acc) do
    sample(<<separator::utf8, rest::binary>>, separator, word, acc)
  end

  # pattern matching for last separator after recent word (see clasule above)
  # in this case we do not want to have trailing separator
  # so we change our empty acc to the first word
  def sample(<<separator::utf8, rest::binary>>, separator, word, "") do
    sample(rest, separator, "", word)
  end

  # same as above, but with non empty acc
  # notice we reset the word after we set/add it to acc
  def sample(<<separator::utf8, rest::binary>>, separator, word, acc) do
    sample(rest, separator, "", <<word::binary, separator::utf8, acc::binary>>)
  end

  # this simple function clasule collects all characters that are not separator
  # and adds it to word parameter
  def sample(<<char::utf8, rest::binary>>, separator, word, acc) do
    sample(rest, separator, <<word::binary, char::utf8>>, acc)
  end
end

Edit: Oh, for those newbies confused with too many solutions I would recommend to give benchee a try. With just few lines we can determine which solutions is faster.

Sebb

Sebb

:grin:

It will at least be magnitudes faster than the version provided in the article and my recursive version. Hopefully also significantly faster than the tail-recursive reverse2 … or is it?

I’ll look into those with Benchee as you suggested.

Where Next?

Popular in Blog Posts Top

SmartLogic
Season four of the Elixir Wizards podcast launches today! This season we’re focused on system and application architecture. We’ll be doin...
New
mudasobwa
Blogged about the motivation and reasoning behind my idea to create yet another FSM library. Long story short: I did it in a proper way :...
New
brainlid
Building a LiveView powered chat app is easier than ever when using Streams! Sophie DeBenedetto shows us how in this article. She createa...
New
Paradox
Testing is an important part of any modern piece of software. But writing tests can quickly become an exercise in frustration, with tons ...
New
victorbjorklund
I’m showing you how you can customise the phx.new generator to give you a new Phoenix project the way YOU want it. In this post I show yo...
New
rlopzc
Use the new log handlers to plug Slack or any other provider into your logging system. https://rlopzc.com/posts/integrate-slack-into-the...
New
marcin
Hi! :waving_hand: I wanted to refresh my knowledge on how to mix phx.gen.auth with local password users db, as well as OAuth providers s...
New

Other popular topics Top

New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New

We're in Beta

About us Mission Statement