{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from notebook_preamble import J, V, define"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [Quadratic formula](https://en.wikipedia.org/wiki/Quadratic_formula)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cf. [jp-quadratic.html](http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "       -b ± sqrt(b^2 - 4 * a * c)\n",
    "    --------------------------------\n",
    "                2 * a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\\frac{-b  \\pm \\sqrt{b^2 - 4ac}}{2a}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Write a straightforward program with variable names.\n",
    "This math translates to Joy code in a straightforward manner.  We are going to use named variables to keep track of the arguments, then write a definition without them."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `-b`\n",
    "    b neg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `sqrt(b^2 - 4 * a * c)`\n",
    "    b sqr 4 a c * * - sqrt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `/2a`\n",
    "    a 2 * /"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `±`\n",
    "There is a function `pm` that accepts two values on the stack and replaces them with their sum and difference.\n",
    "\n",
    "    pm == [+] [-] cleave popdd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Putting Them Together\n",
    "\n",
    "    b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2\n",
    "\n",
    "We use `app2` to compute both roots by using a quoted program `[2a /]` built with `cons`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Derive a definition.\n",
    "Working backwards we use `dip` and `dipd` to extract the code from the variables:\n",
    "\n",
    "    b             neg  b      sqr 4 a c   * * - sqrt pm a    2 * [/] cons app2\n",
    "    b            [neg] dupdip sqr 4 a c   * * - sqrt pm a    2 * [/] cons app2\n",
    "    b a c       [[neg] dupdip sqr 4] dipd * * - sqrt pm a    2 * [/] cons app2\n",
    "    b a c a    [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2\n",
    "    b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2\n",
    "\n",
    "The three arguments are to the left, so we can \"chop off\" everything to the right and say it's the definition of the `quadratic` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try it out:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-0.3819660112501051 -2.618033988749895\n"
     ]
    }
   ],
   "source": [
    "J('3 1 1 quadratic')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you look at the Joy evaluation trace you can see that the first few lines are the `dip` and `dipd` combinators building the main program by incorporating the values on the stack.  Then that program runs and you get the results.  This is pretty typical of Joy code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                                                   . -5 1 4 quadratic\n",
      "                                                -5 . 1 4 quadratic\n",
      "                                              -5 1 . 4 quadratic\n",
      "                                            -5 1 4 . quadratic\n",
      "                                            -5 1 4 . over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2\n",
      "                                          -5 1 4 1 . [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2\n",
      "-5 1 4 1 [[[neg] dupdip sqr 4] dipd * * - sqrt pm] . dip 2 * [/] cons app2\n",
      "                                            -5 1 4 . [[neg] dupdip sqr 4] dipd * * - sqrt pm 1 2 * [/] cons app2\n",
      "                       -5 1 4 [[neg] dupdip sqr 4] . dipd * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                                -5 . [neg] dupdip sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                          -5 [neg] . dupdip sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                                -5 . neg -5 sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                                 5 . -5 sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                              5 -5 . sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                              5 -5 . dup mul 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                           5 -5 -5 . mul 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                              5 25 . 4 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                            5 25 4 . 1 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                          5 25 4 1 . 4 * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                        5 25 4 1 4 . * * - sqrt pm 1 2 * [/] cons app2\n",
      "                                          5 25 4 4 . * - sqrt pm 1 2 * [/] cons app2\n",
      "                                           5 25 16 . - sqrt pm 1 2 * [/] cons app2\n",
      "                                               5 9 . sqrt pm 1 2 * [/] cons app2\n",
      "                                             5 3.0 . pm 1 2 * [/] cons app2\n",
      "                                           8.0 2.0 . 1 2 * [/] cons app2\n",
      "                                         8.0 2.0 1 . 2 * [/] cons app2\n",
      "                                       8.0 2.0 1 2 . * [/] cons app2\n",
      "                                         8.0 2.0 2 . [/] cons app2\n",
      "                                     8.0 2.0 2 [/] . cons app2\n",
      "                                     8.0 2.0 [2 /] . app2\n",
      "                                       [8.0] [2 /] . infra first [2.0] [2 /] infra first\n",
      "                                               8.0 . 2 / [] swaack first [2.0] [2 /] infra first\n",
      "                                             8.0 2 . / [] swaack first [2.0] [2 /] infra first\n",
      "                                               4.0 . [] swaack first [2.0] [2 /] infra first\n",
      "                                            4.0 [] . swaack first [2.0] [2 /] infra first\n",
      "                                             [4.0] . first [2.0] [2 /] infra first\n",
      "                                               4.0 . [2.0] [2 /] infra first\n",
      "                                         4.0 [2.0] . [2 /] infra first\n",
      "                                   4.0 [2.0] [2 /] . infra first\n",
      "                                               2.0 . 2 / [4.0] swaack first\n",
      "                                             2.0 2 . / [4.0] swaack first\n",
      "                                               1.0 . [4.0] swaack first\n",
      "                                         1.0 [4.0] . swaack first\n",
      "                                         4.0 [1.0] . first\n",
      "                                           4.0 1.0 . \n"
     ]
    }
   ],
   "source": [
    "V('-5 1 4 quadratic')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
