eksperimental

eksperimental

Is there a way to conditionally import a function, but make the import available outside the if or case?

this obviously works:

  def foo() do
    import Enum, only: [map: 2]

    map(1..5, &IO.inspect(&1))
  end

this works as well:

    if is_integer(term) do
      import Enum, only: [map: 2]
      map(1..term, &IO.inspect(&1))
    end

this does not work due to lexical scope.

    if true do
      import Enum, only: [map: 2]
    end
  
    map(1..integer, &IO.inspect(&1))

So far so good.
My question is, how can we import conditionally at runtime, and make the import available outside the condition clause.

The only solution that I thought it could make it work was this, it does not and it baffles me.:

    true && (import Enum, only: [map: 2])
    map(1..integer, &IO.inspect(&1))

Note: for my use case I can solve this by running the condition at compile time, but I am just trying to understand how to do it at runtime.

Thank you

Showing Posts 1 to 6

ityonemo

ityonemo

Imports are compile-time.

dimitarvp

dimitarvp

Elixir being FP I don’t see any other way except closures or just passing a function like so

defmodule Helper
  if compile_time_condition do
    def with_scope(fun) do
      import Enum
      fun.()
    end
  else
    def with_scope(fun) do
      import Stream
      fun.()
    end
  end
end

Or you can do it with a keyword list parameter with :do and :else like the if macro does.

LostKobrakai

LostKobrakai

That’s what I’d do, which seems a lot cleaner than conditionally importing things.

mod = if condition, do: Stream, else: Enum
mod.map(1..integer, &IO.inspect(&1))
eksperimental

eksperimental OP

This is pretty much what i am doing.
It is for a BackPort module, where I give support for older Elixir versions importing functions/macros based on macro_exported?(Kernel, :macro_name, :arity)

It still baffles me why using && will not work.

macro_exported?(Kernel, :is_struct, 2) && (import BackPort, :is_struct, 2)

I have not read && creating a lexical scope within itself.

al2o3cr

al2o3cr

The behavior makes sense if you look at the implementation:
https://github.com/elixir-lang/elixir/blob/74bfab8ee271e53d24cb0012b5db1e2a931e0470/lib/elixir/lib/kernel.ex#L3791-L3803

The right-hand expression in && winds up inside a case statement, so the import does not leak out.

eksperimental

eksperimental OP

@al2o3cr you are so right! I wrongly assumed that it was &&/2 was inlined by the compiler. I guess it all comes down to this, anyway had it been, it would have been the same:

:erlang.andalso(true, (import Enum, only: [map: 2]))
map(1..integer, &IO.inspect(&1))

because this seems to work the same way.

So I guess the only option here is evaluating the condition at compile time.

Thank you all guys for your contributions.

— 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
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
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
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
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
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
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
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
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