Python and the ErlangVM

Can anybody explain me, what is this exactly and how to use it in and with Elixir?
http://pyrlang.readthedocs.io/en/latest/

As I checked it’s Python’s implementation of Erlang protocol, which enables you connect with Erlang’s Node and eg. communicate with GenServer.

If it works with Erlang, it surely does with Elixir as well.

1 Like

I skimmed the docs and there seem to be many example using python and erlang. Those erlang snippets can be translated directly into elixir using the usual transformation rules.

Prefix modules with colon
Qualify using dot instead of colon
Use send instead of!
Prefix modules with colon
Don’t use upper case for variables.

If you happen to find an example that you do not understand or can’t translate feel free to ask a more specific question.

1 Like

Somebody in IRC tells me, that Cloudi is suitable in order to handle throughput inbetween Python and Erlang, because Pyrlang is a single socket connection for distributed Erlang node communication:

This project allows us to have multiple socket connections to python processes (and separate threads if you choose), Some comparison to cnodes is at http://cloudi.org/faq.html#4_Erlang

And i found a language which i heavly inspired by Pythons Zen, while targeting the ErlangVM:
http://efene.org/

Ahh I haven’t heard of that one in a long time. Wonder if it’s community lives. :slight_smile:

EDIT:

Heh, this is an interesting idea:

Passing functions around is so common in efene that we provide a nicer syntax for it which also enables some really lightweight dsl construction:

#_ "lists.map:2 takes a function as first argument"
lists.map(List) <<- case X:
  X + 1
end

#_ "mymap takes a function as last argument"
mymap(List) <- case X:
  X + 1
end

I could see similar in Elixir for pipes, hmm, a simple base case:

value
|> pipe_into_first_arg(1, 2, 3)
|>> pipe_into_last_arg(1, 2, 3)
||> pipe_into_last_arg(1, 2, 3) # Different syntaxes, hmm...

/me really hates that pipes only pipe into the first arg in elixir, keep having to use my flip macro a lot. >.<

1 Like

Fred Hébert did an interesting version of something pipe-like where you could indicate where you want the value to go with the _ variable. IIRC he wasn’t impressed with the pipe idea as such, but I could be wrong here.

I remember coming across this (an?) erlang mailing list thread by him when searching to see if a pipe operator equivalent exists for erlang.

This is the original thread I read from ~2 years ago: http://erlang.org/pipermail/erlang-questions/2015-July/085109.html

And it looks like he’s created a library for it now: https://github.com/ferd/fancyflow

Do you mind sharing your flip macro works? Or at least what the call looks like?

I think it would be possible to create an into macro that converts:

value
|> regular_first_arg(1)
|> into irregular_second_arg(1, _, 3)
|> into irregular_third_arg(1, 2, _)

into:

value
|> regular_into_first(1)
|> (&(irregular_second_arg(1, &1, 3))).()
|> (&(irregular_third_arg(1, 2, &1))).()

hi, what do you think of this

1 Like

There are libraries that add that feature to Elixir in a few forms:

a |> blah(1, _, 3) # In the second arg, I like this form

a |2> blah(1, 3) # In the second arg, not a fan of this form, more 'hiding' in my eyes, but it works well

That’s basically what my helpers do, trimmed to a couple things:

defmodule PipeHelpers do
  defmacro to_last(value, {fun, meta, args}) do
    x = {:x, [], __MODULE__}
    call = {:fn, [], [{:->, [], [[x], {fun, meta, args++[x]}]}]}
    {{:., [], [call]}, [], [value]}
  end

  defmacro to(value, {fun, meta, args}) do
    x = {:x, [], __MODULE__}
    args = Macro.prewalk(args, fn
      {:_, _, _} -> x
      ast -> ast
    end)
    call = {:fn, [], [{:->, [], [[x], {fun, meta, args}]}]}
    {{:., [], [call]}, [], [value]}
  end

  defmacro to(value, i, {fun, meta, args}) do
    i = ast_to_int(Macro.expand_all(i, __CALLER__))
    x = {:x, [], __MODULE__}
    call = {:fn, [], [{:->, [], [[x], {fun, meta, List.insert_at(args, i, x)}]}]}
    {{:., [], [call]}, [], [value]}
  end

  defp ast_to_int(i) when is_integer(i), do: i
  defp ast_to_int({:__block__, _, [i]})  when is_integer(i), do: i
  defp ast_to_int(ni), do: throw {:ARG_MUST_BE_STATIC_INTEGER, ni}
end

Can use it like:

blah
|> to_last(something(1, 2)) # Called like `something(1, 2, blah)`

blah
|> to(something(1, _, 2)) # Called like `something(1, blah, 2)

blah
|> to(1, something(1, 2)) # Called like `something(1, blah, 2)

I’ve needed the last one before when I did not know the position at ‘programmer-time’ but it is known at compile-time (another macro).

Hah, yeah that’s the one I mentioned before. :slight_smile:

2 Likes

The Elixir world is small :wink: