Primes in Scala and Elixir

·

1 min read

I've learned and used scala for years and quite like it. But it is quite painful when you want to make a web server, all in scala. There are http4s and scalajs-react but you have to make everything including sessions, authentication, etc.

Elixir, phoenix and livebook look quite nice and many things are already prepared to use with great documents. I'm studying elixir for days.

Prime calculation in scala is quite simple and easy. Make stream elements and at the same time use numbers to filter candidates. (possibly same in Haskell)

val ps: LazyList[Long] = 
  2L #:: 
    LazyList.iterate(3L)(_ + 2).
        filter(odd =>
            ps.takeWhile(p => p*p <= odd).
            forall(p => odd % p != 0))

ps.take(100).toList
ps(100000)

I've tried to port it to Elixir.

two = Stream.cycle(2) |> Stream.take(1)
odds = Stream.unfold(3, &({&1, &1+2}))
primes = 
  Stream.concat(two,
    Stream.filter(odds, fn o -> 
      Stream.take_while(primes, fn p -> p*p <= o end) 
      |> Enum.all?(fn p -> rem(o, p) != 0 end)
    end))

primes |> Stream.take(100) |> Enum.to_list

Elixir refuses

to run with the following error message. undefined function primes/0 (there is no such import)

It seems that you cannot use the variable while you're defining it in Elixir. Maybe hard to implement in dynamic language. Anyway it has own strengths, and I'm quite enjoying learning a new language.