CharlesIrvine

CharlesIrvine

Convert boolean expression into an anonymous function

I’m wondering if the following is possible:

I have an application where I would like to parse boolean expressions and produce corresponding anonymous functions. These expressions:

x > y
x == y
x == y + 3

would be converted to:

fn data -> data.x > data.y
fn data -> data.x == data.y
fn data -> data.x == data.y + 3

Possible?

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Hey @CharlesIrvine can you elaborate if you are being passed these expressions as strings from users or other untrusted sources at runtime, vs compile time expressions?

Last Post!

al2o3cr

al2o3cr

There are useful shorthands like quote, but ultimately macros are transformations from AST to AST. For your example:

# INPUT
iex(1)> quote do: x > y 
{
  :>,
  [context: Elixir, import: Kernel],
  [
    {:x, [if_undefined: :apply], Elixir},
    {:y, [if_undefined: :apply], Elixir}
  ]
}
# OUTPUT
iex(2)> quote do: data.x > data.y
{
  :>,
  [context: Elixir, import: Kernel],
  [
    {
      {
        :.,
        [],
        [
          {:data, [if_undefined: :apply], Elixir},
          :x
        ]
      },
      [no_parens: true],
      []
    },
    {
      {
       :.,
       [],
       [
         {:data, [if_undefined: :apply], Elixir},
         :y
       ]
     },
     [no_parens: true],
    []
   }
 ]
}

The underlying pattern looks like:

{:some_var, _, _} -> {{:., [], {:data, [], Elixir}, :some_var}

You’d apply a transformation like this using a function like Macro.prewalk or your own recursive traversal code.

Once you’ve got the data-fied expression, you’d wrap it in the AST corresponding to fn data -> ... end. You can find that shape using quote:

iex(4)> quote do: fn data -> :ok end
{:fn, [], [{:->, [], [[{:data, [if_undefined: :apply], Elixir}], :ok]}]}

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

Other popular topics Top

Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49134 226
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement