{ "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, 2024-10-01\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.10.5\"" ] }, "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 `D:\\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": [ ":(2x + 1)\n", "├─ :+\n", "├─ :(2x)\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": [ ":(2x + 1)\n", "├─ :+\n", "├─ :(2x)\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), LineNumberNode(4, Symbol(\"In[25]\"))))" ] } ], "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": [ ":(for k = 1:10\n", " x = (k * (k + 1)) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", " end)\n", "├─ :(k = 1:10)\n", "│ ├─ :k\n", "│ └─ :(1:10)\n", "│ ⋮\n", "│ \n", "└─ quote\n", " x = (k * (k + 1)) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", " end\n", " ├─ :(x = (k * (k + 1)) ÷ 2)\n", " │ ⋮\n", " │ \n", " └─ :(println(\"k(k+1)/2 = \", x))\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": [ ":(for k = 1:10\n", " x = (k * (k + 1)) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", " end)\n", "├─ :(k = 1:10)\n", "│ ├─ :k\n", "│ └─ :(1:10)\n", "│ ├─ :(:)\n", "│ ├─ 1\n", "│ └─ 10\n", "└─ quote\n", " x = (k * (k + 1)) ÷ 2\n", " println(\"k(k+1)/2 = \", x)\n", " end\n", " ├─ :(x = (k * (k + 1)) ÷ 2)\n", " │ ├─ :x\n", " │ └─ :((k * (k + 1)) ÷ 2)\n", " │ ├─ :÷\n", " │ ├─ :(k * (k + 1))\n", " │ │ ├─ :*\n", " │ │ ├─ :k\n", " │ │ └─ :(k + 1)\n", " │ │ ├─ :+\n", " │ │ ├─ :k\n", " │ │ └─ 1\n", " │ └─ 2\n", " └─ :(println(\"k(k+1)/2 = \", x))\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": [ ":(for k = 1:10\n", " \u001b[90m#= In[28]:2 =#\u001b[39m\n", " x = (k * (k + 1)) ÷ 2\n", " \u001b[90m#= In[28]:3 =#\u001b[39m\n", " println(\"k(k+1)/2 = \", x)\n", " \u001b[90m#= In[28]:4 =#\u001b[39m\n", " end)\n", "├─ :(k = 1:10)\n", "│ ├─ :k\n", "│ └─ :(1:10)\n", "│ ├─ :(:)\n", "│ ├─ 1\n", "│ └─ 10\n", "└─ quote\n", " \u001b[90m#= In[28]:2 =#\u001b[39m\n", " x = (k * (k + 1)) ÷ 2\n", " \u001b[90m#= In[28]:3 =#\u001b[39m\n", " println(\"k(k+1)/2 = \", x)\n", " \u001b[90m#= In[28]:4 =#\u001b[39m\n", " end\n", " ├─ :(\u001b[90m#= In[28]:2 =#\u001b[39m)\n", " ├─ :(x = (k * (k + 1)) ÷ 2)\n", " │ ├─ :x\n", " │ └─ :((k * (k + 1)) ÷ 2)\n", " │ ├─ :÷\n", " │ ├─ :(k * (k + 1))\n", " │ │ ├─ :*\n", " │ │ ├─ :k\n", " │ │ └─ :(k + 1)\n", " │ │ ├─ :+\n", " │ │ ├─ :k\n", " │ │ └─ 1\n", " │ └─ 2\n", " ├─ :(\u001b[90m#= In[28]:3 =#\u001b[39m)\n", " ├─ :(println(\"k(k+1)/2 = \", x))\n", " │ ├─ :println\n", " │ ├─ \"k(k+1)/2 = \"\n", " │ └─ :x\n", " └─ :(\u001b[90m#= In[28]:4 =#\u001b[39m)\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}((5,))\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", " 5: LineNumberNode\n", " line: Int64 4\n", " file: Symbol In[29]\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", "├─ Base.MultiplicativeInverses.MultiplicativeInverse\n", "│ ├─ Base.MultiplicativeInverses.SignedMultiplicativeInverse\n", "│ └─ Base.MultiplicativeInverses.UnsignedMultiplicativeInverse\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", "├─ AbstractSlices{T, 1} where T\n", "│ └─ Slices{P, SM, AX, S, 1} where {P, SM, AX, S}\n", "├─ Base.ExceptionStack\n", "├─ Base.LogicalIndex\n", "├─ Base.MethodList\n", "├─ Base.ReinterpretArray{T, 1, S} where {T, S}\n", "├─ Base.ReshapedArray{T, 1} where T\n", "├─ Base.Sort.WithoutMissingVector\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", "├─ Core.Compiler.TwoPhaseDefUseMap\n", "├─ Core.Compiler.TwoPhaseVectorView\n", "├─ DenseVector\n", "│ ├─ Base.CodeUnits\n", "│ ├─ Base.Experimental.Const{T, 1} where T\n", "│ ├─ Random.UnsafeView\n", "│ └─ Vector\n", "├─ LinearIndices{1, R} where R<:Tuple{AbstractUnitRange{Int64}}\n", "├─ PermutedDimsArray{T, 1} where T\n", "├─ SubArray{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": [ ":(function f(x::T) where T <: Number\n", " sin(x)\n", " end)\n", "├─ :(f(x::T) where T <: Number)\n", "│ ├─ :(f(x::T))\n", "│ │ ├─ :f\n", "│ │ └─ :(x::T)\n", "│ │ ├─ :x\n", "│ │ └─ :T\n", "│ └─ :(T <: Number)\n", "│ ├─ :T\n", "│ └─ :Number\n", "└─ quote\n", " sin(x)\n", " end\n", " └─ :(sin(x))\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": [ ":(\u001b[90m#= In[39]:1 =#\u001b[39m @show float(π))\n", "├─ Symbol(\"@show\")\n", "├─ :(\u001b[90m#= In[39]:1 =#\u001b[39m)\n", "└─ :(float(π))\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\"), :(\u001b[90m#= In[40]:1 =#\u001b[39m), (: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.1416148\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/png": "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", "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" ], "text/html": [ "" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "begin\n", " using Plots\n", " default(fmt=:png)\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", " (:call, :default, \n", " (:kw, :fmt, QuoteNode(:png))), \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", " default(fmt=:png)\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/png": "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", "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" ], "text/html": [ "" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@teval (:block, \n", " (:using, (:., :Plots)), \n", " (:default, (:kw, :fmt, QuoteNode(:png))), \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", " default(fmt = :png)\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", " (:default, (:kw, :fmt, QuoteNode(:png))), \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.10.5", "language": "julia", "name": "julia-1.10" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.10.5" }, "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 }