{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# MetaUtils\n", "\n", "* Author: Gen Kuroki\n", "* Date: 2020-10-11~2020-10-17, 2021-03-20~2021-03-26, 2021-06-07\n", "* Repository: https://github.com/genkuroki/MetaUtils.jl\n", "* File: https://nbviewer.jupyter.org/github/genkuroki/MetaUtils.jl/blob/master/MetaUtils.ipynb" ] }, { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "

Table of Contents

\n", "
" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "v\"1.7.0-DEV.1133\"" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "VERSION" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[32m\u001b[1m Activating\u001b[22m\u001b[39m project at `C:\\Users\\genkuroki\\OneDrive\\work\\MetaUtils.jl`\n" ] } ], "source": [ "if isfile(\"Project.toml\")\n", " using Pkg\n", " Pkg.activate(\".\")\n", " using Revise\n", "end" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "using MetaUtils" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Explanatory examples" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:call, :+, (:call, :*, 2, :x), 1)" ] } ], "source": [ "@show_sexpr 2x+1" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "21" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 10; (:call, :+, (:call, :*, 2, :x), 1) |> teval" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:call)\n", "├─ :+\n", "├─ Expr(:call)\n", "│ ├─ :*\n", "│ ├─ 2\n", "│ └─ :x\n", "└─ 1\n" ] } ], "source": [ "@show_tree 2x+1" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:call)\n", "├─ :+\n", "├─ Expr(:call)\n", "│ ├─ :*\n", "│ ├─ 2\n", "│ └─ :x\n", "└─ 1\n" ] } ], "source": [ "show_tree(:(2x + 1))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AbstractRange\n", "├─ LinRange\n", "├─ OrdinalRange\n", "│ ├─ AbstractUnitRange\n", "│ │ ├─ Base.IdentityUnitRange\n", "│ │ ├─ Base.OneTo\n", "│ │ ├─ Base.Slice\n", "│ │ └─ UnitRange\n", "│ └─ StepRange\n", "└─ StepRangeLen\n" ] } ], "source": [ "print_subtypes(AbstractRange)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:call, :f, :x, \n", " Expr(:call, :g, :y, :z))" ] } ], "source": [ "show_expr(:(f(x, g(y, z))))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:call, :+, \n", " Expr(:call, :*, 2, :x), 1)" ] } ], "source": [ "@show_expr 2x+1" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "21" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 10; Expr(:call, :+, \n", " Expr(:call, :*, 2, :x), 1) |> eval" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:call, :f, :x, \n", " (:call, :g, :y, :z))" ] } ], "source": [ "show_texpr(:(f(x, g(y, z))))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:call, :+, \n", " (:call, :*, 2, :x), 1)" ] } ], "source": [ "@show_texpr 2x+1" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "21" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 10; (:call, :+, \n", " (:call, :*, 2, :x), 1) |> teval" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ ":(sin(π / 6))" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "texpr2expr((:call, :sin, (:call, :/, π, 6)))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "0.49999999999999994" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(:call, :sin, (:call, :/, π, 6)) |> teval" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "0.49999999999999994" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@teval (:call, :sin, (:call, :/, π, 6))" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ":(sin(π / 6))\n", "→ 0.49999999999999994\n" ] } ], "source": [ "MetaUtils.@t (:call, :sin, (:call, :/, π, 6))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:call, :sin, (:call, :/, π, 6))\n", "→ (:call, :sin, \n", " (:call, :/, π, 6))\n", "→ :(sin(π / 6))\n", "→ 0.49999999999999994\n" ] } ], "source": [ "MetaUtils.@T (:call, :sin, (:call, :/, π, 6))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "0.49999999999999994" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(:sin, (:/, π, 6)) |> teval" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "0.49999999999999994" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@teval (:sin, (:/, π, 6))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ":(sin(π / 6))\n", "→ 0.49999999999999994\n" ] } ], "source": [ "MetaUtils.@t (:sin, (:/, π, 6))" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:sin, (:/, π, 6))\n", "→ (:call, :sin, \n", " (:call, :/, π, 6))\n", "→ :(sin(π / 6))\n", "→ 0.49999999999999994\n" ] } ], "source": [ "MetaUtils.@T (:sin, (:/, π, 6))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Miscellaneous examples of @show_texpr, etc." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### for loop" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:for, \n", " (:(=), :k, \n", " (:call, :(:), 1, 10)), \n", " (:block, \n", " (:(=), :x, \n", " (:call, :÷, \n", " (:call, :*, :k, \n", " (:call, :+, :k, 1)), 2)), \n", " (:call, :println, \"k(k+1)/2 = \", :x)))" ] } ], "source": [ "@show_texpr for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:for, \n", " (:(=), :k, \n", " (:call, :(:), 1, 10)), \n", " (:block, LineNumberNode(2, Symbol(\"In[25]\")), \n", " (:(=), :x, \n", " (:call, :÷, \n", " (:call, :*, :k, \n", " (:call, :+, :k, 1)), 2)), LineNumberNode(3, Symbol(\"In[25]\")), \n", " (:call, :println, \"k(k+1)/2 = \", :x)))" ] } ], "source": [ "@show_texpr for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end true" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:for)\n", "├─ Expr(:(=))\n", "│ ├─ :k\n", "│ └─ Expr(:call)\n", "│ ⋮\n", "│ \n", "└─ Expr(:block)\n", " ├─ Expr(:(=))\n", " │ ⋮\n", " │ \n", " └─ Expr(:call)\n", " ⋮\n", " \n" ] } ], "source": [ "@show_tree for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end 2" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:for)\n", "├─ Expr(:(=))\n", "│ ├─ :k\n", "│ └─ Expr(:call)\n", "│ ├─ :(:)\n", "│ ├─ 1\n", "│ └─ 10\n", "└─ Expr(:block)\n", " ├─ Expr(:(=))\n", " │ ├─ :x\n", " │ └─ Expr(:call)\n", " │ ├─ :÷\n", " │ ├─ Expr(:call)\n", " │ │ ├─ :*\n", " │ │ ├─ :k\n", " │ │ └─ Expr(:call)\n", " │ │ ├─ :+\n", " │ │ ├─ :k\n", " │ │ └─ 1\n", " │ └─ 2\n", " └─ Expr(:call)\n", " ├─ :println\n", " ├─ \"k(k+1)/2 = \"\n", " └─ :x\n" ] } ], "source": [ "@show_tree for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:for)\n", "├─ Expr(:(=))\n", "│ ├─ :k\n", "│ └─ Expr(:call)\n", "│ ├─ :(:)\n", "│ ├─ 1\n", "│ └─ 10\n", "└─ Expr(:block)\n", " ├─ :(#= In[28]:2 =#)\n", " ├─ Expr(:(=))\n", " │ ├─ :x\n", " │ └─ Expr(:call)\n", " │ ├─ :÷\n", " │ ├─ Expr(:call)\n", " │ │ ├─ :*\n", " │ │ ├─ :k\n", " │ │ └─ Expr(:call)\n", " │ │ ├─ :+\n", " │ │ ├─ :k\n", " │ │ └─ 1\n", " │ └─ 2\n", " ├─ :(#= In[28]:3 =#)\n", " └─ Expr(:call)\n", " ├─ :println\n", " ├─ \"k(k+1)/2 = \"\n", " └─ :x\n" ] } ], "source": [ "@show_tree for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end 10 true" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr\n", " head: Symbol for\n", " args: Array{Any}((2,))\n", " 1: Expr\n", " head: Symbol =\n", " args: Array{Any}((2,))\n", " 1: Symbol k\n", " 2: Expr\n", " head: Symbol call\n", " args: Array{Any}((3,))\n", " 1: Symbol :\n", " 2: Int64 1\n", " 3: Int64 10\n", " 2: Expr\n", " head: Symbol block\n", " args: Array{Any}((4,))\n", " 1: LineNumberNode\n", " line: Int64 2\n", " file: Symbol In[29]\n", " 2: Expr\n", " head: Symbol =\n", " args: Array{Any}((2,))\n", " 1: Symbol x\n", " 2: Expr\n", " head: Symbol call\n", " args: Array{Any}((3,))\n", " 1: Symbol ÷\n", " 2: Expr\n", " 3: Int64 2\n", " 3: LineNumberNode\n", " line: Int64 3\n", " file: Symbol In[29]\n", " 4: Expr\n", " head: Symbol call\n", " args: Array{Any}((3,))\n", " 1: Symbol println\n", " 2: String \"k(k+1)/2 = \"\n", " 3: Symbol x\n" ] } ], "source": [ "Meta.@dump for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:for, \n", " Expr(:(=), :k, \n", " Expr(:call, :(:), 1, 10)), \n", " Expr(:block, \n", " Expr(:(=), :x, \n", " Expr(:call, :÷, \n", " Expr(:call, :*, :k, \n", " Expr(:call, :+, :k, 1)), 2)), \n", " Expr(:call, :println, \"k(k+1)/2 = \", :x)))" ] } ], "source": [ "@show_expr for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:for, \n", " (:(=), :k, \n", " (:call, :(:), 1, 10)), \n", " (:block, \n", " (:(=), :x, \n", " (:call, :÷, \n", " (:call, :*, :k, \n", " (:call, :+, :k, 1)), 2)), \n", " (:call, :println, \"k(k+1)/2 = \", :x)))" ] } ], "source": [ "@show_texpr for k in 1:10\n", " x = k*(k+1) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### subtype trees" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AbstractRange\n", "├─ LinRange\n", "├─ OrdinalRange\n", "│ ├─ AbstractUnitRange\n", "│ │ ├─ Base.IdentityUnitRange\n", "│ │ ├─ Base.OneTo\n", "│ │ ├─ Base.Slice\n", "│ │ └─ UnitRange\n", "│ └─ StepRange\n", "└─ StepRangeLen\n" ] } ], "source": [ "print_subtypes(AbstractRange)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number\n", "├─ Complex\n", "└─ Real\n", " ├─ AbstractFloat\n", " │ ├─ BigFloat\n", " │ ├─ Float16\n", " │ ├─ Float32\n", " │ └─ Float64\n", " ├─ AbstractIrrational\n", " │ └─ Irrational\n", " ├─ Integer\n", " │ ├─ Bool\n", " │ ├─ Signed\n", " │ │ ├─ BigInt\n", " │ │ ├─ Int128\n", " │ │ ├─ Int16\n", " │ │ ├─ Int32\n", " │ │ ├─ Int64\n", " │ │ └─ Int8\n", " │ └─ Unsigned\n", " │ ├─ UInt128\n", " │ ├─ UInt16\n", " │ ├─ UInt32\n", " │ ├─ UInt64\n", " │ └─ UInt8\n", " └─ Rational\n" ] } ], "source": [ "print_subtypes(Number)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AbstractVector\n", "├─ AbstractRange\n", "│ ├─ LinRange\n", "│ ├─ OrdinalRange\n", "│ │ ├─ AbstractUnitRange\n", "│ │ │ ├─ Base.IdentityUnitRange\n", "│ │ │ ├─ Base.OneTo\n", "│ │ │ ├─ Base.Slice\n", "│ │ │ └─ UnitRange\n", "│ │ └─ StepRange\n", "│ └─ StepRangeLen\n", "├─ Base.ExceptionStack\n", "├─ Base.LogicalIndex\n", "├─ Base.MethodList\n", "├─ Base.ReinterpretArray{T, 1, S, A} where {T, S, A<:(AbstractArray{S})}\n", "├─ Base.ReshapedArray{T, 1} where T\n", "├─ BitVector\n", "├─ CartesianIndices{1, R} where R<:Tuple{OrdinalRange{Int64, Int64}}\n", "├─ Core.Compiler.AbstractRange\n", "│ ├─ Core.Compiler.LinRange\n", "│ ├─ Core.Compiler.OrdinalRange\n", "│ │ ├─ Core.Compiler.AbstractUnitRange\n", "│ │ │ ├─ Core.Compiler.IdentityUnitRange\n", "│ │ │ ├─ Core.Compiler.OneTo\n", "│ │ │ ├─ Core.Compiler.Slice\n", "│ │ │ ├─ Core.Compiler.StmtRange\n", "│ │ │ └─ Core.Compiler.UnitRange\n", "│ │ └─ Core.Compiler.StepRange\n", "│ └─ Core.Compiler.StepRangeLen\n", "├─ Core.Compiler.BitArray{1}\n", "├─ Core.Compiler.ExceptionStack\n", "├─ Core.Compiler.LinearIndices{1, R} where R<:Tuple{Core.Compiler.AbstractUnitRange{Int64}}\n", "├─ Core.Compiler.MethodList\n", "├─ DenseVector\n", "│ ├─ Base.CodeUnits\n", "│ ├─ Base.Experimental.Const{T, 1} where T\n", "│ ├─ Random.UnsafeView\n", "│ ├─ SharedArrays.SharedVector\n", "│ └─ Vector\n", "├─ LinearIndices{1, R} where R<:Tuple{AbstractUnitRange{Int64}}\n", "├─ PermutedDimsArray{T, 1} where T\n", "├─ SparseArrays.AbstractSparseVector\n", "│ └─ SparseArrays.SparseVector\n", "├─ SubArray{T, 1} where T\n", "├─ Test.GenericArray{T, 1} where T\n", "└─ ZMQ.Message\n" ] } ], "source": [ "print_subtypes(AbstractVector)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### function definition" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:function, \n", " (:where, \n", " (:call, :f, \n", " (:(::), :x, :T)), \n", " (:<:, :T, :Number)), \n", " (:block, \n", " (:call, :sin, :x)))" ] } ], "source": [ "@show_texpr function f(x::T) where T<:Number\n", " sin(x)\n", "end" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:function)\n", "├─ Expr(:where)\n", "│ ├─ Expr(:call)\n", "│ │ ├─ :f\n", "│ │ └─ Expr(:(::))\n", "│ │ ├─ :x\n", "│ │ └─ :T\n", "│ └─ Expr(:<:)\n", "│ ├─ :T\n", "│ └─ :Number\n", "└─ Expr(:block)\n", " └─ Expr(:call)\n", " ├─ :sin\n", " └─ :x\n" ] } ], "source": [ "@show_tree function f(x::T) where T<:Number\n", " sin(x)\n", "end" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:function, \n", " Expr(:where, \n", " Expr(:call, :f, \n", " Expr(:(::), :x, :T)), \n", " Expr(:<:, :T, :Number)), \n", " Expr(:block, \n", " Expr(:call, :sin, :x)))" ] } ], "source": [ "@show_expr function f(x::T) where T<:Number\n", " sin(x)\n", "end" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:function, \n", " (:where, \n", " (:call, :f, \n", " (:(::), :x, :T)), \n", " (:<:, :T, :Number)), \n", " (:block, \n", " (:call, :sin, :x)))" ] } ], "source": [ "@show_texpr function f(x::T) where T<:Number\n", " sin(x)\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### macro and LineNumberNode" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:macrocall)\n", "├─ Symbol(\"@show\")\n", "├─ :(#= In[39]:1 =#)\n", "└─ Expr(:call)\n", " ├─ :float\n", " └─ :π\n" ] } ], "source": [ "@show_tree @show float(π)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:macrocall, Symbol(\"@show\"), :(#= In[40]:1 =#), (:call, :float, :π))" ] } ], "source": [ "@show_sexpr @show float(π)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "float(π) = 3.141592653589793\n" ] }, { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@teval (:macrocall, Symbol(\"@show\"), :(#= In[34]:1 =#), (:call, :float, :π))" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:macrocall, Symbol(\"@show\"), LineNumberNode(1, Symbol(\"In[42]\")), \n", " Expr(:call, :float, :π))" ] } ], "source": [ "@show_expr @show float(π)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expr(:macrocall, Symbol(\"@show\"), LineNumberNode(1, Symbol(\"In[43]\")), \n", " Expr(:call, :float, :π))" ] } ], "source": [ "Expr(:macrocall, Symbol(\"@show\"), LineNumberNode(@__LINE__, @__FILE__), \n", " Expr(:call, :float, :π)) |> show_expr" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "float(π) = 3.141592653589793\n" ] }, { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Expr(:macrocall, Symbol(\"@show\"), LineNumberNode(@__LINE__, @__FILE__), \n", " Expr(:call, :float, :π)) |> eval" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:macrocall, Symbol(\"@show\"), LineNumberNode(1, Symbol(\"In[45]\")), \n", " (:call, :float, :π))" ] } ], "source": [ "@show_texpr @show float(π)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "float(π) = 3.141592653589793\n" ] }, { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(:macrocall, Symbol(\"@show\"), LineNumberNode(@__LINE__, @__FILE__), \n", " (:call, :float, :π)) |> teval" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "float(π) = 3.141592653589793\n" ] }, { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@teval (:macrocall, Symbol(\"@show\"), LineNumberNode(@__LINE__, @__FILE__), \n", " (:call, :float, :π))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### QuoteNode" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ ":($(QuoteNode(:(sin(x)))))" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "QuoteNode(:(sin(x)))" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:quote, #QuoteNode\n", " (:call, :sin, :x)\n", ")" ] } ], "source": [ "QuoteNode(:(sin(x))) |> Meta.show_sexpr" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QuoteNode(\n", " Expr(:call, :sin, :x))" ] } ], "source": [ "QuoteNode(:(sin(x))) |> show_expr" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QuoteNode(\n", " (:call, :sin, :x))" ] } ], "source": [ "QuoteNode(:(sin(x))) |> show_texpr" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "true" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "QuoteNode(\n", " (:call, :sin, :x)) |> texpr2expr == QuoteNode(:(sin(x)))" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ ":(sin(x))" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@teval QuoteNode(\n", " (:call, :sin, :x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Evaluation of Lisp-like tuple expressions\n", "\n", "If you want more Lisp-like examamples, see [LispLikeEval.ipynb](https://nbviewer.jupyter.org/github/genkuroki/LispLikeEval.jl/blob/master/LispLikeEval.ipynb)." ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [], "source": [ "using MetaUtils: @t, @T" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ":(f(x) = sin(x))\n", "→ f\n", "\n", ":(f(π / 6))\n", "→ 0.49999999999999994\n" ] } ], "source": [ "# Define and run a function f(x) = sin(x)\n", "\n", "@t (:(=), :(f(x)), (:sin, :x))\n", "println()\n", "@t (:f, (:/, π, 6))" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:(=), :(f(x)), (:sin, :x))\n", "→ (:(=), \n", " (:call, :f, :x), \n", " (:call, :sin, :x))\n", "→ :(f(x) = sin(x))\n", "→ f\n", "\n", "(:f, (:/, π, 6))\n", "→ (:call, :f, \n", " (:call, :/, π, 6))\n", "→ :(f(π / 6))\n", "→ 0.49999999999999994\n" ] } ], "source": [ "# Define and run a function f(x) = sin(x)\n", "\n", "@T (:(=), :(f(x)), (:sin, :x))\n", "println()\n", "@T (:f, (:/, π, 6))" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "quote\n", " function g(x)\n", " sin(x)\n", " end\n", " g(π / 6)\n", "end\n", "→ 0.49999999999999994\n" ] } ], "source": [ "# Define and run a function g(x) = sin(x)\n", "\n", "@t (:block,\n", " (:function, :(g(x)), (:sin, :x)),\n", " (:call, :g, (:/, π, 6)))" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:block, (:function, :(g(x)), (:sin, :x)), (:call, :g, (:/, π, 6)))\n", "→ (:block, \n", " (:function, \n", " (:call, :g, :x), \n", " (:call, :sin, :x)), \n", " (:call, :g, \n", " (:call, :/, π, 6)))\n", "→ quote\n", " function g(x)\n", " sin(x)\n", " end\n", " g(π / 6)\n", "end\n", "→ 0.49999999999999994\n" ] } ], "source": [ "# Define and run a function g(x) = sin(x)\n", "\n", "@T (:block,\n", " (:function, :(g(x)), (:sin, :x)),\n", " (:call, :g, (:/, π, 6)))" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "quote\n", " function pi_mc(N)\n", " c = 0\n", " for i = 1:N\n", " c += ifelse(rand() ^ 2 + rand() ^ 2 ≤ 1, 1, 0)\n", " end\n", " (4c) / N\n", " end\n", " pi_mc(10 ^ 8)\n", "end\n", "→ 3.14178092\n" ] } ], "source": [ "# Calculation of pi by the Monte Carlo method\n", "\n", "@t (:block, \n", " (:function, :(pi_mc(N)), \n", " (:block, \n", " (:(=), :c, 0), \n", " (:for, (:(=), :i, (:(:), 1, :N)), \n", " (:block, \n", " (:+=, :c, \n", " (:call, :ifelse, \n", " (:≤, (:+, (:^, (:rand,), 2), (:^, (:rand,), 2)), 1), \n", " 1, 0)))), \n", " (:/, (:*, 4, :c), :N))), \n", " (:call, :pi_mc, (:^, 10, 8)))" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ":($(Expr(:quote, :(sin(x)))))\n", "→ :(sin(x))\n" ] } ], "source": [ "# quote\n", "\n", "@t (:quote, (:sin, :x))" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ":((1, 2, 3))\n", "→ (1, 2, 3)\n" ] } ], "source": [ "# tuple\n", "\n", "@t (:tuple, 1, 2, 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot example" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "begin\n", " using Plots\n", " n = 20\n", " x = range(-π, π; length=20)\n", " noise = 0.3randn(n)\n", " y = sin.(x) + noise\n", " X = x .^ (0:3)'\n", " b = X\\y\n", "    f(x) = evalpoly(x, b)\n", " xs = range(-π, π; length=400)\n", " plot(; legend=:topleft)\n", " scatter!(x, y; label=\"sample\")\n", " plot!(xs, sin.(xs); label=\"sin(x)\", color=:blue, ls=:dash)\n", " plot!(xs, f.(xs); label=\"degree-3 polynomial\", color=:red, lw=2)\n", "end" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(:block, \n", " (:using, \n", " (:., :Plots)), \n", " (:(=), :n, 20), \n", " (:(=), :x, \n", " (:call, :range, \n", " (:parameters, \n", " (:kw, :length, 20)), \n", " (:call, :-, :π), :π)), \n", " (:(=), :noise, \n", " (:call, :*, 0.3, \n", " (:call, :randn, :n))), \n", " (:(=), :y, \n", " (:call, :+, \n", " (:., :sin, \n", " (:tuple, :x)), :noise)), \n", " (:(=), :X, \n", " (:call, :.^, :x, \n", " (Symbol(\"'\"), \n", " (:call, :(:), 0, 3)))), \n", " (:(=), :b, \n", " (:call, :\\, :X, :y)), \n", " (:(=), \n", " (:call, :f, :x), \n", " (:block, \n", " (:call, :evalpoly, :x, :b))), \n", " (:(=), :xs, \n", " (:call, :range, \n", " (:parameters, \n", " (:kw, :length, 400)), \n", " (:call, :-, :π), :π)), \n", " (:call, :plot, \n", " (:parameters, \n", " (:kw, :legend, QuoteNode(:topleft)))), \n", " (:call, :scatter!, \n", " (:parameters, \n", " (:kw, :label, \"sample\")), :x, :y), \n", " (:call, :plot!, \n", " (:parameters, \n", " (:kw, :label, \"sin(x)\"), \n", " (:kw, :color, QuoteNode(:blue)), \n", " (:kw, :ls, QuoteNode(:dash))), :xs, \n", " (:., :sin, \n", " (:tuple, :xs))), \n", " (:call, :plot!, \n", " (:parameters, \n", " (:kw, :label, \"degree-3 polynomial\"), \n", " (:kw, :color, QuoteNode(:red)), \n", " (:kw, :lw, 2)), :xs, \n", " (:., :f, \n", " (:tuple, :xs))))" ] } ], "source": [ "@show_texpr begin\n", " using Plots\n", " n = 20\n", " x = range(-π, π; length=20)\n", " noise = 0.3randn(n)\n", " y = sin.(x) + noise\n", " X = x .^ (0:3)'\n", " b = X\\y\n", "    f(x) = evalpoly(x, b)\n", " xs = range(-π, π; length=400)\n", " plot(; legend=:topleft)\n", " scatter!(x, y; label=\"sample\")\n", " plot!(xs, sin.(xs); label=\"sin(x)\", color=:blue, ls=:dash)\n", " plot!(xs, f.(xs); label=\"degree-3 polynomial\", color=:red, lw=2)\n", "end" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@teval (:block, \n", " (:using, (:., :Plots)), \n", " (:(=), :n, 20), \n", " (:(=), :x, (:range, (:parameters, (:kw, :length, 20)), (:-, :π), :π)), \n", " (:(=), :noise, (:*, 0.3, (:randn, :n))), \n", " (:(=), :y, (:+, (:., :sin, (:tuple, :x)), :noise)), \n", " (:(=), :X, (:call, :.^, :x, (Symbol(\"'\"), (:call, :(:), 0, 3)))), \n", " (:(=), :b, (:\\, :X, :y)), \n", " (:(=), (:call, :f, :x), (:block, (:call, :evalpoly, :x, :b))),\n", " (:(=), :xs, (:range, (:parameters, (:kw, :length, 400)), (:-, :π), :π)), \n", " (:plot, (:parameters, (:kw, :legend, QuoteNode(:topleft)))), \n", " (:scatter!, (:parameters, (:kw, :label, \"sample\")), :x, :y), \n", " (:plot!, (:parameters, \n", " (:kw, :label, \"sin(x)\"), \n", " (:kw, :color, QuoteNode(:blue)), \n", " (:kw, :ls, QuoteNode(:dash))), \n", " :xs, (:., :sin, (:tuple, :xs))), \n", " (:plot!, (:parameters, \n", " (:kw, :label, \"degree-3 polynomial\"), \n", " (:kw, :color, QuoteNode(:red)), \n", " (:kw, :lw, 2)), \n", " :xs, (:., :f, (:tuple, :xs))))" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "```julia\n", "begin\n", " using Plots\n", " n = 20\n", " x = range(-π, π; length = 20)\n", " noise = 0.3 * randn(n)\n", " y = sin.(x) + noise\n", " X = x .^ var\"'\"(0:3)\n", " b = X \\ y\n", " f(x) = begin\n", " evalpoly(x, b)\n", " end\n", " xs = range(-π, π; length = 400)\n", " plot(; legend = :topleft)\n", " scatter!(x, y; label = \"sample\")\n", " plot!(xs, sin.(xs); label = \"sin(x)\", color = :blue, ls = :dash)\n", " plot!(xs, f.(xs); label = \"degree-3 polynomial\", color = :red, lw = 2)\n", "end\n", "```" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "(:block, \n", " (:using, (:., :Plots)), \n", " (:(=), :n, 20), \n", " (:(=), :x, (:range, (:parameters, (:kw, :length, 20)), (:-, :π), :π)), \n", " (:(=), :noise, (:*, 0.3, (:randn, :n))), \n", " (:(=), :y, (:+, (:., :sin, (:tuple, :x)), :noise)), \n", " (:(=), :X, (:call, :.^, :x, (Symbol(\"'\"), (:call, :(:), 0, 3)))), \n", " (:(=), :b, (:\\, :X, :y)), \n", " (:(=), (:call, :f, :x), (:block, (:call, :evalpoly, :x, :b))),\n", " (:(=), :xs, (:range, (:parameters, (:kw, :length, 400)), (:-, :π), :π)), \n", " (:plot, (:parameters, (:kw, :legend, QuoteNode(:topleft)))), \n", " (:scatter!, (:parameters, (:kw, :label, \"sample\")), :x, :y), \n", " (:plot!, (:parameters, \n", " (:kw, :label, \"sin(x)\"), \n", " (:kw, :color, QuoteNode(:blue)), \n", " (:kw, :ls, QuoteNode(:dash))), \n", " :xs, (:., :sin, (:tuple, :xs))), \n", " (:plot!, (:parameters, \n", " (:kw, :label, \"degree-3 polynomial\"), \n", " (:kw, :color, QuoteNode(:red)), \n", " (:kw, :lw, 2)), \n", " :xs, (:., :f, (:tuple, :xs)))) |> texpr2expr |> \n", "x -> display(\"text/markdown\", \"```julia\\n$x\\n```\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Documents" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "MetaUtils\n", "\\end{verbatim}\n", "contains utilities for metaprogramming in Julia.\n", "\n", "\\begin{verbatim}\n", "export @show_sexpr, \n", " show_tree, @show_tree, \n", " print_subtypes, \n", " show_expr, @show_expr, \n", " show_texpr, @show_texpr, \n", " texpr2expr, teval, @teval\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "MetaUtils\n", "```\n", "\n", "contains utilities for metaprogramming in Julia.\n", "\n", "```julia\n", "export @show_sexpr, \n", " show_tree, @show_tree, \n", " print_subtypes, \n", " show_expr, @show_expr, \n", " show_texpr, @show_texpr, \n", " texpr2expr, teval, @teval\n", "```\n" ], "text/plain": [ "\u001b[36m MetaUtils\u001b[39m\n", "\n", " contains utilities for metaprogramming in Julia.\n", "\n", "\u001b[36m export @show_sexpr, \u001b[39m\n", "\u001b[36m show_tree, @show_tree, \u001b[39m\n", "\u001b[36m print_subtypes, \u001b[39m\n", "\u001b[36m show_expr, @show_expr, \u001b[39m\n", "\u001b[36m show_texpr, @show_texpr, \u001b[39m\n", "\u001b[36m texpr2expr, teval, @teval\u001b[39m" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc MetaUtils" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "@show_sexpr(expr, linenums=false)\n", "\\end{verbatim}\n", "shows the lisp style S-expression of \\texttt{expr} and prints the line number nodes if \\texttt{linenums} is true. This is the macro version of \\texttt{Meta.show\\_sexpr}.\n", "\n", "\\subsection{Example}\n", "\\begin{verbatim}\n", "julia> @show_sexpr 2x+1\n", "(:call, :+, (:call, :*, 2, :x), 1)\n", "\\end{verbatim}\n", "\\texttt{teval} function can evaluate the output of \\texttt{@show\\_sexpr}. \n", "\n", "\\begin{verbatim}\n", "julia> x = 10; (:call, :+, (:call, :*, 2, :x), 1) |> teval\n", "21\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "@show_sexpr(expr, linenums=false)\n", "```\n", "\n", "shows the lisp style S-expression of `expr` and prints the line number nodes if `linenums` is true. This is the macro version of `Meta.show_sexpr`.\n", "\n", "## Example\n", "\n", "```julia\n", "julia> @show_sexpr 2x+1\n", "(:call, :+, (:call, :*, 2, :x), 1)\n", "```\n", "\n", "`teval` function can evaluate the output of `@show_sexpr`. \n", "\n", "```julia\n", "julia> x = 10; (:call, :+, (:call, :*, 2, :x), 1) |> teval\n", "21\n", "```\n" ], "text/plain": [ "\u001b[36m @show_sexpr(expr, linenums=false)\u001b[39m\n", "\n", " shows the lisp style S-expression of \u001b[36mexpr\u001b[39m and prints the line number nodes\n", " if \u001b[36mlinenums\u001b[39m is true. This is the macro version of \u001b[36mMeta.show_sexpr\u001b[39m.\n", "\n", "\u001b[1m Example\u001b[22m\n", "\u001b[1m =========\u001b[22m\n", "\n", "\u001b[36m julia> @show_sexpr 2x+1\u001b[39m\n", "\u001b[36m (:call, :+, (:call, :*, 2, :x), 1)\u001b[39m\n", "\n", " \u001b[36mteval\u001b[39m function can evaluate the output of \u001b[36m@show_sexpr\u001b[39m.\n", "\n", "\u001b[36m julia> x = 10; (:call, :+, (:call, :*, 2, :x), 1) |> teval\u001b[39m\n", "\u001b[36m 21\u001b[39m" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc @show_sexpr" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "@show_tree(expr, maxdepth=10, linenums=false)\n", "\\end{verbatim}\n", "shows the tree form of the expression \\texttt{expr} with maxdepth and prints the line number nodes if \\texttt{linenums} is true.\n", "\n", "\\subsection{Example}\n", "\\begin{verbatim}\n", "julia> @show_tree 2x+1\n", "Expr(:call)\n", "├─ :+\n", "├─ Expr(:call)\n", "│ ├─ :*\n", "│ ├─ 2\n", "│ └─ :x\n", "└─ 1\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "@show_tree(expr, maxdepth=10, linenums=false)\n", "```\n", "\n", "shows the tree form of the expression `expr` with maxdepth and prints the line number nodes if `linenums` is true.\n", "\n", "## Example\n", "\n", "```julia\n", "julia> @show_tree 2x+1\n", "Expr(:call)\n", "├─ :+\n", "├─ Expr(:call)\n", "│ ├─ :*\n", "│ ├─ 2\n", "│ └─ :x\n", "└─ 1\n", "```\n" ], "text/plain": [ "\u001b[36m @show_tree(expr, maxdepth=10, linenums=false)\u001b[39m\n", "\n", " shows the tree form of the expression \u001b[36mexpr\u001b[39m with maxdepth and prints the line\n", " number nodes if \u001b[36mlinenums\u001b[39m is true.\n", "\n", "\u001b[1m Example\u001b[22m\n", "\u001b[1m =========\u001b[22m\n", "\n", "\u001b[36m julia> @show_tree 2x+1\u001b[39m\n", "\u001b[36m Expr(:call)\u001b[39m\n", "\u001b[36m ├─ :+\u001b[39m\n", "\u001b[36m ├─ Expr(:call)\u001b[39m\n", "\u001b[36m │ ├─ :*\u001b[39m\n", "\u001b[36m │ ├─ 2\u001b[39m\n", "\u001b[36m │ └─ :x\u001b[39m\n", "\u001b[36m └─ 1\u001b[39m" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc @show_tree" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "show_tree(expr) = AbstractTrees.print_tree(expr)\n", "\\end{verbatim}\n", "can be regarded as the function version of \\texttt{@show\\_tree}.\n", "\n" ], "text/markdown": [ "```\n", "show_tree(expr) = AbstractTrees.print_tree(expr)\n", "```\n", "\n", "can be regarded as the function version of `@show_tree`.\n" ], "text/plain": [ "\u001b[36m show_tree(expr) = AbstractTrees.print_tree(expr)\u001b[39m\n", "\n", " can be regarded as the function version of \u001b[36m@show_tree\u001b[39m." ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc show_tree" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "print_subtypes(T::Type; kwargs...)\n", "print_subtypes(io::IO, T::Type; kwargs...)\n", "print_subtypes(f, io::IO, T::Type; kwargs...)\n", "\\end{verbatim}\n", "prints the subtypes of \\texttt{T} by \\texttt{AbstractTrees.print\\_tree}.\n", "\n", "\\subsection{Example}\n", "\\begin{verbatim}\n", "julia> print_subtypes(AbstractRange)\n", "AbstractRange\n", "├─ LinRange\n", "├─ OrdinalRange\n", "│ ├─ AbstractUnitRange\n", "│ │ ├─ Base.IdentityUnitRange\n", "│ │ ├─ Base.OneTo\n", "│ │ ├─ Base.Slice\n", "│ │ └─ UnitRange\n", "│ └─ StepRange\n", "└─ StepRangeLen\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "print_subtypes(T::Type; kwargs...)\n", "print_subtypes(io::IO, T::Type; kwargs...)\n", "print_subtypes(f, io::IO, T::Type; kwargs...)\n", "```\n", "\n", "prints the subtypes of `T` by `AbstractTrees.print_tree`.\n", "\n", "## Example\n", "\n", "```julia\n", "julia> print_subtypes(AbstractRange)\n", "AbstractRange\n", "├─ LinRange\n", "├─ OrdinalRange\n", "│ ├─ AbstractUnitRange\n", "│ │ ├─ Base.IdentityUnitRange\n", "│ │ ├─ Base.OneTo\n", "│ │ ├─ Base.Slice\n", "│ │ └─ UnitRange\n", "│ └─ StepRange\n", "└─ StepRangeLen\n", "```\n" ], "text/plain": [ "\u001b[36m print_subtypes(T::Type; kwargs...)\u001b[39m\n", "\u001b[36m print_subtypes(io::IO, T::Type; kwargs...)\u001b[39m\n", "\u001b[36m print_subtypes(f, io::IO, T::Type; kwargs...)\u001b[39m\n", "\n", " prints the subtypes of \u001b[36mT\u001b[39m by \u001b[36mAbstractTrees.print_tree\u001b[39m.\n", "\n", "\u001b[1m Example\u001b[22m\n", "\u001b[1m =========\u001b[22m\n", "\n", "\u001b[36m julia> print_subtypes(AbstractRange)\u001b[39m\n", "\u001b[36m AbstractRange\u001b[39m\n", "\u001b[36m ├─ LinRange\u001b[39m\n", "\u001b[36m ├─ OrdinalRange\u001b[39m\n", "\u001b[36m │ ├─ AbstractUnitRange\u001b[39m\n", "\u001b[36m │ │ ├─ Base.IdentityUnitRange\u001b[39m\n", "\u001b[36m │ │ ├─ Base.OneTo\u001b[39m\n", "\u001b[36m │ │ ├─ Base.Slice\u001b[39m\n", "\u001b[36m │ │ └─ UnitRange\u001b[39m\n", "\u001b[36m │ └─ StepRange\u001b[39m\n", "\u001b[36m └─ StepRangeLen\u001b[39m" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc print_subtypes" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "show_expr([io::IO,], ex)\n", "\\end{verbatim}\n", "shows expression \\texttt{ex} as a Julia style expression.\n", "\n", "\\section{Examples}\n", "\\begin{verbatim}\n", "julia> show_expr(:(f(x, g(y, z))))\n", "Expr(:call, :f, :x, \n", " Expr(:call, :g, :y, :z))\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "show_expr([io::IO,], ex)\n", "```\n", "\n", "shows expression `ex` as a Julia style expression.\n", "\n", "# Examples\n", "\n", "```julia\n", "julia> show_expr(:(f(x, g(y, z))))\n", "Expr(:call, :f, :x, \n", " Expr(:call, :g, :y, :z))\n", "```\n" ], "text/plain": [ "\u001b[36m show_expr([io::IO,], ex)\u001b[39m\n", "\n", " shows expression \u001b[36mex\u001b[39m as a Julia style expression.\n", "\n", "\u001b[1m Examples\u001b[22m\n", "\u001b[1m ≡≡≡≡≡≡≡≡≡≡\u001b[22m\n", "\n", "\u001b[36m julia> show_expr(:(f(x, g(y, z))))\u001b[39m\n", "\u001b[36m Expr(:call, :f, :x, \u001b[39m\n", "\u001b[36m Expr(:call, :g, :y, :z))\u001b[39m" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc show_expr" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "@show_expr(expr, linenums=false)\n", "\\end{verbatim}\n", "shows the Juia style expression of \\texttt{expr} and prints the line number nodes if \\texttt{linenums} is true. This is the macro version of \\texttt{show\\_expr}.\n", "\n", "\\subsection{Example}\n", "\\begin{verbatim}\n", "julia> @show_expr 2x+1\n", "Expr(:call, :+, \n", " Expr(:call, :*, 2, :x), 1)\n", "\\end{verbatim}\n", "\\texttt{eval} function can evaluate the output of \\texttt{@show\\_expr}. \n", "\n", "\\begin{verbatim}\n", "julia> x = 10; Expr(:call, :+, \n", " Expr(:call, :*, 2, :x), 1) |> eval\n", "21\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "@show_expr(expr, linenums=false)\n", "```\n", "\n", "shows the Juia style expression of `expr` and prints the line number nodes if `linenums` is true. This is the macro version of `show_expr`.\n", "\n", "## Example\n", "\n", "```julia\n", "julia> @show_expr 2x+1\n", "Expr(:call, :+, \n", " Expr(:call, :*, 2, :x), 1)\n", "```\n", "\n", "`eval` function can evaluate the output of `@show_expr`. \n", "\n", "```julia\n", "julia> x = 10; Expr(:call, :+, \n", " Expr(:call, :*, 2, :x), 1) |> eval\n", "21\n", "```\n" ], "text/plain": [ "\u001b[36m @show_expr(expr, linenums=false)\u001b[39m\n", "\n", " shows the Juia style expression of \u001b[36mexpr\u001b[39m and prints the line number nodes if\n", " \u001b[36mlinenums\u001b[39m is true. This is the macro version of \u001b[36mshow_expr\u001b[39m.\n", "\n", "\u001b[1m Example\u001b[22m\n", "\u001b[1m =========\u001b[22m\n", "\n", "\u001b[36m julia> @show_expr 2x+1\u001b[39m\n", "\u001b[36m Expr(:call, :+, \u001b[39m\n", "\u001b[36m Expr(:call, :*, 2, :x), 1)\u001b[39m\n", "\n", " \u001b[36meval\u001b[39m function can evaluate the output of \u001b[36m@show_expr\u001b[39m.\n", "\n", "\u001b[36m julia> x = 10; Expr(:call, :+, \u001b[39m\n", "\u001b[36m Expr(:call, :*, 2, :x), 1) |> eval\u001b[39m\n", "\u001b[36m 21\u001b[39m" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc @show_expr" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "show_texpr([io::IO,], ex)\n", "\\end{verbatim}\n", "Yet another \\texttt{Meta.show\\_sexpr}. It shows expression \\texttt{ex} as a lisp style expression.\n", "\n", "Remark: The indentation is different from \\texttt{Meta.show\\_sexpr}.\n", "\n", "\\section{Examples}\n", "\\begin{verbatim}\n", "julia> show_texpr(:(f(x, g(y, z))))\n", "Expr(:call, :f, :x, \n", " Expr(:call, :g, :y, :z))\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "show_texpr([io::IO,], ex)\n", "```\n", "\n", "Yet another `Meta.show_sexpr`. It shows expression `ex` as a lisp style expression.\n", "\n", "Remark: The indentation is different from `Meta.show_sexpr`.\n", "\n", "# Examples\n", "\n", "```julia\n", "julia> show_texpr(:(f(x, g(y, z))))\n", "Expr(:call, :f, :x, \n", " Expr(:call, :g, :y, :z))\n", "```\n" ], "text/plain": [ "\u001b[36m show_texpr([io::IO,], ex)\u001b[39m\n", "\n", " Yet another \u001b[36mMeta.show_sexpr\u001b[39m. It shows expression \u001b[36mex\u001b[39m as a lisp style\n", " expression.\n", "\n", " Remark: The indentation is different from \u001b[36mMeta.show_sexpr\u001b[39m.\n", "\n", "\u001b[1m Examples\u001b[22m\n", "\u001b[1m ≡≡≡≡≡≡≡≡≡≡\u001b[22m\n", "\n", "\u001b[36m julia> show_texpr(:(f(x, g(y, z))))\u001b[39m\n", "\u001b[36m Expr(:call, :f, :x, \u001b[39m\n", "\u001b[36m Expr(:call, :g, :y, :z))\u001b[39m" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc show_texpr" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "@show_texpr(expr, linenums=false)\n", "\\end{verbatim}\n", "Yet another \\texttt{@show\\_sexpr}. It shows the lisp style S-expression of \\texttt{expr} and prints the line number nodes if \\texttt{linenums} is true.\n", "\n", "Remark: The indentation is different from \\texttt{@show\\_sexpr}.\n", "\n", "\\subsection{Example}\n", "\\begin{verbatim}\n", "julia> @show_texpr 2x+1\n", "(:call, :+, \n", " (:call, :*, 2, :x), 1)\n", "\\end{verbatim}\n", "\\texttt{teval} function can evaluate the output of \\texttt{@show\\_texpr}.\n", "\n", "\\begin{verbatim}\n", "julia> x = 10; (:call, :+, \n", " (:call, :*, 2, :x), 1) |> teval\n", "21\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "@show_texpr(expr, linenums=false)\n", "```\n", "\n", "Yet another `@show_sexpr`. It shows the lisp style S-expression of `expr` and prints the line number nodes if `linenums` is true.\n", "\n", "Remark: The indentation is different from `@show_sexpr`.\n", "\n", "## Example\n", "\n", "```julia\n", "julia> @show_texpr 2x+1\n", "(:call, :+, \n", " (:call, :*, 2, :x), 1)\n", "```\n", "\n", "`teval` function can evaluate the output of `@show_texpr`.\n", "\n", "```julia\n", "julia> x = 10; (:call, :+, \n", " (:call, :*, 2, :x), 1) |> teval\n", "21\n", "```\n" ], "text/plain": [ "\u001b[36m @show_texpr(expr, linenums=false)\u001b[39m\n", "\n", " Yet another \u001b[36m@show_sexpr\u001b[39m. It shows the lisp style S-expression of \u001b[36mexpr\u001b[39m and\n", " prints the line number nodes if \u001b[36mlinenums\u001b[39m is true.\n", "\n", " Remark: The indentation is different from \u001b[36m@show_sexpr\u001b[39m.\n", "\n", "\u001b[1m Example\u001b[22m\n", "\u001b[1m =========\u001b[22m\n", "\n", "\u001b[36m julia> @show_texpr 2x+1\u001b[39m\n", "\u001b[36m (:call, :+, \u001b[39m\n", "\u001b[36m (:call, :*, 2, :x), 1)\u001b[39m\n", "\n", " \u001b[36mteval\u001b[39m function can evaluate the output of \u001b[36m@show_texpr\u001b[39m.\n", "\n", "\u001b[36m julia> x = 10; (:call, :+, \u001b[39m\n", "\u001b[36m (:call, :*, 2, :x), 1) |> teval\u001b[39m\n", "\u001b[36m 21\u001b[39m" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc @show_texpr" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "teval(texpr, m::Module=Main)\n", "\\end{verbatim}\n", "evaluates the lisp-like tuple expression \\texttt{texpr}.\n", "\n", "Example: Calculation of \\texttt{sin(π/6)}\n", "\n", "\\begin{verbatim}\n", "julia> (:call, :sin, (:call, :/, π, 6)) |> teval\n", "0.49999999999999994\n", "\\end{verbatim}\n", "In some cases, you can omit \\texttt{:call}.\n", "\n", "\\begin{verbatim}\n", "julia> (:sin, (:/, π, 6)) |> teval\n", "0.49999999999999994\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "teval(texpr, m::Module=Main)\n", "```\n", "\n", "evaluates the lisp-like tuple expression `texpr`.\n", "\n", "Example: Calculation of `sin(π/6)`\n", "\n", "```julia\n", "julia> (:call, :sin, (:call, :/, π, 6)) |> teval\n", "0.49999999999999994\n", "```\n", "\n", "In some cases, you can omit `:call`.\n", "\n", "```julia\n", "julia> (:sin, (:/, π, 6)) |> teval\n", "0.49999999999999994\n", "```\n" ], "text/plain": [ "\u001b[36m teval(texpr, m::Module=Main)\u001b[39m\n", "\n", " evaluates the lisp-like tuple expression \u001b[36mtexpr\u001b[39m.\n", "\n", " Example: Calculation of \u001b[36msin(π/6)\u001b[39m\n", "\n", "\u001b[36m julia> (:call, :sin, (:call, :/, π, 6)) |> teval\u001b[39m\n", "\u001b[36m 0.49999999999999994\u001b[39m\n", "\n", " In some cases, you can omit \u001b[36m:call\u001b[39m.\n", "\n", "\u001b[36m julia> (:sin, (:/, π, 6)) |> teval\u001b[39m\n", "\u001b[36m 0.49999999999999994\u001b[39m" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc teval" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "@teval texpr\n", "\\end{verbatim}\n", "evaluates the lisp-like tuple expression \\texttt{texpr}.\n", "\n", "Example: Calculation of \\texttt{sin(π/6)}\n", "\n", "\\begin{verbatim}\n", "julia> @teval (:call, :sin, (:call, :/, π, 6))\n", "0.49999999999999994\n", "\\end{verbatim}\n", "In some cases, you can omit \\texttt{:call}.\n", "\n", "\\begin{verbatim}\n", "julia> @teval (:sin, (:/, π, 6))\n", "0.49999999999999994\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "@teval texpr\n", "```\n", "\n", "evaluates the lisp-like tuple expression `texpr`.\n", "\n", "Example: Calculation of `sin(π/6)`\n", "\n", "```julia\n", "julia> @teval (:call, :sin, (:call, :/, π, 6))\n", "0.49999999999999994\n", "```\n", "\n", "In some cases, you can omit `:call`.\n", "\n", "```julia\n", "julia> @teval (:sin, (:/, π, 6))\n", "0.49999999999999994\n", "```\n" ], "text/plain": [ "\u001b[36m @teval texpr\u001b[39m\n", "\n", " evaluates the lisp-like tuple expression \u001b[36mtexpr\u001b[39m.\n", "\n", " Example: Calculation of \u001b[36msin(π/6)\u001b[39m\n", "\n", "\u001b[36m julia> @teval (:call, :sin, (:call, :/, π, 6))\u001b[39m\n", "\u001b[36m 0.49999999999999994\u001b[39m\n", "\n", " In some cases, you can omit \u001b[36m:call\u001b[39m.\n", "\n", "\u001b[36m julia> @teval (:sin, (:/, π, 6))\u001b[39m\n", "\u001b[36m 0.49999999999999994\u001b[39m" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc @teval" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "MetaUtils.@t texpr\n", "\\end{verbatim}\n", "shows the Julia expression and the value of the lisp-like tuple expression \\texttt{texpr}.\n", "\n", "Example:\n", "\n", "\\begin{verbatim}\n", "julia> MetaUtils.@t (:call, :sin, (:call, :/, π, 6))\n", ":(sin(π / 6))\n", "→ 0.49999999999999994\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "MetaUtils.@t texpr\n", "```\n", "\n", "shows the Julia expression and the value of the lisp-like tuple expression `texpr`.\n", "\n", "Example:\n", "\n", "```julia\n", "julia> MetaUtils.@t (:call, :sin, (:call, :/, π, 6))\n", ":(sin(π / 6))\n", "→ 0.49999999999999994\n", "```\n" ], "text/plain": [ "\u001b[36m MetaUtils.@t texpr\u001b[39m\n", "\n", " shows the Julia expression and the value of the lisp-like tuple expression\n", " \u001b[36mtexpr\u001b[39m.\n", "\n", " Example:\n", "\n", "\u001b[36m julia> MetaUtils.@t (:call, :sin, (:call, :/, π, 6))\u001b[39m\n", "\u001b[36m :(sin(π / 6))\u001b[39m\n", "\u001b[36m → 0.49999999999999994\u001b[39m" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc MetaUtils.@t" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\begin{verbatim}\n", "MetaUtils.@T texpr\n", "\\end{verbatim}\n", "shows \\texttt{show(texpr)}, \\texttt{show\\_texpr(texpr)}, the Julia expression, and the value of the lisp-like tuple expression \\texttt{texpr}.\n", "\n", "Example:\n", "\n", "\\begin{verbatim}\n", "julia> MetaUtils.@T (:call, :sin, (:call, :/, π, 6))\n", "(:call, :sin, (:call, :/, π, 6))\n", "→ (:call, :sin, \n", " (:call, :/, π, 6))\n", "→ :(sin(π / 6))\n", "→ 0.49999999999999994\n", "\\end{verbatim}\n" ], "text/markdown": [ "```\n", "MetaUtils.@T texpr\n", "```\n", "\n", "shows `show(texpr)`, `show_texpr(texpr)`, the Julia expression, and the value of the lisp-like tuple expression `texpr`.\n", "\n", "Example:\n", "\n", "```julia\n", "julia> MetaUtils.@T (:call, :sin, (:call, :/, π, 6))\n", "(:call, :sin, (:call, :/, π, 6))\n", "→ (:call, :sin, \n", " (:call, :/, π, 6))\n", "→ :(sin(π / 6))\n", "→ 0.49999999999999994\n", "```\n" ], "text/plain": [ "\u001b[36m MetaUtils.@T texpr\u001b[39m\n", "\n", " shows \u001b[36mshow(texpr)\u001b[39m, \u001b[36mshow_texpr(texpr)\u001b[39m, the Julia expression, and the value of\n", " the lisp-like tuple expression \u001b[36mtexpr\u001b[39m.\n", "\n", " Example:\n", "\n", "\u001b[36m julia> MetaUtils.@T (:call, :sin, (:call, :/, π, 6))\u001b[39m\n", "\u001b[36m (:call, :sin, (:call, :/, π, 6))\u001b[39m\n", "\u001b[36m → (:call, :sin, \u001b[39m\n", "\u001b[36m (:call, :/, π, 6))\u001b[39m\n", "\u001b[36m → :(sin(π / 6))\u001b[39m\n", "\u001b[36m → 0.49999999999999994\u001b[39m" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@doc MetaUtils.@T" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "@webio": { "lastCommId": null, "lastKernelId": null }, "jupytext": { "cell_metadata_json": true, "formats": "ipynb,md" }, "kernelspec": { "display_name": "Julia 1.7.0-DEV", "language": "julia", "name": "julia-1.7" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.7.0" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": true, "toc_position": { "height": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "250px" }, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }