# Julia. Strings and Metaprogramming

3r33877. 3r3-31. 3r33854. Lines

3r33855. 3r33877. 3r33854. String variables are created using a frame of characters in double quotes, single characters of the same type are defined as

char

. Concatenation of strings is performed using multiplication "*":

3r33855. 3r33877. 3r3822.

3r33855. 3r33877. 3r33854. String variables are created using a frame of characters in double quotes, single characters of the same type are defined as

char

. Concatenation of strings is performed using multiplication "*":

3r33855. 3r33877. 3r3822.

` cats = 4`

s1 = "How many cats"; 3r33877. s2 = "is too many cats?"; 3r33877. s3 = s1 * s2

3r33877. Out[]: "How many cats are too many cats?" 3r33850. 3r33851. 3r33855. 3r33877. 3r33854. That is, the exponentiation works like this:

3r33855. 3r33877. 3r3822. ` s1 ^ 3`

Out[]: "How many cats How many cats"

3r33851. 3r33855. 3r33877. 3r33854. On the other hand, indexing is extended to strings: 3r33865. 3r33855. 3r33877. 3r3822. ` s1[3]3r33877. Out[]: 'w': ASCII /Unicode U + 0077 (category Ll: Letter, lowercase) 3r37777. 3r33877. s1[5:13]3r33877. Out[]: "many cats"`

3r33877. s1[13:-1:5]3r33877. Out[]: "stac ynam"

3r33877. s2[end]3r33877. Out[]: '?': ASCII /Unicode U + 003f (category Po: Punctuation, other)

3r33851. 3r33855. 3r33877. 3r33854. Strings can be created from strings and other types: 3r33865. 3r33855. 3r33877. 3r3822. ` s4 = string (s? "- I don't know, but", cats, "is too few.") 3r33877. # or so s4 = "$ s3 - I don't know, but $ cats is too few." 3r33877. 3r33877. Out[]: "How many cats are too many cats? - I don't know, but 4 is too few." 3r33850. 3r33851. 3r33855. 3r33877. 3r33854. In the arsenal there are many all sorts of useful features r3r3864. For example, the search element:`

3r33855. 3r33877. 3r3822. ` findfirst (isequal ('o'), s4)`

Out[]: 4 3r37777. 3r33877. findlast (isequal ('o'), s4)

Out[]: 26 3r3r777. 3r33877. findnext (isequal ('o'), s? 7) # look for a match after the seventh element

Out[]: 11 rr350. 3r33851. 3r33855. 3r33877. 3r33854. And this is how you can easily implement

Caesar cipher

` 3r33865. 3r33855. 3r33877. 3r3822. `` caesar (X, n) = prod ([x += n for x in X]) 3r37777. 3r33877. str3 = "hatifnatty are vicious lifestyle"; 3r33877. 3r33877. caesar (str? 3)`

Out[]: "Shghlchrghhyu # eizkhh # tsusyryum # sudgk # ylkrl"

3r33877. str4 = caesar (str? -32)

Out[]: "KhATIFNATTY877. 3r3822. ` eval (Meta.parse (ans))`

Out[]: 42 3r350. 3r33851. 3r33855. 3r33877. 3r33854. Why all these difficulties? The trick is that when we have

expression

, we can modify it in various interesting ways: 3r33838. 3r33855. 3r33877. 3r3822. ` x = replace (x, "*" => "+")`

eval (Meta.parse (x)) 3r33877. Out[]: 13 3r350. 3r33851. 3r33855. 3r33877. 3r33854. To avoid messing around with strings, an operator of a gloomy face is provided for ` :() 3r33850. 3r33865. 3r33855. 3r33877. 3r3822. `` y =: (2 ^ 8-1)`

Out[]::: (2 ^ 8-1)

3r33877. eval (y)

Out[]: 255 r3r3877. 3r33850. 3r33851. 3r33855. 3r33877. 3r33854. You can "quote" an expression, function, code block 3r33838. 3r33855. 3r33877. 3r3822. ` quote`

