# Convert String to function name

**URL:** <https://discourse.julialang.org/t/convert-string-to-function-name/1547>\
**Category:** General Usage\
**Created:** [January 17, 2017, 3:36pm UTC](https://discourse.julialang.org/t/convert-string-to-function-name/1547 "2017-01-17T15:36:20Z")\
**Posts on this page:** 1\
**Showing post:** 30

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 25, 2023, 3:41pm UTC](https://discourse.julialang.org/t/convert-string-to-function-name/1547/30 "2023-12-25T15:41:07Z")

</div>

Here I post a script that tries to interpret expressions provided in the form of strings and constructs the “corresponding” functions.  
The problem comes from [here](https://discourse.julialang.org/t/multi-threading-with-dataframes/101859/33).  
But this post seems more suitable to host the (possible) discussion.

At the moment only some functions are “read” correctly.  
The aim was however to build a small calculator for some predefined functions.  
And in any case there is a case that causes the function that does the “parsing” to fail.  
I have idea how to work around the problem, but I would like to ask for someone’s suggestion to have a “cleaner” solution.

> **la piccola calcolatatrice**
>
> ```julia
> julia> df=Dict("log"=>log, "sin"=>sin, "*"=>*,"+"=>+,"-"=>-,"^"=>^, "∘"=>∘)
> Dict{String, Function} with 7 entries:
> "∘" => ∘
> "-" => -
> "log" => log
> "^" => ^
> "*" => *
> "+" => +
> "sin" => sin
> 
> julia> function splitpar(str)
> splitpos=[]
> cp=0
> for (i,c) in enumerate(str)
> cp= cp+(c=='(')-(c==')')
> c==','&& cp==0 && push!(splitpos,i)
> end
> splitpos
> end
> splitpar (generic function with 1 method)
> 
> julia> function splitinpos(s2s,pos)
> ss=String[]
> pos=[0;pos;length(s2s)+1]
> for i in (2:length(pos))
> push!(ss,s2s[pos[i-1]+1:pos[i]-1])
> end
> ss
> end
> splitinpos (generic function with 1 method)
> 
> julia> function str2func(str)
>        
> lff=findfirst('(', str)
> op=df[str[1:lff-1]]
> if !occursin('(',str[lff+1:end])     
> par=split(str[lff+1:end-1],',')  
> tp=tryparse.(Int,par)
> n=only(filter(!isnothing,tp))    
> return ((a...)->op(n,a...))      
> else
> s2s=str[lff+1:end-1]
> par=splitinpos(s2s,splitpar(s2s))
> return (x...)->op(
> [str2func(p)(x[indexin(intersect(join(vars), p),vars)]
> ...) for p in par]...)       
> end
> end
> str2func (generic function with 1 method)       
> 
> julia> vars=['x','y','z']
> 3-element Vector{Char}:
> 'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)
> 'y': ASCII/Unicode U+0079 (category Ll: Letter, lowercase)
> 'z': ASCII/Unicode U+007A (category Ll: Letter, lowercase)
> 
> julia> str3= "+(*(+(3,x),*(-2,y)),*(2,x),+(*(3,x),*(4,y)))"
> "+(*(+(3,x),*(-2,y)),*(2,x),+(*(3,x),*(4,y)))"
> 
> julia> str2func(str3)(1,-1)
> 9
> 
> julia> str4= "*(+(3,x),*(-2,z),*(1,x,z))"       
> "*(+(3,x),*(-2,z),*(1,x,z))"
> 
> julia> str2func(str4)(1,-1,2) #-32
> -32
> 
> julia> str5= "+(*(+(3,x),*(-2,y),*(1,x,z)),*(+(3,y),*(-2,z),*(1,x,z)))"
> "+(*(+(3,x),*(-2,y),*(1,x,z)),*(+(3,y),*(-2,z),*(1,x,z)))"
> 
> julia> str2func(str5)(1,-1,2) # 0
> 0
> 
> julia> str6= "+(*(+(3,x),*(-2,z),*(1,x)),*(+(3,y),*(-2,x),*(1,x,z)))"
> "+(*(+(3,x),*(-2,z),*(1,x)),*(+(3,y),*(-2,x),*(1,x,z)))"
> 
> julia> str2func(str6)(1,-1,2)
> ERROR: BoundsError: attempt to access Tuple{Int64, Int64} at index [3]
> Stacktrace:
> ---
> 
> # the operation *(-2,z) indexes the 'z' which is in the third position, but the group *(+(3,x),*(-2,z),*(1,x)) it only has two distinct variables. The same expression with *(1,y) instead of *(1,x) does not in fact raise the same problem-
> julia> str7= "+(*(+(3,x),*(-2,z),*(1,y)),*(+(3,y),*(-2,x),*(1,x,z)))"
> "+(*(+(3,x),*(-2,z),*(1,y)),*(+(3,y),*(-2,x),*(1,x,z)))"      
> 
> julia> str2func(str7)(1,-1,2)# 8
> 8
> 
> julia> 
> 
> ```

---

_[View the full topic](https://discourse.julialang.org/t/convert-string-to-function-name/1547)._
