{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Replacing Functions in the Dictionary\n", "For now, there is no way to define new functions from within the Joy language. All functions (and the interpreter) all accept and return a dictionary parameter (in addition to the stack and expression) so that we can implement e.g. a function that adds new functions to the dictionary. However, there's no function that does that. Adding a new function to the dictionary is a meta-interpreter action, you have to do it in Python, not Joy." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from notebook_preamble import D, J, V" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A long trace" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " . [23 18] average\n", " [23 18] . average\n", " [23 18] . [sum 1.0 *] [size] cleave /\n", " [23 18] [sum 1.0 *] . [size] cleave /\n", " [23 18] [sum 1.0 *] [size] . cleave /\n", " [23 18] [sum 1.0 *] [size] . [i] app2 [popd] dip /\n", " [23 18] [sum 1.0 *] [size] [i] . app2 [popd] dip /\n", "[23 18] [[sum 1.0 *] [23 18]] [i] . infra first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] [sum 1.0 *] . i [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] . sum 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41 . 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41 1.0 . * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41.0 . [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41.0 [[23 18]] . swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] [41.0] . first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] 41.0 . [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] 41.0 [[size] [23 18]] . [i] infra first [popd] dip /\n", "[23 18] 41.0 [[size] [23 18]] [i] . infra first [popd] dip /\n", " [23 18] [size] . i [41.0 [23 18]] swaack first [popd] dip /\n", " [23 18] . size [41.0 [23 18]] swaack first [popd] dip /\n", " [23 18] . 0 swap [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " [23 18] 0 . swap [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " 0 [23 18] . [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " 0 [23 18] [pop ++] . step [41.0 [23 18]] swaack first [popd] dip /\n", " 0 23 [pop ++] . i [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " 0 23 . pop ++ [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " 0 . ++ [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " 1 . [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " 1 [18] . [pop ++] step [41.0 [23 18]] swaack first [popd] dip /\n", " 1 [18] [pop ++] . step [41.0 [23 18]] swaack first [popd] dip /\n", " 1 18 [pop ++] . i [41.0 [23 18]] swaack first [popd] dip /\n", " 1 18 . pop ++ [41.0 [23 18]] swaack first [popd] dip /\n", " 1 . ++ [41.0 [23 18]] swaack first [popd] dip /\n", " 2 . [41.0 [23 18]] swaack first [popd] dip /\n", " 2 [41.0 [23 18]] . swaack first [popd] dip /\n", " [23 18] 41.0 [2] . first [popd] dip /\n", " [23 18] 41.0 2 . [popd] dip /\n", " [23 18] 41.0 2 [popd] . dip /\n", " [23 18] 41.0 . popd 2 /\n", " 41.0 . 2 /\n", " 41.0 2 . /\n", " 20.5 . \n" ] } ], "source": [ "V('[23 18] average')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Replacing `size` with a Python version\n", "\n", "Both `sum` and `size` each convert a sequence to a single value." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " sum == 0 swap [+] step\n", " size == 0 swap [pop ++] step" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An efficient `sum` function is already in the library. But for `size` we can use a “compiled” version hand-written in Python to speed up evaluation and make the trace more readable." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from joy.library import SimpleFunctionWrapper\n", "from joy.utils.stack import iter_stack\n", "\n", "\n", "@SimpleFunctionWrapper\n", "def size(stack):\n", " '''Return the size of the sequence on the stack.'''\n", " sequence, stack = stack\n", " n = 0\n", " for _ in iter_stack(sequence):\n", " n += 1\n", " return n, stack" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we replace the old version in the dictionary with the new version, and re-evaluate the expression." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "D['size'] = size" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A shorter trace\n", "You can see that `size` now executes in a single step." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " . [23 18] average\n", " [23 18] . average\n", " [23 18] . [sum 1.0 *] [size] cleave /\n", " [23 18] [sum 1.0 *] . [size] cleave /\n", " [23 18] [sum 1.0 *] [size] . cleave /\n", " [23 18] [sum 1.0 *] [size] . [i] app2 [popd] dip /\n", " [23 18] [sum 1.0 *] [size] [i] . app2 [popd] dip /\n", "[23 18] [[sum 1.0 *] [23 18]] [i] . infra first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] [sum 1.0 *] . i [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] . sum 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41 . 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41 1.0 . * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41.0 . [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " 41.0 [[23 18]] . swaack first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] [41.0] . first [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] 41.0 . [[size] [23 18]] [i] infra first [popd] dip /\n", " [23 18] 41.0 [[size] [23 18]] . [i] infra first [popd] dip /\n", "[23 18] 41.0 [[size] [23 18]] [i] . infra first [popd] dip /\n", " [23 18] [size] . i [41.0 [23 18]] swaack first [popd] dip /\n", " [23 18] . size [41.0 [23 18]] swaack first [popd] dip /\n", " 2 . [41.0 [23 18]] swaack first [popd] dip /\n", " 2 [41.0 [23 18]] . swaack first [popd] dip /\n", " [23 18] 41.0 [2] . first [popd] dip /\n", " [23 18] 41.0 2 . [popd] dip /\n", " [23 18] 41.0 2 [popd] . dip /\n", " [23 18] 41.0 . popd 2 /\n", " 41.0 . 2 /\n", " 41.0 2 . /\n", " 20.5 . \n" ] } ], "source": [ "V('[23 18] average')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.12" } }, "nbformat": 4, "nbformat_minor": 2 }