x = 2 + 2

hypot (x, 5)

end

3r33877. Out[]: quote

# = In[13]: 2 = #

x = 2 + 2

# = In[13]: 3 = #

hypot (x, 5)

end

3r33877. : (function mysum (xs)

sum = 0

for x in xs

sum + = x

end

end)

3r33877. Out[]:: (function mysum (xs)

# = In[14]: 2 = #

sum = 0

# = In In[14]: 3 = #

for x = xs

# = In[14]: 4 = #

Sum + = x

End

End)

3r33851. 3r33855. 3r33877. 3r33854. And now let's parse the previously calculated matrix (it is better to start a new session after the previous section, my ugly overloads could easily conflict with the connected packages): 3r33865. 3r33855. 3r33877. 3r3822. ` X =["cos(ϕ)"`

"sin(ϕ)"

0

0;

"cos(ϕ)*(-sin(ϕ))"

"cos(ϕ)*(cos(ϕ))"

"sin(ϕ)" 0;

"-sin(ϕ)*(-sin(ϕ))" "-sin(ϕ)*(cos(ϕ))"

"cos(ϕ)" 0;

"x0"

"y0"

"z0"

1; ]3r33877. 3r33877. for i = 1: size (X, 1), j = 1: size (X, 2)

if typeof (X[i,j]) == String

X[i,j]= Meta.parse (X[i,j])

end

end

X 3r3r777 3r33877. Out[]: 4 × 4 Array {Any, 2}:

: (cos (ϕ)): (sin (ϕ)) ???r3r3877. : (cos (ϕ) * - (sin (ϕ))): (cos (ϕ) * cos (ϕ)): (sin (ϕ)) 0

: (- (sin (ϕ)) * - (sin (ϕ))): (- (sin (ϕ)) * cos (ϕ)): (cos (ϕ)) 0

: x0: y0: z???r3r3850. 3r33851. 3r33855. 3r33877. 3r33854. As some have guessed, this is a transformation matrix, we are already 3r3-3534. This is taken apart , only now for three-dimensional coordinates. We will carry out the calculation for specific values: 3r33855. 3r33877. 3r3822. ` ϕ = 20 * pi /180`

x0 = 4

y0 = -???r3r3877. z0 = ???r3r3877. 3r33877. Xtr =[eval(x) for x in X]3r33877. 3r33877. Out[]: 4 × 4 Array {Real, 2}:

???.???

-???.??? 0

???-???.???r3r3877. 4 -???.???r3r3850. 3r33851. 3r33855. 3r33877. 3r33854. This matrix produces a rotation around the ** axes. X 3r3-3560. and 3r33559. Z 3r3-3560. on 3r33714. 3r? 3562. 3r33737. and carry over to r3r3714. 3r33565. 3r33737. 3r33865. 3r33855. 3r33877. 3r3822. **` x =[-1 -1 1 1 -1 -1 1 1 -1 -1]; 3r33877. y =[-1 -1 -1 -1 -1 1 1 1 1 -1]; 3r33877. z =[1 -1 -1 1 1 1 1 -1 -1 -1]3r33877. R =[x' y' z' ones( length(x) ) ]3r33877. plot (x ', y', z ', w = 3) `

3r33851. 3r33855. 3r33877. 3r33854. R2 = R * Xtr

plot! (R2[:,1], R2[:,2], R2[:,3], w = 3)

3r33851. 3r33855. 3r33877. 3r33854. 3r? 3593. 3r33865. 3r33855. 3r33877. 3r? 3597. Fruit of the Expression Tree 3r33855. 3r33877. 3r33854. As we’ve found out, strings support “interpolation”, which allows us to easily create large strings from smaller components. 3r33865. 3r33855. 3r33877. 3r3822. ` x = "million"`

print ("$ x $ x $ x red roses ")

3r33877. Out[]: million million million scarlet roses

3r33851. 3r33855. 3r33877. 3r33854. With quotes (quotes) - the same story: 3r33865. 3r33855. 3r33877. 3r3822. ` x =: (6 * 7)`

y =: ($ x + $ x)

Out[]:: (6 * 7 + 6 * 7)

3r33877. eval (y)

Out[]: 84 3r350. 3r33851. 3r33855. 3r33877.

` The Root of All Eval `

` The Root of All Eval `

` 3r33855. 3r33877. 3r33854. 3r33737. eval () 3r33850. not only returns the value of the expression. Let's try to quote the function declaration: 3r33855. 3r33877. 3r3822. `` ex = :( cats () = println ("Meow!"))`

cats () 3r37777. 3r33877. Out[]: UndefVarError: cats not defined

3r33851. 3r33855. 3r33877. 3r33854. And now we will revive her: 3r33855. 3r33877. 3r3822. ` eval (ex)`

Out[]: cats (generic function with 1 method) 3r3r777. 3r33877. cats () 3r37777. Out[]: Meow! 3r33850. 3r33851. 3r33855. 3r33877. 3r33854. Using interpolation, we can construct the definition of a function on the fly; in fact, we can immediately do a number of functions. 3r33865. 3r33855. 3r33877. 3r3822. ` for name in[:dog, :bird, :mushroom]3r33877. println (: ($ name () = println ($ ("I'm $ (name)!")))`

end

3r33877. Out[]: dog () = begin

# = In[27]: 2 = #

println ("i'm dog!")

end

bird () = begin

# = In[27]: 2 = #

println ("I'm a bird!")

end

mushroom () = begin

# = In[27]: 2 = #

println ("I'm mushroom!")

end

