vshesh

vshesh

I have a situation like:

defmodule X 
   def f(x) when is_integer(x) do 
     # ... something
   end 
   def g(x) when is_integer(x) do 
     # ... something
   end 
end 

Now, I want to also provide clauses that apply when is_binary(x) .
I have a wrapper function like

def wrapper(f) when is_function(f) do 
  fn b when is_binary(b) -> b 
  |> # convert to integer representation (in a custom way, not string.parse_int)
  |> f.() # i need the .() right?
  |> Enum.map(&to_string/1)
  |> Enum.join("") 
end 

I want to express this kind of concept

f(x) when is_binary(x) = wrapper(f)
g(x) when is_binary(x) = wrapper(g)
# ideally would not need to repeat the is_binary(x) clause

Not sure how to do this in elixir in the simplest way. Here’s what I have right now:

    def f(x)
    when is_binary(x) do
      string_version(&f/1).(x)
    end
    def g(x)
    when is_binary(x) do
      string_version(&f/1).(x)
    end

Feels rather clunky/repetitive though. How do I get an extra clause by transforming the initial clause idiomatically? One thought I had is with macros:

add_clause wrapper, f

adding a clause with a macro seems like … oof. and I’m not sure how I would copy the guards from the result of the wrapper to the output of the macro.

Showing Posts 1 to 6

brettbeatty

brettbeatty

If I’m understanding your question correctly, and I’m not sure that I am, one option would be to break out “wrapper” logic into private functions and call them in other clauses of your functions.

  def f(x) when is_integer(x) do
    # ... something
  end

  def f(x) when is_binary(x) do
    x
    |> convert_to_integer()
    |> f()
    |> convert_to_binary()
  end

  def g(x) when is_integer(x) do
    # ... something
  end

  def g(x) when is_binary(x) do
    x
    |> convert_to_integer()
    |> g()
    |> convert_to_binary()
  end

  defp convert_to_integer(binary) do
    # ...
  end

  defp convert_to_binary(integer) do
    # ...
  end

To me it does seem a little strange, though, to use the same function for integer → integer and binary → binary operations.

vshesh

vshesh OP

If it helps, consider the int -> int and string -> int cases and ignore transforming back to a string. The same question still applies.

In some langauges like Scala there is a concept that you can just get natural transformations for free, if they exist.
This is called implicits there, and it’s called other things in other languages

I am in a situation where i want the same function to apply no matter what form the concept represented by its argument is expressed in. It’s admittedly not that much of a change and one could imagine just dropping the transforms wherever I need them in the calling code. It is a nice convenience that’s more “ergonomic” for the data type i’m working with.
As for why int -> int and string -> string it’s common that if I get the type in one format I want it back in the same format.

imagine units - if someone speaks in meters you do the calculation and return to them a value in meters. Someone else can use yards and they would get yards, that kind of thing . So there is a real world analogy to what i’m doing.

kokolegorille

kokolegorille

You might look at protocols for this.

dimitarvp

dimitarvp

Macros are basically code generators, what else would you use if you had the option?

vshesh

vshesh OP

Yeah, I thought about it and realized that macros are indeed the right answer - they are code generation tools and even things like decorators in other languages are also macros, just a special kind of limited macro with special syntax.

So I guess some kind of macro it is :slight_smile:

add_clause to_f, from_f for
add_clause transform for
def somefunc(x) do x end 

or similar i suppose is what I’m looking for? Not sure how i’ll get the stacking property to work on the definition. Maybe this is safer:

add_clause somefunc, to_f, from_f, 
add_clause somefunc, transform 
def somefunc(x) do x end 

and i just use convention to keep them close by so i’m not lost where the extra clauses are coming from.

dimitarvp

dimitarvp

That’s an error-prone format, I’d avoid it.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews