# "using" as a function?

**URL:** <https://discourse.julialang.org/t/using-as-a-function/48462>\
**Category:** General Usage\
**Created:** [October 15, 2020, 9:48pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462 "2020-10-15T21:48:25Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![RodBiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rodbiren/32/16979_2.png) [@RodBiren](https://discourse.julialang.org/u/RodBiren)\
**Post date:** [October 15, 2020, 9:48pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/1 "2020-10-15T21:48:25Z")

</div>

I am messing around with Pluto and decided I would like a shorter way of importing libraries. This question is sort of two fold. How can I dynamically import Modules using a macro or something else? And why is _ **using** _ a keyword a not a function? I suppose this could go into the Julia internals subject, but this just struck me as strange.

What I would like to do.

```julia
using Pkg
pkgs = ["HTTP","DataFrames","CSV"]
Pkg.add(pkgs)
using.(pkgs)

```

I understand this is probably something that I should just overlook, but I found it a good chance to try and learn macros, but I only got close to what i wanted.

```julia
 function toLine(arr)
	out = ""
	for i in 1:1:length(arr)
		if i == length(arr)
			out *= arr[i]
		else
			out *= arr[i] * ", "
		end
	end
	return out
end
macro useit(libs)
	return Meta.parse("using " * toLine(libs))
end
@useit(pkgs)
LoadError: MethodError: no method matching length(::Symbol)
Closest candidates are:
length(!Matched::Core.MethodTable) at reflection.jl:957
length(!Matched::CompositeException) at task.jl:41
length(!Matched::Base.Iterators.Flatten{Tuple{}}) at iterators.jl:1061

```

I’m sure I could do it with a macro, I was just curious if anyone knew if there is a function for this or a way of calling “using” that makes this work. I just noted that it was strange I could add Packages using a variable, but not easily “using” the Modules.

So much stuff is a function I am confused as to why using would be something special.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 15, 2020, 10:09pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/2 "2020-10-15T22:09:02Z")

</div>

There’s no need for a macro here–if you want a function that has the same effect as `using` at the top level, then it’s as simple as:

```julia
julia> function my_using(x)
         @eval using $(Symbol(x))
       end
my_using (generic function with 1 method)

julia> pkgs = ["LinearAlgebra", "Random"]
2-element Array{String,1}:
 "LinearAlgebra"
 "Random"

julia> my_using.(pkgs)

```