3r33877. for name in[:dog, :bird, :mushroom]3r33877. eval (: ($ name () = println ($ ("I'm $ (name)!")))

end

3r33877. dog () 3r33877. Out[]: I'm a dog! 3r33877. 3r33877. mushroom ()

Out[]: I'm mushroom! 3r33850. 3r33851. 3r33855. 3r33877. 3r33854. This can be extremely useful when wrapping an API (say, from the C library or via HTTP). APIs often define a list of available functions, so you can grab them and create an entire shell at once! See Examples Clang.jl, TensorFlow.jl or basic linear algebra. 3r33865. 3r33855. 3r33877. 3r33737. Original sin 3r3702. 3r33855. 3r33877. 3r33854. Here is a more practical example. Consider the following definition of the function ` sin () `

based on taylor series: 3r33865. 3r33855. 3r33877. 3r33854. 3r33865. 3r33854. 3r33714. 3r33737. 3r33737. 3r33865. 3r33855. 3r33877. 3r3822. ` mysin (x) = sum ((- 1) ^ k /factorial (1 + 2 * k) * x ^ (1 + 2k) for k = 0: 5)`

mysin (0.5), sin (0.5)

3r33877. Out[]: (???? ???)

3r33877. using BenchmarkTools

@benchmark mysin (0.5)

3r33877. Out[]: BenchmarkTools.Trial:

memory estimate: 112 bytes

allocs estimate: 6

--------------

minimum time: ??? μs (???% GC)

median time: ??? μs (???% GC)

Mean time: ??? μs (???% GC)

maximum time: ??? μs (???% GC)

--------------

samples: 10000 r3r3877. evals /sample: 10 r3r3850. 3r33851. 3r33855. 3r33877. 3r33854. Now it is much slower than it could be. The reason is that we iterate over k, which is relatively expensive. Explicit recording is much faster: 3r33855. 3r33877. 3r3822. ` mysin (x) = x - x ^ 3/6 + x ^ 5/120 # + 3r350. 3r33851. 3r33855. 3r33877. 3r33854. But it's tedious to write and no longer looks like the original Taylor series. In addition, there is a high risk of ochepyakok. Is there a way to kill a hare with two shots? How about Julia writing us this code? To begin, consider the symbolic version of the + function. 3r33865. 3r33855. 3r33877. 3r3822. `` plus (a, b) =: ($ a + $ b)`

plus (? 2)

3r33877. Out[]::: (1 + 2)

3r33851. 3r33855. 3r33877. 3r33854. From 3r33768. plus ()

we can do many interesting things, for example, the symbolic sum: 3r33855. 3r33877. 3r3822. ` reduce (+ 1:10)`

Out[]: 55 3r37777. 3r33877. reduce (plus, 1:10)

Out[]:: ((((((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9) + 10) 3r33877. 3r33877. eval (ans)

Out[]: 55 3r37777. 3r33877. reduce (plus,[:(x^2), :x, 1])

Out[]:: ((x ^ 2 + x) + 1) 3r3-3850. 3r33851. 3r33855. 3r33877. 3r33854. This gives us an important piece of the puzzle, but we also need to figure out what we summarize. Let's create a symbolic version of the Taylor series above, which interpolates the value of k. 3r33865. 3r33855. 3r33877. 3r3822. ` k = 2 r3r3877. : ($ ((- 1) ^ k) * x ^ $ (1 + 2k) /$ (factorial (1 + 2k))) 3r3r777. Out[]:: ((1 * x ^ 5) /120) 3r3-3850. 3r33851. 3r33855. 3r33877. 3r33854. Now you can rivet the elements of a row like on a conveyor: 3r33865. 3r33855. 3r33877. 3r3822. `` terms =[:($((-1)^k) * x^$(1+2k) /$(factorial(1+2k))) for k = 0:5]3r33877. Out[]: 6-element Array {Expr, 1}:`

: ((1 * x ^ 1) /1) 3r33877. : ((- 1 * x ^ 3) /6) 3r33877. : ((1 * x ^ 5) /120) 3r33877. : ((- 1 * x ^ 7) /5040)

: ((1 * x ^ 9) /362880)

: ((- 1 * x ^ 11) /39916800) r3r3850. 3r33851. 3r33855. 3r33877. 3r33854. And to summarize them: 3r33855. 3r33877. 3r3822. ` reduce (plus, ans)`

Out[]:: (((((((1 * x ^ 1) /1 + (-1 * x ^ 3) /6) + (1 * x ^ 5) /120) + (-1 * x ^ 7) /5040 ) + (1 * x ^ 9) /362880) + (-1 * x ^ 11) /39916800) 3r37777. 3r33877. : (mysin (x) = $ ans)

3r33877. Out[]:: ((mysin (x) = begin

# = In[52]: 1 = #

(((((1 * x ^ 1) /1 + (-1 * x ^ 3) /6) + (1 * x ^ 5) /120) + (-1 * x ^ 7) /5040) + (1 * x ^ 9) /362880) + (-1 * x ^ 11) /39916800

end)

3r33877. eval (ans)

mysin (0.5), sin (0.5)

Out[]: (???? ???)

3r33877. @benchmark mysin (0.5)

3r33877. Out[]: BenchmarkTools.Trial:

memory estimate: 0 bytes

allocs estimate: 0

--------------

minimum time: ??? ns (???% GC)

median time: ??? ns (???% GC)

Mean time: ??? ns (???% GC)

maximum time: ??? μs (???% GC)

--------------

samples: 10000 r3r3877. evals /sample: 201

3r33851. 3r33855. 3r33877. 3r33854. Not bad for a naive implementation! The photon will not have time to run one and a half hundred meters, and the sine is calculated! 3r33855. 3r33877. This is the time to finish. For those who want to continue exploring this topic I will recommend interactive tutorial executable in Jupyter , the translation of which was mostly used here, 3r33859. video course

from the official website, and 3r33861. The corresponding section is 3r36464. documentation. For only arrivals, I advise you to go for 3r33863. Hub 3r33864. , the benefit here is already an acceptable amount of materials. 3r33865. 3r33873. 3r33877. 3r33877. 3r33877. 3r33838. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o -;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r33871. 3r33877. 3r33873. 3r33877. 3r33877. 3r33877. 3r33877.