Getting name from "name"

Be aware that OP is not asking about parsing julia code. eval and Meta.parse will NOT be of help here. They’re trying to create their own programming language. Please don’t confuse the two.

Originally I was thinking you might want to use eval down the line after parsing and creating some Julia Expr. But now that I think about it you can probably avoid it entirely: parse the input language → execute functions. Maybe if you have structs and such you might want it as a near term solution.

Thanks for the suggestion!

For Julia take a look at shashi/APL.jl (github.com). It’s not a common language, but it might be helpful.

It is fun! If you’d like, I can send you the source code and documentation for your suggestions for improvement.

I’m certainly no expert, but I’d be happy to look and try it out! Any extra eyeballs on the code is always so helpful for me personally.

OK, here it is:

(Attachment jacl.txt is missing)

(Attachment jacl.jl is missing)

I’ll need your email address to send to you personally.

DM’ed

Again - you are confusing “parsing julia code” with " creating a new programming language that is not julia". Parsing text into julia code will not help you towards parsing non-julia code into a non-julia runtime and executing the result.

My language in just 10 lines :stuck_out_tongue_winking_eye: (Just have fun! Jupyter notebook)

t2j(s) = s
function t2j(s::Tuple)
    a = (:block, :if, :tuple, :parameters, :kw, :quote, :(=), :(.=), :.)
    s[1] in a && return Expr(s[1], t2j.(s[2:end])...)
    s[1] === :lambda && return Expr(:(->), Expr(:tuple, s[2]...), t2j(s[3]))
    s[1] === :for && return Expr(s[1], Expr(:(=), t2j(s[2]), t2j(s[3])), t2j(s[4]))
    s[1] === :using && return Expr(s[1], Expr.(:., s[2:end])...)
    Expr(:call, t2j.(s)...)
end
macro tupp(x) t2j(Core.eval(__module__, x)) end

I left all the trouble to Julia! (The name tupp might stand for “TUPle Processor”.)

Example 1: for loop and if statement

@tupp (:for, :k, (:(:), 1, 5),
    (:if, (:iseven, :k),
        (:println, "even: ", :k),
        (:println, "odd:  ", :k)))

Output:

odd:  1
even: 2
odd:  3
even: 4
odd:  5

Example2: Fibonacci numbers with U-combinator

@tupp (:block,
    (:(=), :U, (:lambda, (:u,), (:u, :u))),
    (:(=), :F, (:lambda, (:u,), (:lambda, (:n, :a, :b),
                (:if, (:(==), :n, 0), :a,
                    ((:u, :u), (:-, :n, 1), :b, (:+, :a, :b)))))),
    (:(=), :Fib, (:U, :F)),
    (:for, :k, (:(:), 1, 10),
        (:println, "Fib(", :k, ") = ", (:Fib, :k, 0, 1))))

Output:

Fib(1) = 1
Fib(2) = 1
Fib(3) = 2
Fib(4) = 3
Fib(5) = 5
Fib(6) = 8
Fib(7) = 13
Fib(8) = 21
Fib(9) = 34
Fib(10) = 55

t2j (tupp to Julia) exmaple:

(:block,
    (:(=), :U, (:lambda, (:u,), (:u, :u))),
    (:(=), :F, (:lambda, (:u,), (:lambda, (:n, :a, :b),
                (:if, (:(==), :n, 0), :a,
                    ((:u, :u), (:-, :n, 1), :b, (:+, :a, :b)))))),
    (:(=), :Fib, (:U, :F)),
    (:for, :k, (:(:), 1, 10),
        (:println, "Fib(", :k, ") = ", (:Fib, :k, 0, 1)))) |> t2j

Output:

quote
    U = ((u,)->u(u))
    F = ((u,)->((n, a, b)->if n == 0
                    a
                else
                    (u(u))(n - 1, b, a + b)
                end))
    Fib = U(F)
    for k = 1:10
        println("Fib(", k, ") = ", Fib(k, 0, 1))
    end
end

Example 3: Polynomial regression of y = \sin(\pi x)

@tupp (:block,
    (:using, :Plots),
    (:(=), :n, 20),
    (:(=), :x, (:range, 0, 2, (:kw, :length, :n))),
    (:(=), :y, (:+, (:., :sinpi, (:tuple, :x)), (:*, 0.2, (:randn, :n)))),
    (:(=), :xs, (:range, 0, 2, (:kw, :length, 200))),
    (:(=), :X, (:.^, :x, (:transpose, (:(:), 0, 3)))),
    (:(=), :b, (:\, :X, :y)),
    (:scatter, :x, :y, (:kw, :label, "sample")),
    (:plot!, :xs, (:., :sinpi, (:tuple, :xs)),
        (:kw, :label, "sinpi(x)"),
        (:kw, :color, (:quote, :black)),
        (:kw, :ls, (:quote, :dash))),
    (:plot!, :xs, (:., :evalpoly, (:tuple, :xs, (:Ref, :b))),
        (:kw, :label, "degree-3 polynomial"),
        (:kw, :color, 2), (:kw, :lw, 2)))

1 Like

Thanks for this! I can use your examples.

The symbol :name can be created from the string "name" with Symbol("name").

https://docs.julialang.org/en/v1/base/base/#Core.Symbol-Tuple

https://docs.julialang.org/en/v1/manual/metaprogramming/#Symbols

In general, you rarely need Meta.parse, and if you want to use Meta.parse, you’re probably thinking about something wrong. For example, instead of Meta.parse("1 + 1") you can use :(1 + 1) or Expr(:+, 1, 1).

No I’m not. I’m thinking of a quick method to implement a new language, whereby you parse your new language and essentially transpile to Julia Exprs. Such a language could look like anything, although Julia’s semantics could leak pretty easily into it.

1 Like

If you’ve looked at jacl.jl, you’ve noticed I write Julia like a C programmer. C is what I know well :wink:
I would appreciate any suggestions for improvement.