> [@RodBiren](#):
>
> And why is _ **using** _ a keyword a not a function?

`using` has side-effects (bringing names into scope) which would be very surprising for a function. If you run `foo()` you do not expect the name `bar` to suddenly appear in global scope.

By the way, if you’re looking to learn more about using macros, I would suggest that you stick to a simple rule of thumb:

Never use `Meta.parse`, `eval`, or string concatenation in a macro or in any function used by a macro.

Of course all rules have exceptions, but this is a pretty good guideline to live by when dealing with metaprogramming in Julia. Item by item, the reasons are:

- You should not need `Meta.parse` in a macro because a macro _already_ receives a parsed Julia expression. Just use the `Expr` that the macro received and operate directly on that expression.
- You should not need `eval` in a macro because a macro produces code which will eventually be run. If your macro works with the value of some function `f()`, then it should produce code which calls `f()` rather than trying to `@eval(f())` inside the macro body. The reason is that macro expansion happens when the code is lowered, which is almost never the right time to be calling other functions.
- You should not need string concatenation because Julia has better tools (like `Expr`) for representing expressions. Instead of concatenating strings, you can `push!` into `expr.args`. This avoids _all_ of the issues like syntax errors or missing escaping of spaces or commas which are all-too-common in lesser macro systems like C/C++.

---

<div class="post-metadata">

**Author:** ![RodBiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rodbiren/32/16979_2.png) [@RodBiren](https://discourse.julialang.org/u/RodBiren)\
**Post date:** [October 15, 2020, 10:44pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/3 "2020-10-15T22:44:26Z")

</div>

That makes utter sense and is highly appreciated. I suffer from not understanding meta programming yet and am an amateur programmer. I started with cpp and have just picked up the hobby of checking out languages. Julia is really interesting, like a glue language. Anyways, thanks for the well reasoned and thought out answer!

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 15, 2020, 10:48pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/4 "2020-10-15T22:48:01Z")

</div>

Can we get this answer turned intoa thing that is really easy to link? I feel like someone has to give this answer about one a week.

---

<div class="post-metadata">

**Author:** ![timquelch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timquelch/32/18278_2.png) [@timquelch](https://discourse.julialang.org/u/timquelch)\
**Post date:** [October 15, 2020, 11:16pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/5 "2020-10-15T23:16:58Z")

</div>

> [@rdeits](#):
>
> - You should not need string concatenation because Julia has better tools (like `Expr` ) for representing expressions. Instead of concatenating strings, you can `push!` into `expr.args` . This avoids _all_ of the issues like syntax errors or missing escaping of spaces or commas which are all-too-common in lesser macro systems like C/C++.

Just to clarify the bit about avoiding string concatenation: Does this apply only to modifying julia code strings (which would then be parsed), or does this apply to string concatenation in general?

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 15, 2020, 11:37pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/6 "2020-10-15T23:37:52Z")

</div>

I’m pretty sure he’s just talking about using it for building string representations of code.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 15, 2020, 11:50pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/7 "2020-10-15T23:50:44Z")

</div>

In principle also applies if you are parsing the result of string manipulation into some structure, even if the parsing result isn’t julia code. Case in point, don’t use string manipulation to construct a `JSON` string just to parse it immediately (if you are doing that to pass it to javascript that’s probably the best you can do so that’s fine). Obviously string manipulation is still useful and you should use it when you need a string.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 16, 2020, 8:59am UTC](https://discourse.julialang.org/t/using-as-a-function/48462/8 "2020-10-16T08:59:13Z")

</div>

> [@rdeits](#):
>
> Never use `Meta.parse` , `eval` , or string concatenation in a macro or in any function used by a macro.

Excellent writeup, please consider making a PR to the docs, eg as a FAQ.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 16, 2020, 12:45pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/9 "2020-10-16T12:45:57Z")

</div>

> [@timquelch](#):
>
> Does this apply only to modifying julia code strings (which would then be parsed), or does this apply to string concatenation in general?

Yeah, @Mason is right–I mean avoid concatenating strings to build Julia code. It’s still fine to concatenate `"hello"` and `"world"` if your problem requires it 🙂

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [October 16, 2020, 12:47pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/10 "2020-10-16T12:47:05Z")

</div>

Also, if you are adding packages in a script, you should really be using a `Project.toml` and a `Manifest.toml` along with `] instantiate`.

---

<div class="post-metadata">

**Author:** ![RodBiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rodbiren/32/16979_2.png) [@RodBiren](https://discourse.julialang.org/u/RodBiren)\
**Post date:** [October 16, 2020, 1:24pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/11 "2020-10-16T13:24:47Z")

</div>

It was mainly something I wanted to do for a Pluto project. Not sure if there was a way of using Project or Manifest for that.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 16, 2020, 1:32pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/12 "2020-10-16T13:32:09Z")

</div>

A Pluto project is just a regular julia Project - all code is stored in `src` and its has a `Project.toml` and `Manifest.toml` 🙂

---

<div class="post-metadata">

**Author:** ![ctkelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ctkelley/32/10684_2.png) [@ctkelley](https://discourse.julialang.org/u/ctkelley)\
**Post date:** [October 16, 2020, 1:32pm UTC](https://discourse.julialang.org/t/using-as-a-function/48462/13 "2020-10-16T13:32:49Z")

</div>

I am a very slow learner about macros. I had a macro that added a seldom-used directory to my LOAD\_PATH with eval. I was only calling this thing from the REPL and notebooks. I thought it had to be a macro, but making it a function worked as well.

@Oscar_Smith says, "I feel like someone has to give this answer about one a week.‘’, but some of us need to see it several times before it sinks in.
