# How to "source" a string?

**URL:** <https://discourse.julialang.org/t/how-to-source-a-string/52643>\
**Category:** New to Julia\
**Created:** [December 31, 2020, 5:30am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643 "2020-12-31T05:30:08Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [December 31, 2020, 5:30am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/1 "2020-12-31T05:30:08Z")

</div>

I have 2 functions that are highly similar, except that there’s a block of codes appears only in one of the functions.  
For example, something like:

```julia
function fun()
  XXXXXX
  XXXXXX

  YYYYYY
  YYYYYY
end

function gun()
  XXXXXX
  XXXXXX

  ZZZZZZ # the extra block of codes
  ZZZZZZ

  YYYYYY
  YYYYYY
end

```

I want to **factorize the functions** by defining two strings, and then “source” them inside the functions like:

```julia
str1 = "XXXXXX
        XXXXXX"

str2 = "YYYYYY
        YYYYYY"

function fun()
  source(str1)
  source(str2)
end

function gun()
  source(str1)
  ZZZZZZ
  ZZZZZZ
  source(str2)
end

```

the above “`source()`” works like **string interpolation**. how to do it in `Julia`?

Noted that `include()` not work as it involves **evaluation** of the string.

On the other hand, defining sub-function also not work as it would create local variables that are not reachable by the other sub-functions…

thanks.

---

<div class="post-metadata">

**Author:** ![danielw2904](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielw2904/32/10890_2.png) [@danielw2904](https://discourse.julialang.org/u/danielw2904)\
**Post date:** [December 31, 2020, 5:59am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/2 "2020-12-31T05:59:57Z")

</div>

I think what you are looking for is `Meta.parse` to convert the string to an expression and `eval` to run it

See: [Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/)

---

<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:** [December 31, 2020, 6:05am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/3 "2020-12-31T06:05:48Z")

</div>

Lots of the answer is that you definitely shouldn’t be using strings for this. Instead, (if meta-programming is the answer), you should be using expressions instead of strings.

---

<div class="post-metadata">

**Author:** ![danielw2904](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielw2904/32/10890_2.png) [@danielw2904](https://discourse.julialang.org/u/danielw2904)\
**Post date:** [December 31, 2020, 6:09am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/4 "2020-12-31T06:09:31Z")

</div>

Maybe you could also define “XXX…” “YYY…” and “ZZZ…” as functions and then use them within the two functions as needed.

---

<div class="post-metadata">

**Author:** ![thautwarm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thautwarm/32/37760_2.png) [@thautwarm](https://discourse.julialang.org/u/thautwarm)\
**Post date:** [December 31, 2020, 6:43am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/5 "2020-12-31T06:43:26Z")

</div>

I don’t think it a good approach to use strings for code reuse, but you can still do it in this way.

```julia
macro source(str)
  str |>
  __module__.eval |> # evaluate macro arguments in top level
  Meta.parse |> # it should be a string, parse it to Julia Expr
  esc # do not rename symbols in the Expr
end

str = "a + 1"
function f(a)
   @source(str) # equals to `a + 1`
end

```

---

<div class="post-metadata">

**Author:** ![purplishrock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/purplishrock/32/13451_2.png) [@purplishrock](https://discourse.julialang.org/u/purplishrock)\
**Post date:** [December 31, 2020, 6:49am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/6 "2020-12-31T06:49:24Z")

</div>

> [@tomtom](#):
>
> On the other hand, defining sub-function also not work as it would create local variables that are not reachable by the other sub-functions…

yes, but you can define the functions locally to a function and then share variables within that function, e.g.

```julia
function one()
 x= 5
 y= 7
 function two()
   # x , y are visible
 end
function three_a()
  # the same x,y are visible
end
function three_b()
  # the same x,y are visible
end
function four()
 # etc...
end

function combo1()
  two()
  three_a()
  four()
end

function combo2()
  two()
  three_b()
  four()
end

combo1()
combo2()
 
end
```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [December 31, 2020, 9:58am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/7 "2020-12-31T09:58:48Z")

</div>

Thanks for all replies!

@thautwarm’s answer is “my” solution: it works perfectly with local variables. It has no running cost penalty and no warntype also.

```julia
function fun(x, y)
  z = 2x + y # block A
  z *= 3 # block B
  return z
end

function gun(x, y)
  z = 2x + y # block A
  z -= 5 # the extra block of codes
  z *= 3 # block B
  return z
end

const strA = "z = 2x + y"
const strB = "z *= 3"
function fun1(x, y)
    @source(strA)
    @source(strB)
    return z
end

function gun1(x, y)
    @source(strA)
    z -= 5 # the extra block of codes
    @source(strB)
    return z
end

julia> fun(1, 2)
12
julia> fun1(1, 2)
12

julia> gun(1, 2)
-3
julia> gun1(1, 2)
-3

@code_warntype fun(1, 2)
@code_warntype fun1(1, 2)
@code_warntype gun(1, 2)
@code_warntype gun1(1, 2)

julia> @btime fun($1, $2);
  0.022 ns (0 allocations: 0 bytes)
julia> @btime fun1($1, $2);
  0.022 ns (0 allocations: 0 bytes)

julia> @btime gun($1, $2);
  0.021 ns (0 allocations: 0 bytes)
julia> @btime gun1($1, $2);
  0.021 ns (0 allocations: 0 bytes)

```

On the other hand, I think a “proper” solution is to define a function for each re-using block. But we have to **carefully** _pass in any needed locals as arguments_ and _return any locals that are needed in later codes_. For example:

```julia
function _blockA(x, y)
    z = 2x + y
    return z
end

function _blockB(z)
    z *= 3
    return z
end

function fun2(x, y)
    z = _blockA(x, y) # NEED to pass in x & y AND return z
    z = _blockB(z) # NEED to pass in and return z
    return z
end

function gun2(x, y)
    z = _blockA(x, y)
    z -= 5 # the extra block of codes
    z = _blockB(z)
    return z
end

@code_warntype fun2(1, 2)
@code_warntype gun2(1, 2)

julia> @btime fun2($1, $2);
  0.022 ns (0 allocations: 0 bytes)
julia> @btime gun2($1, $2);
  0.022 ns (0 allocations: 0 bytes)

```

@purplishrock has a clever suggestion, but it’s not working if the two highly-similar functions are to be called in different times.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 31, 2020, 10:02am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/8 "2020-12-31T10:02:25Z")

</div>

> [@tomtom](#):
>
> would create local variables that are not reachable by the other sub-functions…

Function parameters and return values are for that. You are probably not using the correct approach. I think one can bet without risk that the “sourcing” of strings is not used at all in any of the important Julia packages.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [December 31, 2020, 10:35am UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/9 "2020-12-31T10:35:40Z")

</div>

Please, just use functions. There is no need for any metaprogramming/parse/eval magic here. The mere fact that you couldn’t come up with a fancy macro for this should tell you that you shouldn’t go down this road. In particular because there is a super simple alternative: functions. Bundling code for (multiple) reuse is **the** central purpose of functions!

I go even further than @lmiq: If you need to parse/eval a string you are almost always doing it wrong. Not just in Base or Julia but in general 🙂

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 31, 2020, 12:24pm UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/10 "2020-12-31T12:24:06Z")

</div>

> [@tomtom](#):
>
> the other hand, I think a “proper” solution is to define a function for each re-using block. But we have to **carefully** _pass in any needed locals as arguments_ and _return any locals that are needed in later codes_ .

This **is the proper solution** , without quotes. And that careful passing of parameters and return values is what makes the function reusable. Otherwise you don’t know what the code expects to use, and what it returns as a result, which variables it modifies, you very rapidly would have a code impossible to maintain.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [December 31, 2020, 1:06pm UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/11 "2020-12-31T13:06:13Z")

</div>

One solution that I don’t think has been mentioned yet: using higher-order functions (HOF). In my experience, it is frequently the case that most of the code can be factored out, and only a small part of it needs to change. It can then be beneficial to factor out the large, common parts in a higher-order function; the small, “extra” part can then be passed as a function argument to the HOF.

Minimal example:

```julia
# A higher-order function to factor out all common code
julia> function common_parts(extra, x, y)
           z = 2x + y # block A
           z = extra(z) # extra block
           z *= 3 # block B
       end
common_parts (generic function with 1 method)

# No extra part: z = identity(z)
julia> fun(x, y) = common_parts(identity, x, y)
fun (generic function with 1 method)

# I tend to like the `do` block better, but you could also write
# gun(x, y) = common_parts(z -> z-5, x, y)
julia> gun(x, y) = common_parts(x, y) do z
           z - 5
       end
gun (generic function with 1 method)

julia> fun(1, 2)
12

julia> gun(1, 2)
-3

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [December 31, 2020, 1:32pm UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/12 "2020-12-31T13:32:31Z")

</div>

@lmiq, @carstenbauer all u said are absolutely correct, in theory at least.

Imagine, block A and block B **share tons of local variables** : it would make properly defining functions for them **really painful**.

In practice, the solution by @ffevotte is quite genius I think.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 31, 2020, 1:56pm UTC](https://discourse.julialang.org/t/how-to-source-a-string/52643/13 "2020-12-31T13:56:55Z")

</div>

Then you should use a data structure. The `do` syntax is a nice way to pass an anonymous function as a parameter, and `z` there is the parameter of that anonymous function, thus it does not solve the problem of the “tons of locals”.

Never a code that depends on many variables will be easier to maintain if those variables can be arbitrarily modified in different files with unpredictable effects on independent chunks of code. That will be worse the more variables you have.
